|
| 1 | +import matplotlib.pyplot as plt |
| 2 | +import pandas as pd |
| 3 | +import numpy as np |
| 4 | +import seaborn as sns |
| 5 | +import keras |
| 6 | +from keras.models import Sequential |
| 7 | +from keras.layers import Dense, Conv2D , MaxPool2D , Flatten , Dropout , BatchNormalization |
| 8 | +from keras.preprocessing.image import ImageDataGenerator |
| 9 | +from sklearn.model_selection import train_test_split |
| 10 | +from sklearn.metrics import classification_report,confusion_matrix |
| 11 | +from keras.callbacks import ReduceLROnPlateau |
| 12 | +import cv2 |
| 13 | +import os |
| 14 | + |
| 15 | +labels = ['PNEUMONIA', 'NORMAL'] |
| 16 | +img_size = 150 |
| 17 | +def get_training_data(data_dir): |
| 18 | + data = [] |
| 19 | + for label in labels: |
| 20 | + path = os.path.join(data_dir, label) |
| 21 | + class_num = labels.index(label) |
| 22 | + for img in os.listdir(path): |
| 23 | + try: |
| 24 | + img_arr = cv2.imread(os.path.join(path, img), cv2.IMREAD_GRAYSCALE) |
| 25 | + resized_arr = cv2.resize(img_arr, (img_size, img_size)) # Reshaping images to preferred size |
| 26 | + data.append([resized_arr, class_num]) |
| 27 | + except Exception as e: |
| 28 | + print(e) |
| 29 | + return np.array(data) |
| 30 | + |
| 31 | +train = get_training_data('/content/drive/MyDrive/chest-xray-pneumonia/chest_xray/train') |
| 32 | +test = get_training_data('/content/drive/MyDrive/chest-xray-pneumonia/chest_xray/test') |
| 33 | +val = get_training_data('/content/drive/MyDrive/chest-xray-pneumonia/chest_xray/val') |
| 34 | + |
| 35 | +l = [] |
| 36 | +for i in train: |
| 37 | + if(i[1] == 0): |
| 38 | + l.append("Pneumonia") |
| 39 | + else: |
| 40 | + l.append("Normal") |
| 41 | +sns.set_style('darkgrid') |
| 42 | +sns.countplot(l) |
| 43 | + |
| 44 | +plt.figure(figsize = (5,5)) |
| 45 | +plt.imshow(train[0][0], cmap='gray') |
| 46 | +plt.title(labels[train[0][1]]) |
| 47 | + |
| 48 | +plt.figure(figsize = (5,5)) |
| 49 | +plt.imshow(train[-1][0], cmap='gray') |
| 50 | +plt.title(labels[train[-1][1]]) |
| 51 | + |
| 52 | +x_train = [] |
| 53 | +y_train = [] |
| 54 | + |
| 55 | +x_val = [] |
| 56 | +y_val = [] |
| 57 | + |
| 58 | +x_test = [] |
| 59 | +y_test = [] |
| 60 | + |
| 61 | +for feature, label in train: |
| 62 | + x_train.append(feature) |
| 63 | + y_train.append(label) |
| 64 | + |
| 65 | +for feature, label in test: |
| 66 | + x_test.append(feature) |
| 67 | + y_test.append(label) |
| 68 | + |
| 69 | +for feature, label in val: |
| 70 | + x_val.append(feature) |
| 71 | + y_val.append(label) |
| 72 | + |
| 73 | +x_train = np.array(x_train) / 255 |
| 74 | +x_val = np.array(x_val) / 255 |
| 75 | +x_test = np.array(x_test) / 255 |
| 76 | + |
| 77 | +x_train = x_train.reshape(-1, img_size, img_size, 1) |
| 78 | +y_train = np.array(y_train) |
| 79 | + |
| 80 | +x_val = x_val.reshape(-1, img_size, img_size, 1) |
| 81 | +y_val = np.array(y_val) |
| 82 | + |
| 83 | +x_test = x_test.reshape(-1, img_size, img_size, 1) |
| 84 | +y_test = np.array(y_test) |
| 85 | + |
| 86 | +datagen = ImageDataGenerator( |
| 87 | + featurewise_center=False, |
| 88 | + samplewise_center=False, |
| 89 | + featurewise_std_normalization=False, |
| 90 | + samplewise_std_normalization=False, |
| 91 | + zca_whitening=False, |
| 92 | + rotation_range = 30, |
| 93 | + zoom_range = 0.2, |
| 94 | + width_shift_range=0.1, |
| 95 | + height_shift_range=0.1, |
| 96 | + horizontal_flip = True, |
| 97 | + vertical_flip=False) |
| 98 | + |
| 99 | + |
| 100 | +datagen.fit(x_train) |
| 101 | + |
| 102 | +model = Sequential() |
| 103 | +model.add(Conv2D(32 , (3,3) , strides = 1 , padding = 'same' , activation = 'relu' , input_shape = (150,150,1))) |
| 104 | +model.add(BatchNormalization()) |
| 105 | +model.add(MaxPool2D((2,2) , strides = 2 , padding = 'same')) |
| 106 | +model.add(Conv2D(64 , (3,3) , strides = 1 , padding = 'same' , activation = 'relu')) |
| 107 | +model.add(Dropout(0.1)) |
| 108 | +model.add(BatchNormalization()) |
| 109 | +model.add(MaxPool2D((2,2) , strides = 2 , padding = 'same')) |
| 110 | +model.add(Conv2D(64 , (3,3) , strides = 1 , padding = 'same' , activation = 'relu')) |
| 111 | +model.add(BatchNormalization()) |
| 112 | +model.add(MaxPool2D((2,2) , strides = 2 , padding = 'same')) |
| 113 | +model.add(Conv2D(128 , (3,3) , strides = 1 , padding = 'same' , activation = 'relu')) |
| 114 | +model.add(Dropout(0.2)) |
| 115 | +model.add(BatchNormalization()) |
| 116 | +model.add(MaxPool2D((2,2) , strides = 2 , padding = 'same')) |
| 117 | +model.add(Conv2D(256 , (3,3) , strides = 1 , padding = 'same' , activation = 'relu')) |
| 118 | +model.add(Dropout(0.2)) |
| 119 | +model.add(BatchNormalization()) |
| 120 | +model.add(MaxPool2D((2,2) , strides = 2 , padding = 'same')) |
| 121 | +model.add(Flatten()) |
| 122 | +model.add(Dense(units = 128 , activation = 'relu')) |
| 123 | +model.add(Dropout(0.2)) |
| 124 | +model.add(Dense(units = 1 , activation = 'sigmoid')) |
| 125 | +model.compile(optimizer = "rmsprop" , loss = 'binary_crossentropy' , metrics = ['accuracy']) |
| 126 | +model.summary() |
| 127 | + |
| 128 | +learning_rate_reduction = ReduceLROnPlateau(monitor='val_accuracy', patience = 2, verbose=1,factor=0.3, min_lr=0.000001) |
| 129 | + |
| 130 | +history = model.fit(datagen.flow(x_train,y_train, batch_size = 32) ,epochs = 12 , validation_data = datagen.flow(x_val, y_val) ,callbacks = [learning_rate_reduction]) |
| 131 | + |
| 132 | +print("Loss of the model is - " , model.evaluate(x_test,y_test)[0]) |
| 133 | +print("Accuracy of the model is - " , model.evaluate(x_test,y_test)[1]*100 , "%") |
| 134 | + |
| 135 | +epochs = [i for i in range(12)] |
| 136 | +fig , ax = plt.subplots(1,2) |
| 137 | +train_acc = history.history['accuracy'] |
| 138 | +train_loss = history.history['loss'] |
| 139 | +val_acc = history.history['val_accuracy'] |
| 140 | +val_loss = history.history['val_loss'] |
| 141 | +fig.set_size_inches(20,10) |
| 142 | + |
| 143 | +ax[0].plot(epochs , train_acc , 'go-' , label = 'Training Accuracy') |
| 144 | +ax[0].plot(epochs , val_acc , 'ro-' , label = 'Validation Accuracy') |
| 145 | +ax[0].set_title('Training & Validation Accuracy') |
| 146 | +ax[0].legend() |
| 147 | +ax[0].set_xlabel("Epochs") |
| 148 | +ax[0].set_ylabel("Accuracy") |
| 149 | + |
| 150 | +ax[1].plot(epochs , train_loss , 'g-o' , label = 'Training Loss') |
| 151 | +ax[1].plot(epochs , val_loss , 'r-o' , label = 'Validation Loss') |
| 152 | +ax[1].set_title('Testing Accuracy & Loss') |
| 153 | +ax[1].legend() |
| 154 | +ax[1].set_xlabel("Epochs") |
| 155 | +ax[1].set_ylabel("Training & Validation Loss") |
| 156 | +plt.show() |
| 157 | + |
| 158 | +predictions = model.predict(x_test) |
| 159 | +predictions = predictions.reshape(1,-1)[0] |
| 160 | +y_pred = np.where(predictions > 0.5,1,0) |
| 161 | +predictions[:15] |
| 162 | + |
| 163 | +print(classification_report(y_test, y_pred, target_names = ['Pneumonia (Class 0)','Normal (Class 1)'])) |
| 164 | + |
| 165 | +cm = confusion_matrix(y_test,y_pred) |
| 166 | +cm |
| 167 | + |
| 168 | +cm = pd.DataFrame(cm , index = ['0','1'] , columns = ['0','1']) |
| 169 | + |
| 170 | +correct = np.nonzero(predictions == y_test)[0] |
| 171 | +incorrect = np.nonzero(predictions != y_test)[0] |
| 172 | + |
| 173 | +i = 0 |
| 174 | +for c in correct[:6]: |
| 175 | + plt.subplot(3,2,i+1) |
| 176 | + plt.xticks([]) |
| 177 | + plt.yticks([]) |
| 178 | + plt.imshow(x_test[c].reshape(150,150), cmap="gray", interpolation='none') |
| 179 | + plt.title("Predicted Class {},Actual Class {}".format(predictions[c], y_test[c])) |
| 180 | + plt.tight_layout() |
| 181 | + i += 1 |
| 182 | + |
| 183 | +i = 0 |
| 184 | +for c in incorrect[:6]: |
| 185 | + plt.subplot(3,2,i+1) |
| 186 | + plt.xticks([]) |
| 187 | + plt.yticks([]) |
| 188 | + plt.imshow(x_test[c].reshape(150,150), cmap="gray", interpolation='none') |
| 189 | + plt.title("Predicted Class {},Actual Class {}".format(predictions[c], y_test[c])) |
| 190 | + plt.tight_layout() |
| 191 | + i += 1 |
0 commit comments