كيفية الكشف عن Covid-19 الذي يسببه فايروس كورونا المستجد باستخدام الـDeepLearning (التعلم العميق)

كيفية الكشف عن Covid-19 الذي يسببه فايروس كورونا المستجد باستخدام الـDeepLearning (التعلم العميق)

اكتشاف Covid-19 تلقائيًا في صور الأشعة السينية باستخدام لغة البرمجة Python وتقنيات التعلم العميق

في يومنا هذا، يعلم الصغير قبل الكبير الخطر المحدق الذي يحيط بعالمنا وهو مرض Covid-19، الذي يسببه الفيروس التاجي (فايروس كورونا) الذي أصاب حتى وقتنا هذا 2,426,753 شخص حول العالم.

man using a laptop at a wood workshop
Photo by Ivan Samkov on Pexels.com

هو مرض معد تسببه متلازمة الالتهاب الرئوي الحاد 2 (سارس -CoV -2). تم تحديد المرض لأول مرة في عام 2019 في ووهان، الصين، وانتشر منذ ذلك الحين على مستوى العالم، مما أدى إلى جائحة فيروس كورونا 2019-2020. تشمل الأعراض الشائعة الحمى والسعال وضيق التنفس.

لكن في مقالنا هذا، لن نتحدث عن المرض نفسه أو اعراضه أو طرق انتشاره. إنما، سيقوم عملنا على تصنيف الصور الشعاعية للصدر والرئة أما إلى Covid-19 (إيجابي) أو Covid-19 (سلبي) على الصدر,عن طريق إنشاء نموذج (model) بواسطة التعليم العميق باستخدام Python ومكتباته TensorFlow وKeras وOpenCV.

بداية لنتحدث قليلاً عن مفهوم التعلم العميق DeepLearning:

تعريف التعلم العميق:

كان أول ظهور للتعلم العميق عام 2006 والذي يطلق عليه أيضاً التعلم عميق البنية أو التعلم الهرمي كمجال جديد ضمن بحث تعلم الألة Machine Learning (ML) والذي تطور بشكل كبير في السنوات الأخرى ودخل في العديد من المجالات الطبية و القيادة الذاتية للمركبات و معالجة الصورة ومختلف العلوم التقليدية والحديثة ومختلف مجالات تعلم الآلة والذكاء الصنعي.

يمكننا الآن إعداد بيئة التطوير التي سنستخدمها لهذا المشروع.

إعداد بيئة التطوير الافتراضية:

البيئة الافتراضية: هي أداة تساعد في الحفاظ على المتطلبات (مكتبات مثلاً) الخاصة بالمشاريع المختلفة بشكل منفصل عن طريق إنشاء بيئات بايثون افتراضية معزولة لهذه المشاريع. وهذا يعني أن كل مشروع يمكن أن يكون له متطلبات خاصة به، بغض النظر عن المتطلبات الموجودة في مشروع آخر.

في Python، لبناء بيئة افتراضية، نستخدم حزمة virtualenv.

نقوم بتحميل virtualenv في بايثون كما يلي:

pip install virtualenv

ثم نقوم بإنشاء البيئة باستخدام الأمر التالي:

virtualenv project

سيؤدي هذا إلى إنشاء مجلد المشروع. ثم نقوم بتفعيل البيئة الافتراضية:

On UNIX (Mac and Linux): source project/bin/activate

On Windows: project\env\Scripts\activate.Bat

هكذا نكون قد قمنا بتثبيت وإعداد بيئة التطوير، والآن نحتاج إلى تثبيت الحزم (المكتبات) التي سنستخدمها خلال هذا المشروع:

يتم تثبيت كل حزمة بالتعليمة المرافقة لها:


·        TensorFlow (ستأخذ بعض الوقت): pip install tensorflow
·        scikit-learn: pip install sklearn
·        Imutils: pip install imutils
·        Matplotlib: pip install matplotlib
·        OpenCV: pip install opencv-python

بعد تثبيت كل هذه الحزم، نكون على استعداد للانتقال إلى الخطوة التالية.

سنقوم ببناء شبكة CNN التي تكتشف الفيروس التاجي في صور الأشعة السينية.

