COVID-19 Detection with ML and CXR | تشخیص کرونا توسط یادگیری ماشین و CXR


زمانیکه شروع به ساخت این برنامه کردم بحران تعداد کیت داشتیم
با توجه به علائم کیفی مانند تب و سرفه و غیره نمیتوان بطور قطع گفت که فرد مبتلا به این بیماریست یا خیر …
بنابر مقاله های جدید منتشر شده در دو هفته اخیر متوجه شدم که اسکن ریه میتونه خیلی واضح توی روند تشخیص کمک کنه.
با مطالعه مقالات و پیدا کردن دیتابیسشون تونستم یه شمای کلی از مساله پیدا کنم
متاسفانه تنها مشکل این نرم افزار کم بودن داده های آموزش هست که خوب میشه اگر بیمارستان ها بتونند داده هاشون رو به اشتراک بزارن
علاوه بر عکس های ایکس ری، نیاز به داده های بیشتر مثل سچوریشن اکسیژن خون، میزان دمای بدن، جنسیت و فاکتور های دیگر رو میشه بعنوان ورودی به سیستم داد تا تخمین دقیق تری داشته باشیم
When I started to work on this problem, we had problem with numbers of DETECTING KITs to examine patients who had the symptoms.
After reading papers about this problem, I tried to create an demo app to distinguish between normal and abnormal lungs.


