Artikel ini merupakan review dari artikel Medium asli (percobaan sedang dilakukan dengan perubahan pada beberapa kondisi).
Bidang penerapan jaringan saraf dalam kedokteran berkembang pesat. Di bidang ini, tugas diselesaikan yang memfasilitasi pekerjaan dokter. Secara khusus, salah satu tugas yang dituntut di area ini adalah deteksi objek dalam gambar medis (ini adalah ketika persegi panjang ditumpangkan pada gambar, yang membatasi area di mana seharusnya ada beberapa objek). Contoh gambar seperti itu ditunjukkan di bawah ini.
https://github.com/ultralytics/yolov3
, - . person tie. ( person 0.59, tie - 0.62). (, , , , ..), , , , , . ( , "person 0.59". , person - - 0.59). , - , 0 1.
, , . , , .
, . , 20 . 2019- ( 2,6 ). . - , . .
, , .
, , ( - ) , ( ).
.
YOLOv3 , YOLO (You Only Look Once). , CNN (Convolutional Neural Network) ( ). YOLOv3 106- . , YOLOv3 ( 3), . YOLOv3:
https://www.researchgate.net/figure/The-framework-of-YOLOv3-neural-network-for-ship-detection_fig2_335228064
YOLO 13 13. ? , bounding box' ( ) , . (, ) confidence value ( ). , , (, ). YOLOv3.
https://medium.com/nerd-for-tech/a-real-time-object-detection-model-using-yolov3-algorithm-for-non-gpu-computers-8941a20b445
, YOLO , anchor boxes ( ). Medium. ( ) . , anchor boxes ( ) bounding box' COCO k-.
, . ? , . Kaggle, . .
. stage_2_train_images.zip stage_2_test_images.zip. , , . ( ) 26684 . DICOM 1024 1024. .
Class |
Target |
Patients |
Lung Opacity |
1 |
9555 |
No Lung Opacity / Not Normal |
0 |
11821 |
Normal |
0 |
8851 |
DICOM. JPG .
import pydicom as dicom
import os
from tqdm import tqdm
import numpy as np
import cv2
import pandas as pd
dicom jpg
def dicom_to_jpg(source_folder,destination_folder,labels):
images_path = os.listdir(source_folder)
image_dirs_label = {'image_dir':[],'Target':[]}
for n, image in tqdm(enumerate(images_path)):
ds = dicom.dcmread(os.path.join(source_folder, image))
pixel_array_numpy = ds.pixel_array
image = image.replace('.dcm', '.jpg')
cv2.imwrite(os.path.join(destination_folder, image), pixel_array_numpy)
image_dirs_label['image_dir'].append(os.path.join(destination_folder, image))
image_dirs_label['Target'].append(train_labels[train_labels.patientId== image.split('.')[0]].Target.values[0])
print('{} dicom files converted to jpg!'.format(len(images_path)))
return pd.DataFrame(image_dirs_label)
3 , : Normal β 0, No Lung Opacity / Not Normal β 0, Lung Opacity β 1. Class, Target Patients, , . .
, (positive Lung Opacity). (negative) 1:4 ( , ).
( , ). (positive) β . Albumentations. .
import albumentations as A
import pandas as pd
import cv2
import os
transformer
transform = A.Compose([
A.RandomRotate90(),
A.Flip(),
A.Transpose(),
A.OneOf([
A.IAAAdditiveGaussianNoise(),
A.GaussNoise(),
], p=0.2),
A.OneOf([
A.MotionBlur(p=.2),
A.MedianBlur(blur_limit=3, p=0.1),
A.Blur(blur_limit=3, p=0.1),
], p=0.2),
A.ShiftScaleRotate(shift_limit=0.0625, scale_limit=0.2, rotate_limit=45, p=0.2),
A.OneOf([
A.OpticalDistortion(p=0.3),
A.GridDistortion(p=.1),
A.IAAPiecewiseAffine(p=0.3),
], p=0.2),
A.OneOf([
A.CLAHE(clip_limit=2),
A.IAASharpen(),
A.IAAEmboss(),
A.RandomBrightnessContrast(), ], p=0.3),
A.HueSaturationValue(p=0.3),
])
( " ", , )
"". JPG DICOM YOLOv3 (backbone') DarkNet. DarkNet . YOLOv3 ( Darknet) CheXNet. CheXNet 121- , , . CheXNet. 14 , , CheXNet 2- (negative β positive β ). TensorFlow, DenseNet121. .
# CheXNet classifier_weights.hdf5,
https://drive.google.com/file/d/1Bd50DpRWorGMDuEZ3-VHgndpJZwUGTAr/view
from absl import flags
from absl.flags import FLAGS
import numpy as np
import tensorflow as tf
from tensorflow.keras import Model
from tensorflow.keras.applications import DenseNet121
from tensorflow.keras.layers import (
Add,
Concatenate,
Conv2D,
Input,
Lambda,
LeakyReLU,
MaxPool2D,
UpSampling2D,
ZeroPadding2D,
BatchNormalization,
Dense
)
def base_model(chexnet_weights=None,size=None):
dense_net_121 = DenseNet121(input_shape = [size,size,3], include_top = False,pooling = 'avg')
base_model_output = Dense(units = 14, activation = 'relu')(dense_net_121.output)
base_model = Model(inputs = dense_net_121.input,outputs = base_model_output)
output_layer = Dense(1, activation = 'sigmoid')(base_model.layers[-2].output)
model = Model(inputs = base_model.inputs, outputs = output_layer)
if chexnet_weights:
model.load_weights(chexnet_weights)
final_base_model = Model(inputs = model.inputs, outputs = model.layers[-3].output)
return final_base_model
def ChexNet(name=None, chexnet_weights='PATH_TO_WEIGTHS/classifier_weights.hdf5',size=None):
chexnet = base_model(chexnet_weights = chexnet_weights, size = size)
back_bone = Model(inputs = chexnet.inputs, outputs=(chexnet.get_layer('pool3_conv').output,
chexnet.get_layer('pool4_conv').output,
chexnet.output),name=name)
return back_bone
:
Model |
Total params |
Trainable params |
Non-trainable params |
DarkNet |
61576342 |
61523734 |
52608 |
CheXNet |
27993206 |
27892662 |
100544 |
, CheXNet 2 , DarkNet. CheXNet.
YOLOv3 CheXNet ( ).
, (1 ) (positive negative), , ( positive). YOLOv3 416 416 13 13 (416 / 32 = 13). 13 13. anchor box' 3, 13 13 3- anchor box'. 13 13 3 = 507 ( ). , 507 . positive ( ) 2 (), 2 507-2=505 . , . , "" .
, ImageDataGenerator . , ( ), .
# true_augmented_labels - DataFrame,
( , ()
datagen=ImageDataGenerator(
rescale = 1. / 255.,
validation_split = 0.20)
train_generator = datagen.flow_from_dataframe(
dataframe = true_augmented_labels,
x_col = "image_dir",
y_col = "Target",
subset = "training",
batch_size = 4,
seed = 42,
shuffle = True,
class_mode = "binary",
target_size = (416, 416))
valid_generator = datagen.flow_from_dataframe(
dataframe = true_augmented_labels,
x_col = "image_dir",
y_col = "Target",
subset = "validation",
batch_size = 4,
seed = 42,
shuffle = True,
class_mode = "binary",
target_size = (416, 416))
( positive, negative), .
# brucechou1983_CheXNet_Keras_0.3.0_weights.h5 classifier_weights.hdf5
https://www.kaggle.com/theewok/chexnet-keras-weights/version/1
https://github.com/junaidnasirkhan/Replacing-YoloV3-Backbone-with-ChexNet-for-Pneumonia-Detection
dense_net_121 = DenseNet121(input_shape = [416,416] + [3], include_top = False, pooling = 'avg')
base_model_output = Dense(units = 14, activation = 'relu')(dense_net_121.output)
base_model = Model(inputs = dense_net_121.input, outputs = base_model_output)
""
base_model.load_weights('brucechou1983_CheXNet_Keras_0.3.0_weights.h5')
for layer in base_model.layers[:10]:
layer.trainable = False
output_layer = Dense(1, activation = 'sigmoid')(base_model.layers[-2].output)
model = Model(inputs = base_model.inputs, outputs = output_layer)
model.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy', f1_m])
checkpoint = ModelCheckpoint(filepath = 'classifier_weights.hdf5', monitor = 'val_accuracy', verbose = 0, save_best_only = True, save_weights_only = True, mode = 'auto')
log_dir = "classifier_logs/" + datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
tensorboard = TensorBoard(log_dir = log_dir, histogram_freq = 1, write_graph = True, write_grads = True)
callback_list = [checkpoint, tensorboard]
model.fit(train_generator,
validation_data = valid_generator,
epochs = 1, # 3
steps_per_epoch = len(train_generator),
callbacks = callback_list)
positive ( ).
# rsna_train_pos.tfrecord rsna_val_pos.tfrecord
.names ( )
"opacity" "no_opacity"
model = train(dataset = 'PATH_TO_TFRECORD/rsna_train_pos.tfrecord',
val_dataset = 'PATH_TO_TFRECORD/rsna_val_pos.tfrecord',
backbone = 'chexnet',
classes = 'PATH_TO_CLASSES/RSNA_VOC.names',
size = 416,
epochs = 30,
batch_size = 16, learning_rate = 1e-4,
num_classes = 1)
hdf5.
(YOLOv3 CheXNet).
learning_rate = 1e-4, epoch = 20
loss'
learning_rate = 1e-4, epochs = 30
loss'
.
CheXNet DarkNet , CheXNet, DarkNet.
CheXNet 1 , 20 30 , .
, epoch, .
. :
( , learning_rate)
CheXNet
-
Ke GitHub saya