لمحة: الشبكة العصبية الالتفافية  CNN أحد تقنيات الشبكات العصبونية التي تعنى بالرؤية الحاسوبية في الذكاء الصنعي مثل معالجة الصور والفيديوهات

الخطوات التي سيتم سردها في هذا المقال:

  • تحميل مجموعة البيانات
  • بناء شبكة عصبية التفافية CNN لاكتشاف Covid-19 تلقائيًا في صور الأشعة السينية
  • بناء النموذج

مجموعة البيانات The Dataset:

تم تنسيق مجموعة بيانات (صور) Covid-19 للأشعة السينية التي سنستخدمها في هذا المشروع من قبل الدكتور جوزيف كوهين Dr. Joseph Cohen، زميل ما بعد الدكتوراه في جامعة مونتريال.

يمكنك تحميل مجموعة البيانات من هنا.

بمجرد تحميل الملف مضغوط، قم بفك ضغطه. يجب أن تشاهد في مجلد التنزيلات مجلد /dataset. انقله إلى المسار الذي ستستخدمه خلال هذا المشروع.

هيكل مجموعة البيانات:

كما لاحظنا في الصورة السابقة، يتم فصل مجموعة البيانات الخاصة بنا إلى مجلدين: / covid و / normal.

يحتوي الدليل / covid على 25 صورة بالأشعة السينية للصدر الإيجابي للجوف بينما يحتوي المجلد /normal على 25 صورة بالأشعة السينية للصدر السلبي.

نموذج CNN:

بعد رؤية كيف يتم بناء مجموعة البيانات الخاصة بنا، يمكننا البدء في بناء CNN الخاص بنا.

الحزم المطلوبة (المكتبات) و البارمترات الخاصة :

نقوم بإنشاء ملف train_covid19.py و الصق الكود التالي:

# import the necessary modules
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.applications import VGG16
from tensorflow.keras.layers import AveragePooling2D
from tensorflow.keras.layers import Dropout
from tensorflow.keras.layers import Flatten
from tensorflow.keras.layers import Dense
from tensorflow.keras.layers import Input
from tensorflow.keras.models import Model
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.utils import to_categorical
from sklearn.preprocessing import LabelBinarizer
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix
from imutils import paths
import matplotlib.pyplot as plt
import numpy as np
import argparse
import cv2
import os

يستخدم البرنامج النصي script الذي سننشئه مكتبات TensorFlow و Keras و scikit-learn ومكتبات OpenCV

سوف نستخدم:

  •  TensorFlow و Keras للعمل مع كل شيء يتعلق بشبكة CNN (الشبكة العصبية الالتفافية)
  •  Scikit-learn العمل مع المعالجة المسبقة للبيانات preprocessing وتقييم النموذج evaluating
  • OpenCV لتحميل الصور ومعالجتها
  •  Matplotlib لرسم نتائج النموذج

بعد استيراد الحزم المطلوبة، نقوم بتحليل معاملات سطر الأوامر وتهيئة المعاملات (المعاملات التي سيتم استخدامها لإنشاء CNN):

# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-d", "--dataset", required=True,
	help="path to input dataset")
ap.add_argument("-p", "--plot", type=str, default="plot.png",
	help="path to output loss/accuracy plot")
ap.add_argument("-m", "--model", type=str, default="covid19.model",
	help="path to output loss/accuracy plot")
args = vars(ap.parse_args())


# initialize the initial learning rate, number of epochs to train for, and batch size
INIT_LR = 1e-3 # initial learning rate
EPOCHS = 25 # epochs
BS = 8 # batch size  

تحدد الأسطر من 2 إلى 9 بارامتراتنا في command-line:

-dataset هي مسار مجموعة البيانات.

-plot هو مسار اختياري لخرج الرسم البياني لسجل التدريب. الافتراضي هو plot.png.

–model هو المسار الاختياري لخرج النموذج(الموديل) Covid-19 ؛ بشكل افتراضي ، سيتم تسميته covid19.model.

تحدد الأسطر 13-15 معدل التعلم الإبتدائي initial، وعدد التكرارات epochs ، وجحمbatch .

تحميل ومعالجة البيانات:

الآن يمكننا تحميل مجموعة البيانات dataset والقيام بالمعالجة المسبقة  preprocess لبيانات الأشعة السينية x-ray.

