پایتون پزشکی: درس اول: پردازش تصاویر پزشکی

مقدمه:

در این سلسله مقالات که در ۴ درس تهیه شده است به آموزش پردازش تصاویر پزشکی با پایتون می پردازیم. در این آموزش از روش هایی نظیر یادگیری عمیق برای کلاسبندی، سگمنتبندی، و تشخیص آبجکت ها و همچنین از ابزارهایی نظیر MD.ai برای تفسیر و تحلیل تصاویر استفاده شده است. شما میتونید برای اجرا کردن کدهای ارائه شده از کامپایلرها و محیطهایی نظیر Google Colab و Jupyter استفاده کنید.

تفسیرگر MD.ai چیست؟

تفسیرگر MD.ai یک اپلیکیشن تحت وب برای ذخیره، مشاهده و تفسیر تصاویر پزشکی (نظیر تصاویر DICOM) در فضای ابری است. ما با استفاده از کتابخانه پایتون MD.ai می توانیم تصاویر پزشکی را دانلود و تفسیر کنیم و سپس با استفاده از آنها مدلهای یادگیری عمیق خودمان را پیاده سازی کنیم. برای توضیحات بیشتر درمورد تفسیرگر MD.ai میتونید به این لینک مراجعه کنید.

اجرای Jupyter بر روی GoogleColab:

ما باید در قدم اول Jupyter رو روی GoogleColab که یک GPU رایگان هست پیاده سازی کنیم.

بخش اول:

کلاسبندی تصاویر اشعه ایکس (X-rays) ناحیه قفسه سینه از شکم با استفاده از تنسورفلو (TensorFlow) و کراس (Keras)

این بخش یک معرفی سطح بالا و عملی از یادگیری ماشین است. هدف از این معرفی یک کلاسبندی کننده مبتنی بر یادگیری عمیق است که با آن بتوان یک تمایز خیلی دقیق بین ناحیه قفسه سینه از شکم در تصاویر x-rays ایجاد کرد. این مدل با ۷۵ تصویر شناسایی نشده که از طریق Open-i (که یک مرجع تصاویر پزشکی است) دریافت شده آموزش دیده است.

سعی می کنیم کدها رو به صورت بخش به بخش توضیح و تفسیر کنیم:

برنامه زیر رو هم در jupyter و هم در GoogleColab میتونید اجرا کنید:

قسمت اول: اضافه کردن کتابخانه mdai:

برای نصب کتابخانه mdai از کدهای زیر استفاده می کنیم:

%%bash

pip install -q -U mdai
import mdai
mdai.__version__

بعد از اجرا کردن کد بالا آخرین ورژن mdai براتون نمایش داده میشه:

۰.۷.۸

قسمت دوم: ایجاد یک اشتراک mdai:

برای ایجاد اشتراک mdai ما نیاز به یک توکن دسترسی داریم که mdai مارو به عنوان یک کاربر در نظر بگیره. برای ایجاد یک توکن جدید کافیه به تب Personal Access Tokens در صفحه تنظیمات کاربری (user settings) در سایت MD.ai با آدرس: public.md.ai بریم.بعد از دریافت توکن خط کدهای زیر را بنویسید:

mdai_client = mdai.Client(domain='public.md.ai', access_token="")

بعد از اجرای خط بالا پیام زیر باید نمایش داده بشه:

Successfully authenticated to public.md.ai.

قسمت سوم: تعریف پروژه:

از اونجا که این پروژه از قبل نوشته شده است می توان به آن در دیتاست mdai دسترسی داشت که با استفاده از آی دی پروژه و مسیر دسترسی به آن مشخص می شود. برای اینکار کافیست کد خط زیر را بنویسیم که آی دی آن ‘PVq9raBJ’ و مسیر آن ‘lesson1-data’ خواهد بود:

p = mdai_client.project('PVq9raBJ', path='./lesson1-data')

با اجرای کد بالا خروجی زیر را خواهیم داشت:

Using path './lesson1-data' for data.
Preparing annotations export for project PVq9raBJ...                                                
Using cached annotations data for project PVq9raBJ.
Preparing images export for project PVq9raBJ...                                                     
Using cached images data for project PVq9raBJ.

قسمت چهارم: تنظیم لیبل آی دی ها (Label Ids)

