Keras-RetinaNet을 이용한 모델 로딩 및 예측

load weight-Copy1

Keras-RetinaNet을 이용한 모델 로딩 및 예측

In [4]:
import random
from keras_retinanet import models
from keras_retinanet.utils.image import read_image_bgr, preprocess_image, resize_image
from keras_retinanet.utils.visualization import draw_box, draw_caption
from keras_retinanet.utils.colors import label_color
from keras_retinanet.utils.gpu import setup_gpu
from keras_retinanet.models import load_model
from keras_retinanet.utils.colors import label_color
import os
import pydicom
import cv2

import pandas as pd
import numpy as np

from tqdm import tqdm_notebook as tqdm

GPU 설정

  • 사용가능한 GPU가 있는 경우 설정
In [106]:
gpu = 0
setup_gpu(gpu)

기존 모델 로드

  • 레티나넷에서 제공하는 load_model을 이용한다.
  • 백본은 resnet이 될수도 있고, 다른 네트워크가 될수도 있음
In [108]:
model = load_model('../input/model_weight.h5', backbone_name='resnet101')

추론 모드로 변환

  • 추론모드로 변환하지 않으면 추후 아규먼트가 맞지 않음
In [ ]:
model = models.convert_model(model)

기존의 파일에서 랜덤으로 뽑기

  • 가용성을 보기위해 하나만 일단 뽑는다.
In [159]:
file_list = os.listdir('../images/')

random_file = random.choice(file_list)

dcm = pydicom.read_file('../images/' + random_file)
image = dcm.pixel_array

image.shape
Out[159]:
(4280, 3520)

(참조) PNG로 변환할경우

  • PNG로 변환할때 MONOCHROME을 참조한다.
  • 윈도우사이즈나, 파일의 속성에 따라 노말라이제이션이 필요할 수 있다.
  • 실제 훈련에는 DICOM을 그대로 활용하는편이 활용성이 낫다.
In [160]:
# import pylab

# PATH = '../test_png/'

# for name in tqdm(os.listdir('../images/')):
    
#     dcm = pydicom.read_file('../images/' + name)
#     image = dcm.pixel_array
    

#     if dcm[('0028','0004')].value == 'MONOCHROME1':
#         pylab.imsave(PATH + name + '.png', image, cmap='binary')
#     elif dcm[('0028','0004')].value == 'MONOCHROME2':
#         pylab.imsave(PATH + name + '.png',image, cmap='gray')
  • 변환한 PNG파일 확인
In [161]:
file_list_png = os.listdir('../test_png/')

random_file = random.choice(file_list_png)

bgr = read_image_bgr('../test_png/' + random_file)
image = cv2.cvtColor(bgr, cv2.COLOR_BGR2RGB) #필요없음, 참조

image.shape
  • DICOM은 몇가지 처리방법이 있을 수 있는데, pretrained이 3채널을 가지는 경우 stack을 해서 사용하기도 한다. 혹은 채널별로 윈도우 범위를 다르게 잡을 수 있다.
  • 1채널 모델인경우 stack할 필요가 없어 보인다.
  • 현재 변환된 PNG의 경우 채널은 총 세개지만, 각각이 가지는 값은 같다.
In [163]:
resized_image = cv2.resize(image, (1024,1024), interpolation=cv2.INTER_LINEAR)

# normalized_image = normalize(resized_image)
# stacked_image = np.stack((normalized_image, normalized_image, normalized_image))

# stacked_image = np.stack((resized_image, resized_image, resized_image))

# stacked_image = np.swapaxes(stacked_image,0,1)
# stacked_image = np.swapaxes(stacked_image,1,2)

추론 (예측)

  • 추론모드로 RTX2060으로 약 3초정도 걸린다.
In [167]:
boxes, scores, labels = model.predict_on_batch(np.expand_dims(resized_image, axis=0))
Out[167]:
array([[757.6449 , 527.0725 , 812.03143, 589.4323 ],
       [146.58601, 552.5455 , 197.9453 , 618.62195],
       [637.8172 , 285.8778 , 708.3167 , 343.30438],
       ...,
       [ -1.     ,  -1.     ,  -1.     ,  -1.     ],
       [ -1.     ,  -1.     ,  -1.     ,  -1.     ],
       [ -1.     ,  -1.     ,  -1.     ,  -1.     ]], dtype=float32)

시각화

  • 0.05이상의 확률을 가지는 패치의 경우만을 나타낸다.
In [ ]:
labels_to_names = {0: 'spot'} # 클래스는 다수가 있을 수 있음

for box, score, label in zip(boxes[0], scores[0], labels[0]):
    
    if score < 0.05: # 그림에 표시할 쓰레시홀드를 정한다.
        break
        
    color = label_color(label)
    
    b = box.astype(int)
    draw_box(resized_image, b, color=color)
    
    caption = "{} {:.3f}".format(labels_to_names[label], score)
    draw_caption(resized_image, b, caption)
    
plt.figure(figsize=(15, 15))
plt.axis('off')
plt.imshow(resized_image)
plt.show()

답글 남기기