# grab the list of images in our dataset directory, then initialize the list of data (i.e., images) and class images
print("[INFO] loading images...")
imagePaths = list(paths.list_images(args["dataset"]))
data = []
labels = []


# loop over the image paths
for imagePath in imagePaths:
	# extract the class label from the filename
	label = imagePath.split(os.path.sep)[-2]

	# load the image, swap color channels, and resize it to be a fixed
	# 224x224 pixels while ignoring aspect ratio
	image = cv2.imread(imagePath)
	image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
	image = cv2.resize(image, (224, 224))

	# update the data and labels lists, respectively
	data.append(image)
	labels.append(label)


# convert the data and labels to NumPy arrays while scaling the pixel
# intensities to the range [0, 255]
data = np.array(data) / 255.0
labels = np.array(labels)

لتحميل بياناتنا، نأخذ مسار للصور الموجودة في مجموعة البيانات (السطر 3).

 ثم بالنسبة لكل مسار صورة image Path ، نقوم بما يلي:

استخرج التسمية أي الفئة التي تنتمي لها الصورة (إما Covid أو normal) من المسار (السطر 9).

ثم نقوم بتحميل الصورة، ومعالجة مسبقة عن طريق التحويل إلى ترتيب مسار RGB، وقم بتغيير حجمها إلى 224 × 224 بكسل حتى تكون جاهزة لشبكتنا العصبية الالتفافية (الأسطر 12-14).

ثم نقوم بتحديث قوائم البيانات data list  و الفئات labels ، على التوالي (السطران 16 و 17).

الأسطر 20-21: تحويل البيانات والفئات إلى مصفوفات NumPy.

يمكننا الآن ترميز الفئتين التي تصنف الصور لهما باستخدام ترميز on-hot encoding (السطور من 2 إلى 4) وتقسيم مجموعة البيانات إلى بيانات تدريب واختبار:

	# perform one-hot encoding on the labels
	lb = LabelBinarizer()
	labels = lb.fit_transform(labels)
	labels = to_categorical(labels)
	

	# partition the data into training and testing splits using 80% of
	# the data for training and the remaining 20% for testing
	(trainX, testX, trainY, testY) = train_test_split(data, labels,
		test_size=0.20, stratify=labels, random_state=42)
	

	# initialize the training data augmentation object
	trainAug = ImageDataGenerator(
		rotation_range=15,
		fill_mode="nearest") 

الترميز أحادي يعني أن بياناتنا سيتم عرضها بالتنسيق التالي:

[[0. 1.] [0. 1.] [0. 1.] … [1. 0.] [1. 0.] [1. 0.]]

يتكون كل صنف مرمز encoded label من مصفوفة من عنصرين يكون أحد العناصر “hot” (1) أو “not” (0). نستخدمها حسب الحاجة لتصنيف الحالات الإيجابية أو السلبية؛ أي، نقوم بإجراء تصنيف ثنائي binary classification.

في السطر 9، حجم الاختبار 0.20 يعني أننا قمنا بتقسيم مجموعة البيانات، مع الاحتفاظ بـ 20٪ منها للاختبار و80٪ المتبقية للتدريب.

بعد ذلك، في السطور من 12 إلى 14، نقوم بإجراء زيادة البيانات، وهي من تقنيات المعالجة المسبقة للبيانات التي تعمل على تحسين قدرة النموذج على التصنيف.

بناء النموذج Build the model:

بعد تحضير البيانات و معالجتها، يمكننا الآن تهيئة نموذجنا الذي سيقوم بالتصنيف, وسنستخدم VGG16 model.

# load the VGG16 network, ensuring the head FC layer sets are left off
	baseModel = VGG16(weights="imagenet", include_top=False,
		input_tensor=Input(shape=(224, 224, 3)))
	

	# construct the head of the model that will be placed on top of the the base model
	headModel = baseModel.output
	headModel = AveragePooling2D(pool_size=(4, 4))(headModel)
	headModel = Flatten(name="flatten")(headModel)
	headModel = Dense(64, activation="relu")(headModel)
	headModel = Dropout(0.5)(headModel)
	headModel = Dense(2, activation="softmax")(headModel)
	

	# place the head FC model on top of the base model (this will become the actual model we will train)
	model = Model(inputs=baseModel.input, outputs=headModel)
	

	# loop over all layers in the base model and freeze them so they will *not* be updated during the first training process
	for layer in baseModel.layers:
		layer.trainable = False