لیبل آی دی ها باید صراحتا توسط روش Project#set_label_ids برای دسترسی به دیتاست تنظیم بشن. برای اینکار کدهای زیر را می نویسیم:

در مرحله اول همه آی دی ها را نمایش میدیم:

p.show_label_groups()

که خروجی اون به صورت زیر میشه:

Label Group, Id: G_BdW4M5, Name: Default group
	Labels:
	Id: L_38Y7Jl, Name: Abdomen
	Id: L_z8xEkB, Name: Chest

در مرحله دوم آی دی هارو ذخیره و تفکیک می کنیم:

# this maps label ids to class ids as a dict obj
labels_dict = {
    'L_38Y7Jl': 0, # Abdomen 
    'L_z8xEkB': 1, # Chest  
}

print(labels_dict)
p.set_labels_dict(labels_dict)

که خروجی کد بالا به صورت زیر میشه:

{'L_38Y7Jl': 0, 'L_z8xEkB': 1}

قسمت پنجم: ایجاد دیتاست ها برای آموزش (Training) و صحه گذاری عملکرد (Validation):

مرحله اول نمایش دیتاست ها:

p.show_datasets() 

خروجی کد بالا:

Datasets:
Id: D_8ogmzN, Name: TRAIN
Id: D_OoJ98E, Name: VAL
Id: D_8oAvmQ, Name: TEST

مرحله دوم ایجاد دیتاست آموزش و صحه گذاری عملکرد:

# create training dataset 
train_dataset = p.get_dataset_by_name('TRAIN')
train_dataset.prepare() 
train_image_ids = train_dataset.get_image_ids()
print(len(train_image_ids))

# create the validation dataset 
val_dataset = p.get_dataset_by_name('VAL')
val_dataset.prepare()
val_image_ids = val_dataset.get_image_ids()
print(len(val_image_ids))

خروجی کد بالا به صورت زیر خواهد بود:

۶۵
۱۰

قسمت ششم: نمایش چند تصویر:

نمایش چند تصویر آموزشی یا نمونه:

# visualize a few train images 
mdai.visualize.display_images(train_image_ids[:2], cols=2)
mdai.visualize.display_images(val_image_ids[:2], cols=2)

با اجرای کد بالا تصاویر زیر نشان داده خواهند شد:

قسمت هفتم: استفاده از tf.keras برای آموزش و صحه گذاری:

با استفاده از خط کد زیر میتونیم ورژن تنسورفلو رو روی ۲ ست کنیم:

%tensorflow_version 2.x

با استفاده از کد زیر میتونیم کتابخونه tf روی به پروژه اضافه کنیم و ورژن اون رو نمایش بدیم:

import tensorflow as tf

print(tf.__version__)
tf.keras.backend.clear_session()

خروجی کد بالا به صورت زیر نمایش داده میشه( البته ممکنه برای شما ورژن جدیدتری نمایش داده بشه)

۲.۱.۰

تعریف پارامترهای مدل:

# Define model parameters 
img_width = 224
img_height = 224
epochs = 100

params = {
    'dim': (img_width, img_height),
    'batch_size': 5,
    'n_classes': 2,
    'n_channels': 3,
    'shuffle': True,
}
base_model = tf.keras.applications.MobileNet(weights='imagenet', include_top=False, 
                                             input_shape=(img_width, img_height, 3))

output = tf.keras.layers.GlobalAveragePooling2D()(base_model.output)
output = tf.keras.layers.Dense(2, activation='softmax')(output)

model = tf.keras.Model(inputs=base_model.input, outputs=output)

model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.0001), 
              loss='categorical_crossentropy', metrics=['accuracy'])

model.summary()

با اجرای کد بالا همه پارامترها و مدلها نمایش داده میشن:

