<jupyter_start><jupyter_text>Classifying White Blood Cells  IntroductionAn important problem in blood diagnostics is classifying different types of blood cells. In this notebook, we will attempt to train a classifier to predict the type of a blood cell given a dyed picture of it. DataWe have 351 pictures of dyed white blood cells along with labels of what type of blood cell they are. Below is an example of each of the types of blood cells in our dataset. Basophil![Basophil](Basophil.jpg) Eosinophil![Eosinophil](Eosinophil.jpg) Lymphocyte![Lymphocyte](Lymphocyte.jpg) Monocyte![Monocyte](Monocyte.jpg) Neutrophil![Neutrophil](Neutrophil.jpg) MethodologyWe use a simple LeNet architecture trained on 280 training samples with image augmentation. Our augmentation techniques include rotations, shifts, and zooms.We validate our results against 70 samples. ResultsWe obtain an accuracy of 93% on this validation set with the following confusion matrix:![Confusion Matrix](confusion_matrix.png) ConclusionI think these results show that it is possible to train a strong classifier for WBCs that can approach really strong accuracies with more and more data. Next StepsIt's hard to try and improve the results with so little validation data. Fixing one prediction here or there would lead to a big change in accuracy etc. The next steps should be to augment our training and test sets with further image augmentation techniques or just more real data.Here are some potential techniques to improve accuracy:* Use color thresholding to find the center of each WBC and crop the images to be centered around those areas.* Use VGG net etc. and retrain the last few layers.* Balance out the dataset through image augmentation.  Code<jupyter_code>import numpy as np
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Conv2D, MaxPooling2D, Lambda
from keras.layers import Dense
from keras.wrappers.scikit_learn import KerasClassifier
from keras.utils import np_utils
from keras.preprocessing.image import ImageDataGenerator
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import KFold
from sklearn.preprocessing import LabelEncoder
from sklearn.pipeline import Pipeline
from sklearn.cross_validation import train_test_split
from sklearn.metrics import roc_curve, auc
import csv
import cv2
import scipy

