Recognition (3 diseases) from X-ray (Machine Learning tutorial) with accuracy: 96%. Using TensorFlow
By: Alex G.
Tags: Colab, Image Classification, TensorFlow, Keras, Python

So Let’s start :)

In order to get started, we need data. I took the data for this task from here:

- Dataset with Pneumonia and Normal https://www.kaggle.com/paultimothymooney/chest-xray-pneumonia

Dataset with Tuberculosis and Normal

https://www.dropbox.com/s/f64cvlhm0gp80v5/tuberculosis.zip?dl=1 -O tuberculosis.zip or from https://www.kaggle.com/raddar/tuberculosis-chest-xrays-shenzhen

I downloaded these datasets and combined them into one folder to make them look like this:

Then, I used the “Imagedatagenerator” to add the data only for training the neural model (not for validation) as there is not a lot of data.

train_datagen = ImageDataGenerator(rescale=1. / 255,

height_shift_range= 0.02,

width_shift_range=0.02,

rotation_range=0.02,

shear_range = 0.01,

fill_mode='nearest',

zoom_range=0.01) train_generator = train_datagen.flow_from_directory(

train_dir,

target_size=(image_size, image_size),

batch_size=batch_size,

class_mode='categorical') test_datagen = ImageDataGenerator(rescale=1. / 255) test_generator = test_datagen.flow_from_directory(

test_dir,

target_size=(image_size, image_size),

batch_size=batch_size,

class_mode='categorical')

After the data was prepared, I decided to use the pretrained model “Xception”. This model works very well with images and has very high scores when trained on new data. It is also the #1 in models that are available to public and the best rated

The first stage of training is “Transfer learning”. To do this, we download the model, “freeze” the weights from “Imagenet” (since this model was trained on the Imagenet dataset), add our layers to the existing model, and train. Besides, we save only the best results when we are training the model.

pretrained_model = tf.keras.applications.Xception(weights='imagenet', include_top=False) #download Xception model without last layer pretrained_model.trainable = False #"Frozen" all weights pretrained models #Created main layers for end Xception model x = pretrained_model.output

x = GlobalAveragePooling2D()(x)

x = Dense(512)(x)

x = BatchNormalization()(x)

x = Activation('relu')(x)

x = Dropout(0.5)(x)

predictions = Dense(3, activation='softmax')(x)

model = Model(inputs=pretrained_model.input, outputs=predictions) #compile & start train model model.compile(loss='categorical_crossentropy',

optimizer='adam',

metrics=["accuracy"]) filepath="inceptionv3_best.h5"

checkpoint = ModelCheckpoint(filepath, monitor='val_loss', verbose=1,

save_best_only=True, mode='min')

learning_rate_reduction = ReduceLROnPlateau(monitor='val_loss',

patience=10,

verbose=1,

factor=0.5,

min_lr=0.00001)

callbacks_list = [checkpoint, learning_rate_reduction] steps_per_epoch = 32

history = model.fit_generator(

train_generator,

steps_per_epoch=steps_per_epoch,

validation_data=test_generator,

validation_steps=5,

callbacks=callbacks_list,

epochs=50,

verbose=1)

After “Transfer Learning” we have good results::

loss: 0.1679 — accuracy: 0.9336 — val_loss: 0.3329 — val_accuracy: 0.8687

However, we need better results. Therefore, we will do “Fine Tuning”. For this, we will load the best weights that were saved before from “Tranfer learning”, “unfreeze” several layers, and train them on our data.

model.load_weights("inceptionv3_best.h5") #upload best weights #Defrost the last 2 blocks pretrained_model.trainable = False

for layer in model.layers[:290]:

layer.trainable = False

for layer in model.layers[290:]:

layer.trainable = True #compile & start train model model.compile(loss='categorical_crossentropy',

optimizer='adam',

metrics=["accuracy"]) filepath="inceptionv3_fine_tuned.h5"

checkpoint = ModelCheckpoint(filepath, monitor='val_accuracy', verbose=1, save_best_only=True, mode='max')

callbacks_list = [checkpoint, learning_rate_reduction] steps_per_epoch = 32

history = model.fit_generator(

train_generator,

steps_per_epoch=steps_per_epoch,

validation_data=test_generator,

validation_steps=5,

callbacks=callbacks_list,

epochs=40,

verbose=2)

Let’s check our results after applying “Fine Tuning”.

loss: 0.1144 — accuracy: 0.9600 — val_loss: 0.2944 — val_accuracy: 0.9000

Awesome!

Now let’s recognize Pneumonia on the new image that neural network has not seen before.

from tensorflow.keras.applications.inception_v3 import InceptionV3

from tensorflow.keras.preprocessing import image

from tensorflow.keras.models import Model, load_model

from tensorflow.keras.callbacks import ModelCheckpoint, ReduceLROnPlateau

from tensorflow.keras.layers import Dense, GlobalAveragePooling2D, Dropout

from tensorflow.keras.layers import BatchNormalization, Activation

from tensorflow.python.keras.optimizers import Adam, RMSprop

from tensorflow.python.keras.preprocessing.image import ImageDataGenerator

import numpy as np

import matplotlib.pyplot as plt

import tensorflow as tf

from numpy import loadtxt

import tensorflow.keras

from PIL import Image, ImageOps

%matplotlib inline image_size = 256

batch_size = 32

model = tensorflow.keras.models.load_model('inceptionv3_best.h5') img_path = '/content/chest_xray/test/PNEUMONIA/person100_bacteria_475.jpeg'

img = image.load_img(img_path, target_size=(image_size, image_size))

plt.imshow(img)

plt.show() x = image.img_to_array(img)

x /= 255

x = np.expand_dims(x, axis=0)

prediction = model.predict(x)

prediction

classes = np.argmax(prediction, axis = 1)

print(classes)

Result:

Here we are! Our model has just recognized Pneumonia.

I would like to remind you that the completed code is located here.