Model: "model"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         [(None, 224, 224, 3)]     0         
_________________________________________________________________
conv1_pad (ZeroPadding2D)    (None, 225, 225, 3)       0         
_________________________________________________________________
conv1 (Conv2D)               (None, 112, 112, 32)      864       
_________________________________________________________________
conv1_bn (BatchNormalization (None, 112, 112, 32)      128       
_________________________________________________________________
conv1_relu (ReLU)            (None, 112, 112, 32)      0         
_________________________________________________________________
conv_dw_1 (DepthwiseConv2D)  (None, 112, 112, 32)      288       
_________________________________________________________________
conv_dw_1_bn (BatchNormaliza (None, 112, 112, 32)      128       
_________________________________________________________________
conv_dw_1_relu (ReLU)        (None, 112, 112, 32)      0         
_________________________________________________________________
conv_pw_1 (Conv2D)           (None, 112, 112, 64)      2048      
_________________________________________________________________
conv_pw_1_bn (BatchNormaliza (None, 112, 112, 64)      256       
_________________________________________________________________
conv_pw_1_relu (ReLU)        (None, 112, 112, 64)      0         
_________________________________________________________________
conv_pad_2 (ZeroPadding2D)   (None, 113, 113, 64)      0         
_________________________________________________________________
conv_dw_2 (DepthwiseConv2D)  (None, 56, 56, 64)        576       
_________________________________________________________________
conv_dw_2_bn (BatchNormaliza (None, 56, 56, 64)        256       
_________________________________________________________________
conv_dw_2_relu (ReLU)        (None, 56, 56, 64)        0         
_________________________________________________________________
conv_pw_2 (Conv2D)           (None, 56, 56, 128)       8192      
_________________________________________________________________
conv_pw_2_bn (BatchNormaliza (None, 56, 56, 128)       512       
_________________________________________________________________
conv_pw_2_relu (ReLU)        (None, 56, 56, 128)       0         
_________________________________________________________________
conv_dw_3 (DepthwiseConv2D)  (None, 56, 56, 128)       1152      
_________________________________________________________________
conv_dw_3_bn (BatchNormaliza (None, 56, 56, 128)       512       
_________________________________________________________________
conv_dw_3_relu (ReLU)        (None, 56, 56, 128)       0         
_________________________________________________________________
conv_pw_3 (Conv2D)           (None, 56, 56, 128)       16384     
_________________________________________________________________
conv_pw_3_bn (BatchNormaliza (None, 56, 56, 128)       512       
_________________________________________________________________
conv_pw_3_relu (ReLU)        (None, 56, 56, 128)       0         
_________________________________________________________________
conv_pad_4 (ZeroPadding2D)   (None, 57, 57, 128)       0         
_________________________________________________________________
conv_dw_4 (DepthwiseConv2D)  (None, 28, 28, 128)       1152      
_________________________________________________________________
conv_dw_4_bn (BatchNormaliza (None, 28, 28, 128)       512       
_________________________________________________________________
conv_dw_4_relu (ReLU)        (None, 28, 28, 128)       0         
_________________________________________________________________
conv_pw_4 (Conv2D)           (None, 28, 28, 256)       32768     
_________________________________________________________________
conv_pw_4_bn (BatchNormaliza (None, 28, 28, 256)       1024      
_________________________________________________________________
conv_pw_4_relu (ReLU)        (None, 28, 28, 256)       0         
_________________________________________________________________
conv_dw_5 (DepthwiseConv2D)  (None, 28, 28, 256)       2304      
_________________________________________________________________
conv_dw_5_bn (BatchNormaliza (None, 28, 28, 256)       1024      
_________________________________________________________________
conv_dw_5_relu (ReLU)        (None, 28, 28, 256)       0         
_________________________________________________________________
conv_pw_5 (Conv2D)           (None, 28, 28, 256)       65536     
_________________________________________________________________
conv_pw_5_bn (BatchNormaliza (None, 28, 28, 256)       1024      
_________________________________________________________________
conv_pw_5_relu (ReLU)        (None, 28, 28, 256)       0         
_________________________________________________________________
conv_pad_6 (ZeroPadding2D)   (None, 29, 29, 256)       0         
_________________________________________________________________
conv_dw_6 (DepthwiseConv2D)  (None, 14, 14, 256)       2304      
_________________________________________________________________
conv_dw_6_bn (BatchNormaliza (None, 14, 14, 256)       1024      
_________________________________________________________________
conv_dw_6_relu (ReLU)        (None, 14, 14, 256)       0         
_________________________________________________________________
conv_pw_6 (Conv2D)           (None, 14, 14, 512)       131072    
_________________________________________________________________
conv_pw_6_bn (BatchNormaliza (None, 14, 14, 512)       2048      
_________________________________________________________________
conv_pw_6_relu (ReLU)        (None, 14, 14, 512)       0         
_________________________________________________________________
conv_dw_7 (DepthwiseConv2D)  (None, 14, 14, 512)       4608      
_________________________________________________________________
conv_dw_7_bn (BatchNormaliza (None, 14, 14, 512)       2048      
_________________________________________________________________
conv_dw_7_relu (ReLU)        (None, 14, 14, 512)       0         
_________________________________________________________________
conv_pw_7 (Conv2D)           (None, 14, 14, 512)       262144    
_________________________________________________________________
conv_pw_7_bn (BatchNormaliza (None, 14, 14, 512)       2048      
_________________________________________________________________
conv_pw_7_relu (ReLU)        (None, 14, 14, 512)       0         
_________________________________________________________________
conv_dw_8 (DepthwiseConv2D)  (None, 14, 14, 512)       4608      
_________________________________________________________________
conv_dw_8_bn (BatchNormaliza (None, 14, 14, 512)       2048      
_________________________________________________________________
conv_dw_8_relu (ReLU)        (None, 14, 14, 512)       0         
_________________________________________________________________
conv_pw_8 (Conv2D)           (None, 14, 14, 512)       262144    
_________________________________________________________________
conv_pw_8_bn (BatchNormaliza (None, 14, 14, 512)       2048      
_________________________________________________________________
conv_pw_8_relu (ReLU)        (None, 14, 14, 512)       0         
_________________________________________________________________
conv_dw_9 (DepthwiseConv2D)  (None, 14, 14, 512)       4608      
_________________________________________________________________
conv_dw_9_bn (BatchNormaliza (None, 14, 14, 512)       2048      
_________________________________________________________________
conv_dw_9_relu (ReLU)        (None, 14, 14, 512)       0         
_________________________________________________________________
conv_pw_9 (Conv2D)           (None, 14, 14, 512)       262144    
_________________________________________________________________
conv_pw_9_bn (BatchNormaliza (None, 14, 14, 512)       2048      
_________________________________________________________________
conv_pw_9_relu (ReLU)        (None, 14, 14, 512)       0         
_________________________________________________________________
conv_dw_10 (DepthwiseConv2D) (None, 14, 14, 512)       4608      
_________________________________________________________________
conv_dw_10_bn (BatchNormaliz (None, 14, 14, 512)       2048      
_________________________________________________________________
conv_dw_10_relu (ReLU)       (None, 14, 14, 512)       0         
_________________________________________________________________
conv_pw_10 (Conv2D)          (None, 14, 14, 512)       262144    
_________________________________________________________________
conv_pw_10_bn (BatchNormaliz (None, 14, 14, 512)       2048      
_________________________________________________________________
conv_pw_10_relu (ReLU)       (None, 14, 14, 512)       0         
_________________________________________________________________
conv_dw_11 (DepthwiseConv2D) (None, 14, 14, 512)       4608      
_________________________________________________________________
conv_dw_11_bn (BatchNormaliz (None, 14, 14, 512)       2048      
_________________________________________________________________
conv_dw_11_relu (ReLU)       (None, 14, 14, 512)       0         
_________________________________________________________________
conv_pw_11 (Conv2D)          (None, 14, 14, 512)       262144    
_________________________________________________________________
conv_pw_11_bn (BatchNormaliz (None, 14, 14, 512)       2048      
_________________________________________________________________
conv_pw_11_relu (ReLU)       (None, 14, 14, 512)       0         
_________________________________________________________________
conv_pad_12 (ZeroPadding2D)  (None, 15, 15, 512)       0         
_________________________________________________________________
conv_dw_12 (DepthwiseConv2D) (None, 7, 7, 512)         4608      
_________________________________________________________________
conv_dw_12_bn (BatchNormaliz (None, 7, 7, 512)         2048      
_________________________________________________________________
conv_dw_12_relu (ReLU)       (None, 7, 7, 512)         0         
_________________________________________________________________
conv_pw_12 (Conv2D)          (None, 7, 7, 1024)        524288    
_________________________________________________________________
conv_pw_12_bn (BatchNormaliz (None, 7, 7, 1024)        4096      
_________________________________________________________________
conv_pw_12_relu (ReLU)       (None, 7, 7, 1024)        0         
_________________________________________________________________
conv_dw_13 (DepthwiseConv2D) (None, 7, 7, 1024)        9216      
_________________________________________________________________
conv_dw_13_bn (BatchNormaliz (None, 7, 7, 1024)        4096      
_________________________________________________________________
conv_dw_13_relu (ReLU)       (None, 7, 7, 1024)        0         
_________________________________________________________________
conv_pw_13 (Conv2D)          (None, 7, 7, 1024)        1048576   
_________________________________________________________________
conv_pw_13_bn (BatchNormaliz (None, 7, 7, 1024)        4096      
_________________________________________________________________
conv_pw_13_relu (ReLU)       (None, 7, 7, 1024)        0         
_________________________________________________________________
global_average_pooling2d (Gl (None, 1024)              0         
_________________________________________________________________
dense (Dense)                (None, 2)                 2050      
=================================================================
Total params: 3,230,914
Trainable params: 3,209,026
Non-trainable params: 21,888

نوشتن توابع مدل:

from mdai.visualize import load_dicom_image
import numpy as np
from PIL import Image


class DataGenerator(tf.keras.utils.Sequence):
    def __init__(
        self,
        dataset,
        batch_size=32,
        dim=(32, 32),
        n_channels=1,
        n_classes=10,
        shuffle=True,
        to_RGB=True,
        rescale=False,
    ):
        """Generates data for Keras fit_generator() function.
        """

        # Initialization
        self.dim = dim
        self.batch_size = batch_size

        self.img_ids = dataset.image_ids
        self.imgs_anns_dict = dataset.imgs_anns_dict
        self.dataset = dataset

        self.n_channels = n_channels
        self.n_classes = n_classes
        self.shuffle = shuffle
        self.to_RGB = to_RGB
        self.rescale = rescale
        self.on_epoch_end()

    def __len__(self):
        "Denotes the number of batches per epoch"
        return int(np.floor(len(self.img_ids) / self.batch_size))

    def __getitem__(self, index):
        "Generate one batch of data"

        # Generate indexes of the batch
        indexes = self.indexes[index * self.batch_size : (index + 1) * self.batch_size]

        # Find list of IDs
        img_ids_temp = [self.img_ids[k] for k in indexes]

        # Generate data
        X, y = self.__data_generation(img_ids_temp)

        return X, y

    def on_epoch_end(self):
        "Updates indexes after each epoch"
        self.indexes = np.arange(len(self.img_ids))
        if self.shuffle:
            np.random.shuffle(self.indexes)

    def __data_generation(self, img_ids_temp):
        "Generates data containing batch_size samples"

        # Initialization
        X = np.empty((self.batch_size, *self.dim, self.n_channels))
        y = np.empty((self.batch_size), dtype=int)

        # Generate data
        for i, ID in enumerate(img_ids_temp):
            image = load_dicom_image(ID, to_RGB=self.to_RGB, rescale=self.rescale)
            try:
                image = Image.fromarray(image)
            except Exception:
                print(
                    "Pil.Image can't read image. Possible 12 or 16 bit image. Try rescale=True to "
                    + "scale to 8 bit."
                )

            image = image.resize((self.dim[0], self.dim[1]))

            X[i,] = image

            ann = self.imgs_anns_dict[ID][0]
            y[i] = self.dataset.classes_dict[ann["labelId"]]["class_id"]
        return X, tf.keras.utils.to_categorical(y, num_classes=self.n_classes)
train_generator = DataGenerator(train_dataset, **params)
val_generator = DataGenerator(val_dataset, **params)
# Set callback functions to early stop training and save the best model so far
callbacks = [
    tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=4, verbose=2, min_delta=1e-3),
    tf.keras.callbacks.ModelCheckpoint(filepath='./model.h5', monitor='val_loss', 
                                       save_best_only=True, verbose=2)
]

history = model.fit(
    train_generator,
    epochs=epochs,
    verbose=1,
    callbacks=callbacks,
    validation_data=val_generator,
)

با اجرای کد بالا مراحل نصب و راه اندازی انجام میشود:

WARNING:tensorflow:sample_weight modes were coerced from
  ...
    to  
  ['...']
WARNING:tensorflow:sample_weight modes were coerced from
  ...
    to  
  ['...']
Train for 13 steps, validate for 2 steps
Epoch 1/100
۱۱/۱۳ [========================>.....] - ETA: 0s - loss: 0.4748 - accuracy: 0.7818
Epoch 00001: val_loss improved from inf to 0.87730, saving model to ./model.h5
۱۳/۱۳ [==============================] - ۳s 203ms/step - loss: 0.4067 - accuracy: 0.8154 - val_loss: 0.8773 - val_accuracy: 0.7000
Epoch 2/100
۱۱/۱۳ [========================>.....] - ETA: 0s - loss: 0.0112 - accuracy: 1.0000
Epoch 00002: val_loss improved from 0.87730 to 0.18718, saving model to ./model.h5
۱۳/۱۳ [==============================] - ۱s 47ms/step - loss: 0.0104 - accuracy: 1.0000 - val_loss: 0.1872 - val_accuracy: 0.8000
Epoch 3/100
۱۱/۱۳ [========================>.....] - ETA: 0s - loss: 0.0034 - accuracy: 1.0000
Epoch 00003: val_loss improved from 0.18718 to 0.01628, saving model to ./model.h5
۱۳/۱۳ [==============================] - ۱s 47ms/step - loss: 0.0029 - accuracy: 1.0000 - val_loss: 0.0163 - val_accuracy: 1.0000
Epoch 4/100
۱۱/۱۳ [========================>.....] - ETA: 0s - loss: 0.0012 - accuracy: 1.0000
Epoch 00004: val_loss improved from 0.01628 to 0.00735, saving model to ./model.h5
۱۳/۱۳ [==============================] - ۱s 47ms/step - loss: 0.0015 - accuracy: 1.0000 - val_loss: 0.0074 - val_accuracy: 1.0000
Epoch 5/100
۱۲/۱۳ [==========================>...] - ETA: 0s - loss: 9.7492e-04 - accuracy: 1.0000
Epoch 00005: val_loss improved from 0.00735 to 0.00498, saving model to ./model.h5
۱۳/۱۳ [==============================] - ۱s 47ms/step - loss: 0.0010 - accuracy: 1.0000 - val_loss: 0.0050 - val_accuracy: 1.0000
Epoch 6/100
۱۲/۱۳ [==========================>...] - ETA: 0s - loss: 8.0281e-04 - accuracy: 1.0000
Epoch 00006: val_loss improved from 0.00498 to 0.00331, saving model to ./model.h5
۱۳/۱۳ [==============================] - ۱s 46ms/step - loss: 7.4724e-04 - accuracy: 1.0000 - val_loss: 0.0033 - val_accuracy: 1.0000
Epoch 7/100
۱۲/۱۳ [==========================>...] - ETA: 0s - loss: 6.2463e-04 - accuracy: 1.0000
Epoch 00007: val_loss improved from 0.00331 to 0.00251, saving model to ./model.h5
۱۳/۱۳ [==============================] - ۱s 46ms/step - loss: 5.9762e-04 - accuracy: 1.0000 - val_loss: 0.0025 - val_accuracy: 1.0000
Epoch 8/100
۱۱/۱۳ [========================>.....] - ETA: 0s - loss: 3.6382e-04 - accuracy: 1.0000
Epoch 00008: val_loss improved from 0.00251 to 0.00230, saving model to ./model.h5
۱۳/۱۳ [==============================] - ۱s 46ms/step - loss: 5.1158e-04 - accuracy: 1.0000 - val_loss: 0.0023 - val_accuracy: 1.0000
Epoch 9/100
۱۱/۱۳ [========================>.....] - ETA: 0s - loss: 4.4580e-04 - accuracy: 1.0000
Epoch 00009: val_loss did not improve from 0.00230
۱۳/۱۳ [==============================] - 0s 33ms/step - loss: 4.7193e-04 - accuracy: 1.0000 - val_loss: 0.0025 - val_accuracy: 1.0000
Epoch 10/100
۱۱/۱۳ [========================>.....] - ETA: 0s - loss: 3.7999e-04 - accuracy: 1.0000
Epoch 00010: val_loss did not improve from 0.00230
۱۳/۱۳ [==============================] - 0s 35ms/step - loss: 4.1578e-04 - accuracy: 1.0000 - val_loss: 0.0027 - val_accuracy: 1.0000
Epoch 11/100
۱۱/۱۳ [========================>.....] - ETA: 0s - loss: 3.3985e-04 - accuracy: 1.0000
Epoch 00011: val_loss did not improve from 0.00230
۱۳/۱۳ [==============================] - 0s 35ms/step - loss: 3.7973e-04 - accuracy: 1.0000 - val_loss: 0.0027 - val_accuracy: 1.0000
Epoch 12/100
۱۱/۱۳ [========================>.....] - ETA: 0s - loss: 3.8943e-04 - accuracy: 1.0000
Epoch 00012: val_loss improved from 0.00230 to 0.00210, saving model to ./model.h5
۱۳/۱۳ [==============================] - ۱s 47ms/step - loss: 3.4834e-04 - accuracy: 1.0000 - val_loss: 0.0021 - val_accuracy: 1.0000
Epoch 00012: early stopping

رسم نمودار مدل:

import matplotlib.pyplot as plt

print(history.history.keys())

plt.figure()
plt.plot(history.history['accuracy'], 'orange', label='Training accuracy')
plt.plot(history.history['val_accuracy'], 'blue', label='Validation accuracy')
plt.plot(history.history['loss'], 'red', label='Training loss')
plt.plot(history.history['val_loss'], 'green', label='Validation loss')
plt.legend()
plt.show()

با اجرای کد بالا نمودار زیر نمایش داده می شود:

قسمت هشتم: ایجاد دیتاست تست:

برای هر تصویر نمونه، ما تصاویر توصیفی از نوع Grad-CAm و SmoothGrad ایجاد می کنیم که اینکارو با استفاده از tf-explain انجام میدیم.

درون نرم افزار Colab کدهای زیر را به ترتیب اجرا کنید:

%tensorflow_version 2.x
%%bash

pip install -q -U tf-explain
import tensorflow as tf

print(tf.__version__)
tf.keras.backend.clear_session()

خروجی کد بالا ورژن tf را نمایش خواه داد:

۲.۱.۰
model = tf.keras.models.load_model('./model.h5')
test_dataset = p.get_dataset_by_name('TEST')
test_dataset.prepare()
import numpy as np
from PIL import Image
from tf_explain.core.grad_cam import GradCAM
from tf_explain.core.smoothgrad import SmoothGrad
import cv2
import matplotlib.pyplot as plt

img_width = 224
img_height = 224

plt.figure(figsize=(20, 10))

for i, image_id in enumerate(test_dataset.image_ids): 
    
    image = mdai.visualize.load_dicom_image(image_id, to_RGB=True)
    image = Image.fromarray(image)
    image = image.resize((img_width, img_height))
    
    X = np.empty((1, img_width, img_height, 3))
    X[0,:] = image
    y_prob = model.predict(X)
    y_classes = y_prob.argmax(axis=-1)
    
    pred_class = test_dataset.class_id_to_class_text(y_classes[0])
    pred_prob = y_prob[0][y_classes[0]]
    title = f'Pred: {pred_class}, Prob: {pred_prob:.3}'
    
    plt.subplot(len(test_dataset.image_ids), 3, i*3+1)
    plt.title(title)
    plt.imshow(image)
    plt.axis('off')
    
    explainer = GradCAM()
    output = explainer.explain(
        validation_data=(X, None),
        model=model,
        layer_name="conv_pw_13",
        class_index=y_classes[0],
        colormap=cv2.COLORMAP_TURBO,
    )
    
    plt.subplot(len(test_dataset.image_ids), 3, i*3+2)
    plt.imshow(output)
    plt.axis('off')
    
    explainer = SmoothGrad()
    output = explainer.explain(
        validation_data=(X, None),
        model=model,
        class_index=y_classes[0],
    )
    
    plt.subplot(len(test_dataset.image_ids), 3, i*3+3)
    plt.imshow(output, cmap='gray')
    plt.axis('off')
    
plt.show()

و در نهایت با اجرای کد بالا خواهیم داشت:

WARNING:tensorflow:From /home/leon/.pyenv/versions/3.7.5/lib/python3.7/site-packages/tensorflow_core/python/ops/image_ops_impl.py:1556: div (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.
Instructions for updating:
Deprecated in favor of operator or tf.math.divide.

لینک درس های منتشر شده:

پایتون پزشکی: درس اول: پردازش تصاویر پزشکی

پایتون پزشکی: درس دوم: ناحیه بندی مفهومی تصاویر X-Ray ریه

2 دیدگاه در “پایتون پزشکی: درس اول: پردازش تصاویر پزشکی

  1. درود
    بنده قصد دارم یک کار پزشکی با پایتون برای سگمنتیشن روی تصاویر ام آر انجام دهم
    کار شما حالب است
    اگر لطف کنید این مطالب را برام ایمیل کنید ممنون میشم

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

قبلا حساب کاربری ایجاد کرده اید؟
گذرواژه خود را فراموش کرده اید؟
Loading...