num_classes = 5
epochs = 20
# BASE_PATH = '/home/ec2-user/cell_classifier/'
BASE_PATH = '../'
batch_size = 32
def get_model():
    model = Sequential()
    model.add(Lambda(lambda x: x/127.5 - 1., input_shape=(120, 160, 3), output_shape=(120, 160, 3)))
    model.add(Conv2D(32, (3, 3), input_shape=(120, 160, 3)))
    model.add(Activation('relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))

    model.add(Conv2D(32, (3, 3)))
    model.add(Activation('relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))

    model.add(Conv2D(64, (3, 3)))
    model.add(Activation('relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))

    model.add(Flatten())  # this converts our 3D feature maps to 1D feature vectors
    model.add(Dense(64))
    model.add(Activation('relu'))
    model.add(Dropout(0.5))
    model.add(Dense(num_classes))
    model.add(Activation('softmax'))

    model.compile(loss='categorical_crossentropy',
                optimizer='rmsprop',
                metrics=['accuracy'])

    return model
def get_filename_for_index(index):
    PREFIX = 'images/BloodImage_'
    num_zeros = 5 - len(index)
    path = '0' * num_zeros + index
    return PREFIX + path + '.jpg'
reader = csv.reader(open(BASE_PATH + 'labels.csv'))
# skip the header
next(reader)

X = []
y = []

for row in reader:
    label = row[2]
    if len(label) > 0 and label.find(',') == -1:
        filename = get_filename_for_index(row[1])
        img_file = cv2.imread(BASE_PATH + filename)
        if img_file is not None:
            img_file = scipy.misc.imresize(arr=img_file, size=(120, 160, 3))
            img_arr = np.asarray(img_file)
            img_arr = apply_color_mask(img_arr)
            X.append(img_arr)
            y.append(label)


X = np.asarray(X)
y = np.asarray(y)

encoder = LabelEncoder()
encoder.fit(y)
encoded_y = encoder.transform(y)

y = np_utils.to_categorical(encoded_y)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=10)
datagen = ImageDataGenerator(
    rotation_range=20,
    width_shift_range=0.2,
    height_shift_range=0.2,
    horizontal_flip=True)
train_generator = datagen.flow(
        X_train,
        y_train,
        batch_size=batch_size)

validation_generator = datagen.flow(
        X_test,
        y_test,
        batch_size=batch_size)
model = get_model()

# fits the model on batches with real-time data augmentation:
model.fit_generator(
    train_generator,
    steps_per_epoch=len(X_train),
    validation_data=validation_generator,
    validation_steps=len(X_test),
    epochs=epochs)
model.save_weights('mask_1.h5')  # always save your weights after training or during training<jupyter_output>Epoch 1/20
133/280 [=============>................] - ETA: 192s - loss: 1.2470 - acc: 0.5345[...]<jupyter_text>Load Model<jupyter_code>model = get_model()
model.load_weights('first_try.h5')<jupyter_output><empty_output><jupyter_text>Accuracy<jupyter_code>print('Predicting on test data')
y_pred = np.rint(model.predict(X_test))
from sklearn.metrics import accuracy_score

print(accuracy_score(y_test, y_pred))<jupyter_output>0.929577464789<jupyter_text>Confusion Matrix<jupyter_code>from sklearn.metrics import confusion_matrix

y_pred_unencoded = np.argmax(y_pred, axis=1)
y_test_unencoded = np.argmax(y_test, axis=1)

print(confusion_matrix(y_test_unencoded, y_pred_unencoded))
encoder.inverse_transform([0, 1, 2, 3, 4])<jupyter_output><empty_output><jupyter_text>Eosinophils<jupyter_code>eosinophils = np.where(y_pred[:,1] == 1)
eosinophils
print("IS CORRECT?", np.array_equal(y_test[11],y_pred[11]))
print(y_test[11])
print(y_pred[11])
imshow(X_test[11])
print("IS CORRECT?", np.array_equal(y_test[11],y_pred[11]))
print(y_test[15])
print(y_pred[15])
imshow(X_test[15])
print("IS CORRECT?", np.array_equal(y_test[11],y_pred[11]))
print(y_test[16])
print(y_pred[16])
imshow(X_test[16])
print("IS CORRECT?", np.array_equal(y_test[11],y_pred[11]))
print(y_test[11])
print(y_pred[11])
imshow(X_test[11])<jupyter_output>IS CORRECT? True
[ 0.  1.  0.  0.  0.]
[ 0.  1.  0.  0.  0.]<jupyter_text>Lymphocytes<jupyter_code>lymphocytes = np.where(y_pred[:,2] == 1)
print(lymphocytes)
print("IS CORRECT?", np.array_equal(y_test[22],y_pred[22]))
print(y_test[22])
print(y_pred[22])
imshow(X_test[22])
print("IS CORRECT?", np.array_equal(y_test[22],y_pred[22]))
print(y_test[32])
print(y_pred[32])
imshow(X_test[32])
print("IS CORRECT?", np.array_equal(y_test[22],y_pred[22]))
print(y_test[60])
print(y_pred[60])
imshow(X_test[60])<jupyter_output>IS CORRECT? True
[ 0.  0.  1.  0.  0.]
[ 0.  0.  1.  0.  0.]<jupyter_text>Monocytes<jupyter_code>monocytes = np.where(y_pred[:,3] == 1)
print(monocytes)
print("IS CORRECT?", np.array_equal(y_test[6],y_pred[6]))
print(y_test[6])
print(y_pred[6])
imshow(X_test[6])
print("IS CORRECT?", np.array_equal(y_test[28],y_pred[28]))
print(y_test[28])
print(y_pred[28])
imshow(X_test[28])<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.21893635146647195, 'fraction_numerical': 0.031033223804308143, 'mean_word_length': 5.9233361415332775, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '597933', 'license': 'Apache-2.0', 'n_tokens_mistral': 3664, 'n_tokens_neox': 3442, 'n_words': 625, 'path': 'training.ipynb', 'repo_name': 'BIJIRAVI/WBC_Segmentaion', 'size': '8217'}