الأسطر 2-3 تعمل على إنشاء شبكة VGG16 بأوزان مُدرَّبة مسبقًا على ImageNet.

في الأسطر 6-11، نقوم ببناء طبقات head layer، وفي السطر 14، نضيفهم للنموذج (الموديل).

في الأسطر 17-18، نقوم بإلغاء تفعيل كل طبقة في نموذجنا حتى لا يتم تحديثها أثناء عملية التدريب الأولى.

تدريب الشبكة العصبية الالتفافية (تدريب CNN):

نحن الآن على استعداد لتجميع وتدريب نموذج التعلم العميق Covid-19 (Coronavirus):

# compile our model
	print("[INFO] compiling model...")
	opt = Adam(lr=INIT_LR, decay=INIT_LR / EPOCHS)
	model.compile(loss="binary_crossentropy", optimizer=opt,
		metrics=["accuracy"])
	

	# train the head of the network
	print("[INFO] training head...")
	H = model.fit_generator(
		trainAug.flow(trainX, trainY, batch_size=BS),
		steps_per_epoch=len(trainX) // BS,
		validation_data=(testX, testY),
		validation_steps=len(testX) // BS,
		epochs=EPOCHS)

الأسطر 3-4: هنا نقوم بتجميع CNN باستخدام Adam المحسّن.

 بالنظر إلى أن هذه مشكلة من صنفين، فإننا نستخدم loss=”binary_crossentropy” وذلك من أجل فقد البيانات.

الأسطر من 9 إلى 14: نقوم باستدعاء Keras ‘fit_generator ، أثناء تمرير بيانات الأشعة السينية للصدر عبر أداة زيادة البيانات augmentation.

تقييم النموذج Evaluate the model:

بعد تدريب النموذج، نقوم بتقييمه:

# make predictions on the testing set
	print("[INFO] evaluating network...")
	predIdxs = model.predict(testX, batch_size=BS)
	

	# for each image in the testing set we need to find the index of the label with corresponding largest predicted probability
	predIdxs = np.argmax(predIdxs, axis=1)
	

	# show a nicely formatted classification report
	print(classification_report(testY.argmax(axis=1), predIdxs,
		target_names=lb.classes_))

الأسطر 3-6: نقوم بإجراء تنبؤات على مجموعة بيانات الاختبار ونأخذ قيم التنبؤ.

الأسطر 9-10: ننشئ هنا ونطبع تقرير تصنيف باستخدام الأداة المساعدة لـ scikit-learn.

بعد ذلك، نحسب مصفوفة الارتياب confusion matrix من أجل التقييم دقة عمل النموذج:

# compute the confusion matrix and and use it to derive the raw accuracy, sensitivity, and specificity
	cm = confusion_matrix(testY.argmax(axis=1), predIdxs)
	total = sum(sum(cm))
	acc = (cm[0, 0] + cm[1, 1]) / total
	sensitivity = cm[0, 0] / (cm[0, 0] + cm[0, 1])
	specificity = cm[1, 1] / (cm[1, 0] + cm[1, 1])
	

	# show the confusion matrix, accuracy, sensitivity, and specificity
	print(cm)
	print("acc: {:.4f}".format(acc))
	print("sensitivity: {:.4f}".format(sensitivity))
	print("specificity: {:.4f}".format(specificity))

السطر 2: إنشاء مصفوفة الارتياب.

الأسطر 4-6: استخدم مصفوفة الارتياب لاشتقاق الدقة والحساسية (عدم الاستقرار) والخصوصية وطباعتها (الأسطر 9-12).

لمحة: الحساسية والخصوصية هي مقاييس إحصائية لأداء اختبار التصنيف الثنائي، والمعروف أيضًا في الإحصاء باسم دالة التصنيف، والتي تستخدم على نطاق واسع في الطب:

الحساسية (تسمى أيضًا المعدل الإيجابي الحقيقي، والاستدعاء، أو احتمال الكشف في بعض المجالات) تقيس نسبة الإيجابيات الفعلية التي تم تحديدها بشكل صحيح على هذا النحو (على سبيل المثال، نسبة المرضى الذين تم تحديدهم بشكل صحيح على أنهم حققوا الحالة أو الإصابة).