import os import numpy as np import pandas as pd import random import cv2 import matplotlib.pyplot as plt import keras.backend as K from keras.models import Model, Sequential from keras.layers import Input, Dense, Flatten, Dropout, BatchNormalization from keras.layers import Conv2D, SeparableConv2D, MaxPool2D, LeakyReLU, Activation from keras.optimizers import Adam from keras.preprocessing.image import ImageDataGenerator from keras.callbacks import ModelCheckpoint, ReduceLROnPlateau, EarlyStopping import tensorflow as tf seed = 200 np.random.seed(seed) tf.random.set_seed(seed) input_path = 'chest_xray/DATA/' fig, img = plt.subplots(2, 3, figsize=(15, 15)) img = img.ravel() plt.tight_layout() for i, _set in enumerate(['train', 'val', 'test']): set_path = input_path+_set img[i].imshow(plt.imread(set_path+'/NORMAL/'+os.listdir(set_path+'/NORMAL')[0]), cmap='gray') img[i].set_title('Normal'.format(_set)) img[i+3].imshow(plt.imread(set_path+'/COVID/'+os.listdir(set_path+'/COVID')[0]), cmap='gray') img[i+3].set_title('nCoVid-19'.format(_set)) for _set in ['train', 'val', 'test']: n_normal = len(os.listdir(input_path + _set + '/NORMAL')) n_infect = len(os.listdir(input_path + _set + '/COVID')) print('normal images: {}, nCoVid-19 images: {}'.format(_set, n_normal, n_infect)) def process_data(img_dims, batch_size): train_datagen = ImageDataGenerator(rescale=1./255, zoom_range=0.3, vertical_flip=True) test_val_datagen = ImageDataGenerator(rescale=1./255) train_gen = train_datagen.flow_from_directory( directory=input_path+'train', target_size=(img_dims, img_dims), batch_size=batch_size, class_mode='binary', shuffle=True) test_gen = test_val_datagen.flow_from_directory( directory=input_path+'test', target_size=(img_dims, img_dims), batch_size=batch_size, class_mode='binary', shuffle=True) test_data = [] test_labels = [] for cond in ['/NORMAL/', '/COVID/']: for img in (os.listdir(input_path + 'test' + cond)): img = plt.imread(input_path+'test'+cond+img) img = cv2.resize(img, (img_dims, img_dims)) img = np.dstack([img, img, img]) img = img.astype('float32') / 255 if cond=='/NORMAL/': label = 0 elif cond=='/COVID/': label = 1 test_data.append(img) test_labels.append(label) test_data = np.array(test_data) test_labels = np.array(test_labels) return train_gen, test_gen, test_data, test_labels img_dims = 150 epochs = 10 batch_size = 32 train_gen, test_gen, test_data, test_labels = process_data(img_dims, batch_size) inputs = Input(shape=(img_dims, img_dims, 3)) x = Conv2D(filters=16, kernel_size=(3, 3), activation='relu', padding='same')(inputs) x = Conv2D(filters=16, kernel_size=(3, 3), activation='relu', padding='same')(x) x = MaxPool2D(pool_size=(2, 2))(x) x = SeparableConv2D(filters=32, kernel_size=(3, 3), activation='relu', padding='same')(x) x = SeparableConv2D(filters=32, kernel_size=(3, 3), activation='relu', padding='same')(x) x = BatchNormalization()(x) x = MaxPool2D(pool_size=(2, 2))(x) x = SeparableConv2D(filters=64, kernel_size=(3, 3), activation='relu', padding='same')(x) x = SeparableConv2D(filters=64, kernel_size=(3, 3), activation='relu', padding='same')(x) x = BatchNormalization()(x) x = MaxPool2D(pool_size=(2, 2))(x) x = SeparableConv2D(filters=128, kernel_size=(3, 3), activation='relu', padding='same')(x) x = SeparableConv2D(filters=128, kernel_size=(3, 3), activation='relu', padding='same')(x) x = BatchNormalization()(x) x = MaxPool2D(pool_size=(2, 2))(x) x = Dropout(rate=0.2)(x) x = SeparableConv2D(filters=256, kernel_size=(3, 3), activation='relu', padding='same')(x) x = SeparableConv2D(filters=256, kernel_size=(3, 3), activation='relu', padding='same')(x) x = BatchNormalization()(x) x = MaxPool2D(pool_size=(2, 2))(x) x = Dropout(rate=0.2)(x) x = SeparableConv2D(filters=512, kernel_size=(3, 3), activation='relu', padding='same')(x) x = SeparableConv2D(filters=512, kernel_size=(3, 3), activation='relu', padding='same')(x) x = BatchNormalization()(x) x = MaxPool2D(pool_size=(2, 2))(x) x = Dropout(rate=0.2)(x) output = Dense(units=1, activation='sigmoid')(x) model = Model(inputs=inputs, outputs=output) model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy']) checkpoint = ModelCheckpoint(filepath='best_weights.hdf5', save_best_only=True, save_weights_only=True) lr_reduce = ReduceLROnPlateau(monitor='val_loss', factor=0.3, patience=2, verbose=2, mode='max') early_stop = EarlyStopping(monitor='val_loss', min_delta=0.1, patience=1, mode='min') hist = model.fit_generator(train_gen, steps_per_epoch=train_gen.samples // batch_size,epochs=epochs, validation_data=test_gen,validation_steps=test_gen.samples // batch_size,callbacks=[checkpoint, lr_reduce])
https://pubs.rsna.org/2019-nCoV#images https://www.itnonline.com/content/ct-provides-best-diagnosis-novel-coronavirus-covid-19https://radiopaedia.org/cases/covid-19-pneumonia-4
Update 1: A Chinese group developed improved version of my idea :
https://www.medrxiv.org/content/10.1101/2020.02.14.20023028v3 A deep learning algorithm using CT images to screen for Corona Virus Disease (COVID-19) Shuai Wang, Bo Kang, Jinlu Ma, Xianjun Zeng, Mingming Xiao, Jia Guo, Mengjiao Cai, Jingyi Yang, Yaodong Li, Xiangfei Meng, Bo Xu doi: https://doi.org/10.1101/2020.02.14.20023028
Update 2: Dataset I used: DOWNLOAD
Update 3: Add this part to the code if you face with errors
import os import numpy as np import pandas as pd import random import cv2 import matplotlib.pyplot as plt import keras.backend as K from keras.models import Model, Sequential from keras.layers import Input, Dense, Flatten, Dropout, BatchNormalization from keras.layers import Conv2D, SeparableConv2D, MaxPool2D, LeakyReLU, Activation from keras.optimizers import Adam from keras.preprocessing.image import ImageDataGenerator from keras.callbacks import ModelCheckpoint, ReduceLROnPlateau, EarlyStopping import tensorflow as tf seed = 200 np.random.seed(seed) tf.random.set_seed(seed) input_path = 'chest_xray/DATA/' fig, img = plt.subplots(2, 3, figsize=(15, 15)) img = img.ravel() plt.tight_layout() for i, _set in enumerate(['train', 'val', 'test']): set_path = input_path+_set img[i].imshow(plt.imread(set_path+'/NORMAL/'+os.listdir(set_path+'/NORMAL')[0]), cmap='gray') img[i].set_title('Normal'.format(_set)) img[i+3].imshow(plt.imread(set_path+'/COVID/'+os.listdir(set_path+'/COVID')[0]), cmap='gray') img[i+3].set_title('nCoVid-19'.format(_set)) for _set in ['train', 'val', 'test']: n_normal = len(os.listdir(input_path + _set + '/NORMAL')) n_infect = len(os.listdir(input_path + _set + '/COVID')) print('normal images: {}, nCoVid-19 images: {}'.format(_set, n_normal, n_infect)) def process_data(img_dims, batch_size): train_datagen = ImageDataGenerator(rescale=1./255, zoom_range=0.3, vertical_flip=True) test_val_datagen = ImageDataGenerator(rescale=1./255) train_gen = train_datagen.flow_from_directory( directory=input_path+'train', target_size=(img_dims, img_dims), batch_size=batch_size, class_mode='binary', shuffle=True) test_gen = test_val_datagen.flow_from_directory( directory=input_path+'test', target_size=(img_dims, img_dims), batch_size=batch_size, class_mode='binary', shuffle=True) test_data = [] test_labels = [] for cond in ['/NORMAL/', '/COVID/']: for img in (os.listdir(input_path + 'test' + cond)): img = plt.imread(input_path+'test'+cond+img) img = cv2.resize(img, (img_dims, img_dims)) img = np.dstack([img, img, img]) img = img.astype('float32') / 255 if cond=='/NORMAL/': label = 0 elif cond=='/COVID/': label = 1 test_data.append(img) test_labels.append(label) test_data = np.array(test_data) test_labels = np.array(test_labels) return train_gen, test_gen, test_data, test_labels img_dims = 150 epochs = 10 batch_size = 32 train_gen, test_gen, test_data, test_labels = process_data(img_dims, batch_size) inputs = Input(shape=(img_dims, img_dims, 3)) x = Conv2D(filters=16, kernel_size=(3, 3), activation='relu', padding='same')(inputs) x = Conv2D(filters=16, kernel_size=(3, 3), activation='relu', padding='same')(x) x = MaxPool2D(pool_size=(2, 2))(x) x = SeparableConv2D(filters=32, kernel_size=(3, 3), activation='relu', padding='same')(x) x = SeparableConv2D(filters=32, kernel_size=(3, 3), activation='relu', padding='same')(x) x = BatchNormalization()(x) x = MaxPool2D(pool_size=(2, 2))(x) x = SeparableConv2D(filters=64, kernel_size=(3, 3), activation='relu', padding='same')(x) x = SeparableConv2D(filters=64, kernel_size=(3, 3), activation='relu', padding='same')(x) x = BatchNormalization()(x) x = MaxPool2D(pool_size=(2, 2))(x) x = SeparableConv2D(filters=128, kernel_size=(3, 3), activation='relu', padding='same')(x) x = SeparableConv2D(filters=128, kernel_size=(3, 3), activation='relu', padding='same')(x) x = BatchNormalization()(x) x = MaxPool2D(pool_size=(2, 2))(x) x = Dropout(rate=0.2)(x) x = SeparableConv2D(filters=256, kernel_size=(3, 3), activation='relu', padding='same')(x) x = SeparableConv2D(filters=256, kernel_size=(3, 3), activation='relu', padding='same')(x) x = BatchNormalization()(x) x = MaxPool2D(pool_size=(2, 2))(x) x = Dropout(rate=0.2)(x) x = SeparableConv2D(filters=512, kernel_size=(3, 3), activation='relu', padding='same')(x) x = SeparableConv2D(filters=512, kernel_size=(3, 3), activation='relu', padding='same')(x) x = BatchNormalization()(x) x = MaxPool2D(pool_size=(2, 2))(x) x = Dropout(rate=0.2)(x) x = Flatten()(x) x = Dense(units=512, activation='relu')(x) x = Dropout(rate=0.7)(x) x = Dense(units=128, activation='relu')(x) x = Dropout(rate=0.5)(x) x = Dense(units=64, activation='relu')(x) x = Dropout(rate=0.3)(x) x = Dense(units=32, activation='relu')(x) x = Dropout(rate=0.1)(x) output = Dense(units=1, activation='sigmoid')(x) model = Model(inputs=inputs, outputs=output) model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy']) checkpoint = ModelCheckpoint(filepath='best_weights.hdf5', save_best_only=True, save_weights_only=True) lr_reduce = ReduceLROnPlateau(monitor='val_loss', factor=0.3, patience=2, verbose=2, mode='max') early_stop = EarlyStopping(monitor='val_loss', min_delta=0.1, patience=1, mode='min') hist = model.fit_generator(train_gen, steps_per_epoch=train_gen.samples // batch_size,epochs=epochs, validation_data=test_gen,validation_steps=test_gen.samples // batch_size,callbacks=[checkpoint, lr_reduce])
16 Responses
Hi,
Can you share the dataset on which you worked?
I updated this post and added dataset. I changed folders containing COVID-19 subjects and deleted low-quality images, just add yours and run the code 🙂 good luck.
Thank you for this. Do you know if the Chinese group’s dataset is available? I can’t seem to access it.
https://ai.nscc-tj.cn/thai/deploy/public/pneumonia_ct
Do you know other places with the CT dataset?
I couldn’t find their dataset.
https://luna16.grand-challenge.org/download/
https://wiki.cancerimagingarchive.net/display/Public/Lung+CT+Segmentation+Challenge+2017
Most of the datasets are for classifying cancer
Also, I couldn’t open the url you mentioned.
It’s ok, but thank you again for compiling a dataset, even with the small sample. May I know where you got the images? I might use your dataset in the future and I would like to cite you and your sources. Thanks again!
https://www.kaggle.com/paultimothymooney/chest-xray-pneumonia
You are welcome
سلام مرسی از مطالبی که گذاشتید
دیتاستتون رو نگا میکردم فقط با 3 تا عکس از کرونا استفاده کردین . دقت شبکه تا چند درصد بود ؟
از چه معماری استفاده کردید ؟
نسخه تنسورفلو شما چنده ؟ چون من میخواستم تست کنم کلا بهم ارور داد با کد های بالا
نسخه پایتون چند استفاده کردید؟
سلام. تعداد 16 عکس استفاده کردم که غیر ا این 3 تا. 4 تا عکس دیگه از توی مقالات پیدا کرده بودم و بقیش رو هم دوستم که در بیمارستان کار میکنه برام فرستاده بود(9 عکس). 4 تا رو بخاطر اینکه حس کردم کیفیتش بده حذف کردم و بقیه رو بخاطر اینکه رایگان نبودن.
صرفا جهت ایده بود انجامش چون تازه اولای بیماری بود و تقریبا تعداد تصویر کمی با رعایت پروتکل های تصویر برداری خاص وجود داشت
شاید اگه ارور مورد نظر رو مینوشتین میتونستم کمکتون کنم چون برای من اروری نداده
Spyder 3.3.6
python 3.7
tensorflow 2.0.0
مرسی از راهنماییتون
تو شبکه ای که پیاده کردین خروجی نهایی چی هست؟
سگمنتیشن انجام میگیره مثل یونت ؟ یا چی؟
احتمالا مشکلتون رو فهمیدم! از قسمت آپدیت سوم استفاده کنید
مرسی اینم حتما چک میکنم . سپاس
ایول حل شد .
مشکلش چی بود ؟ میشه اشاره کنی بهش؟
من کلی بررسی کردم چیزی نفهمیده بودم
بخاطر ابعاد ورودی ها بود
من هرچی بگم کم گفتم بخاطر همین توابعی که میگم رو گوگل کن:
flatten – dropout
کاری هم که کردم خیلی سادس. فقط چن ردیف شبکه کانولوشنی تشکیل دادم/ (همونطور که گفتم این یه دمو هست و هدف ایده دادن بود فقط )
خیلی خیلی ممنونم
I foresaw this from February 9th, having started an ai based ct scan initiative:
http://www.facebook.com/ProgrammingGodJordan%2Fposts%2F889038718221822
it’s great, good job. Thanks for sharing
Comments are closed.