تقيس النوعية (تسمى أيضًا المعدل السلبي الحقيقي) نسبة السلبيات الفعلية التي تم تحديدها بشكل صحيح على هذا النحو (على سبيل المثال، النسبة المئوية للأشخاص الأصحاء الذين تم تحديدهم بشكل صحيح على أنهم ليس لديهم الحالة).

لقد انتهينا على الأقل من كشف Covid-19)) عن طريق CNN . لكننا نريد أيضًا الاطلاع على تسلسل تدريب الكاشف (الموديل المدرب)، وفي النهاية، حفظ النموذج في ملف.

# plot the training loss and accuracy
	N = EPOCHS
	plt.style.use("ggplot")
	plt.figure()
	plt.plot(np.arange(0, N), H.history["loss"], label="train_loss")
	plt.plot(np.arange(0, N), H.history["val_loss"], label="val_loss")
	plt.plot(np.arange(0, N), H.history["accuracy"], label="train_acc")
	plt.plot(np.arange(0, N), H.history["val_accuracy"], label="val_acc")
	plt.title("Training Loss and Accuracy on COVID-19 Dataset")
	plt.xlabel("Epoch #")
	plt.ylabel("Loss/Accuracy")
	plt.legend(loc="lower left")
	plt.savefig(args["plot"])
	

	# serialize the model to disk
	print("[INFO] saving COVID-19 detector model...")
	model.save(args["model"], save_format="h5")

الأسطر  2-12: الرسم البياني للدقة / خسارة  accuracy/loss في تدريب النموذج.

السطر 13: احفظ الرسم البياني في plot.png التي حددناها.

الأسطر 16-17: حفظ النموذج في ملف من النوع .model.

انتهى!

الاختبار:

كما ترى، فإن ملف train_covid19.py الذي أنشأناه من قبل موجود في نفس المسار لمجلد /dataset. هذه نقطة رئيسية، حيث يبحث البرنامج النصي script عن مجلد مجموعة البيانات في المجلد /covid-19_x_rays_detect.

بمجرد إعداد الدليل directory كما رأينا سابقًا، يمكننا تنفيذ ملف train_covid19.py:

python3 train_covid19.py –dataset dataset

سيستغرق هذا بضع دقائق، حيث أن العمل مع الصور أكثر تكلفة من الناحية الحسابية.

عند تنفيذ train_covid19.py:

1-     تتم قراءة مجموعة البيانات ومعالجتها مسبقًا

2-     ثم تحميل أوزان الموديل VGG16

3-     ثم تدريب الموديل لمدة 25 تكرار

4-     ثم تقييم أداء CNN

5-     طباعتها

من خلال قراءة الرسم البياني لتدريب النموذج، يمكننا الحصول على ما يلي:

  • النموذج ليس مدرباً بشكل مفرط over-fitted أو غير مناسب under-fitted.
  • ينخفض الخطأ عندما تزداد التكرارات.

حتى الآن نكون قد صممنا موديل قادر على الكشف عن مرض Covid19 من خلال صور الأشعة السينية للصدر وبدقة 80%، نلاحظ أن هذه النسبة ليست كافية طبياً، والسبب وراء انخفاض الدقة:

مجموعة البيانات صغيرة جدًا. لسوء الحظ، لم أجد أي أشعة سينية أخرى مصابة بـ Covid-19.

الخاتمة: 

يعمل خبراء الذكاء الصنعي وعلم البيانات جنبا لجنب مع الأطباء والباحثين من أجل إيجاد لقاح و علاج فعال للحد من انتشار هذا الوباء العالمي الذي هدد حياتنا .

فيمكننا القول أن الذكاء الصنعي بمجالاته يمكن أن يقحم تقنياته في مختلف المجالات ومشاركة الإنسان ومساعدته في شتى مجالات الحياة فهو يتفوق على القدرات البشرية من ناحية الدقة والسرعة, ونأمل أن تنتشر علوم الذكاء الصنعي في جميع المجتمعات مع إمكانية رؤية تطبيقاته على أرض الواقع.

المصدر : https://medium.com/better-programming/how-to-detect-coronavirus-using-deep-learning-1568332c728