1
$\begingroup$

I am doing a project in plant pest detection using CNN. There are four classes each having about 1000 images.I have use alexnet architecture for training. I think confusion matrix is not correct. What you have to say?

You can find the code in more detail alexnetmodel alexnetevaluate

EPOCHS = 20
INIT_LR = 1e-5
BS = 8
default_image_size = tuple((256, 256))
image_size = 0
directory_root = '../input/plantvillag/'
width=256
height=256
depth=3

Function to convert images to array

  def convert_image_to_array(image_dir):
        try:
            image = cv2.imread(image_dir)
            if image is not None :
                image = cv2.resize(image, default_image_size)   
                return img_to_array(image)
            else :
                return np.array([])
        except Exception as e:
            print(f"Error : {e}")
            return None

Fetch images from directory

image_list, label_list = [], []
    try:
        print("[INFO] Loading images ...")
        root_dir = listdir(directory_root)
        for directory in root_dir :
            # remove .DS_Store from list
            if directory == ".DS_Store" :
                root_dir.remove(directory)

    for plant_folder in root_dir :
        plant_disease_folder_list = listdir(f"{directory_root}/{plant_folder}")

        for disease_folder in plant_disease_folder_list :
            # remove .DS_Store from list
            if disease_folder == ".DS_Store" :
                plant_disease_folder_list.remove(disease_folder)

        for plant_disease_folder in plant_disease_folder_list:
            print(f"[INFO] Processing {plant_disease_folder} ...")
            plant_disease_image_list = listdir(f"{directory_root}/{plant_folder}/{plant_disease_folder}/")

            for single_plant_disease_image in plant_disease_image_list :
                if single_plant_disease_image == ".DS_Store" :
                    plant_disease_image_list.remove(single_plant_disease_image)

            for image in plant_disease_image_list[:1000]:
                image_directory = f"{directory_root}/{plant_folder}/{plant_disease_folder}/{image}"
                if image_directory.endswith(".jpg") == True or image_directory.endswith(".JPG") == True:
                    image_list.append(convert_image_to_array(image_directory))
                    label_list.append(plant_disease_folder)
    print("[INFO] Image loading completed")  
except Exception as e:
    print(f"Error : {e}")

Get Size of Processed Image

image_size = len(image_list)

Transform Image Labels uisng Scikit Learn's LabelBinarizer

    label_binarizer = LabelBinarizer()
image_labels = label_binarizer.fit_transform(label_list)
pickle.dump(label_binarizer,open('label_transform.pkl', 'wb'))
n_classes = len(label_binarizer.classes_)

    np_image_list = np.array(image_list, dtype=np.float32) / 255.0

Splitting data

print("[INFO] Spliting data to train, test")

x_train, x_test, y_train, y_test = 
train_test_split(np_image_list,image_labels, test_size=0.2, random_state = 42) 



aug = ImageDataGenerator(
    rotation_range=25, width_shift_range=0.1,
    height_shift_range=0.1, shear_range=0.2, 
    zoom_range=0.2,horizontal_flip=True, 
    fill_mode="nearest")

Model Build

from keras import layers
from keras.models import Model

optss = Adam(lr=INIT_LR, decay=INIT_LR / EPOCHS)
def alexnet(in_shape=(256,256,3), n_classes=n_classes, opt=optss):
    in_layer = layers.Input(in_shape)
    conv1 = layers.Conv2D(96, 11, strides=4, activation='relu')(in_layer)
    pool1 = layers.MaxPool2D(3, 2)(conv1)
    conv2 = layers.Conv2D(256, 5, strides=1, padding='same', activation='relu')(pool1)
    pool2 = layers.MaxPool2D(3, 2)(conv2)
    conv3 = layers.Conv2D(384, 3, strides=1, padding='same', activation='relu')(pool2)
    conv4 = layers.Conv2D(256, 3, strides=1, padding='same', activation='relu')(conv3)
    pool3 = layers.MaxPool2D(3, 2)(conv4)
    flattened = layers.Flatten()(pool3)
    dense1 = layers.Dense(4096, activation='relu')(flattened)
    drop1 = layers.Dropout(0.8)(dense1)
    dense2 = layers.Dense(4096, activation='relu')(drop1)
    drop2 = layers.Dropout(0.8)(dense2)
    preds = layers.Dense(n_classes, activation='softmax')(drop2)

    model = Model(in_layer, preds)
    model.compile(loss="categorical_crossentropy", optimizer=opt,metrics=["accuracy"])
    return model


    model = alexnet()

Performing Training

    history = model.fit_generator(
    aug.flow(x_train, y_train, batch_size=BS),
    validation_data=(x_test, y_test),
    steps_per_epoch=len(x_train) // BS,
    epochs=EPOCHS, verbose=1
    )

Graphs

acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs = range(1, len(acc) + 1)
#Train and validation accuracy
plt.plot(epochs, acc, 'b', label='Training accurarcy')
plt.plot(epochs, val_acc, 'r', label='Validation accurarcy')
plt.title('Training and Validation accurarcy')
plt.legend()

plt.figure()
#Train and validation loss
plt.plot(epochs, loss, 'b', label='Training loss')
plt.plot(epochs, val_loss, 'r', label='Validation loss')
plt.title('Training and Validation loss')
plt.legend()
plt.show()

enter image description here enter image description here

scores = model.evaluate(x_test, y_test)
print(f"Test Accuracy: {scores[1]*100}")

Test Accuracy: 85.75

Making Predictions

y_pred = model.predict(x_test)

#getting labels
y_pred_labels = np.argmax(y_pred,axis = 1)
y_true = np.argmax(y_test,axis = 1)

Making confusion matrix

#Creating a confusion matrix
from sklearn.metrics import confusion_matrix

cm = confusion_matrix(y_true,y_pred_labels)

Visualizing Confusion matrix

import pandas as pd
import seaborn as sns

from sklearn.metrics import accuracy_score, confusion_matrix, precision_recall_fscore_support

#Transform to df for easier plotting
cm_df = pd.DataFrame(cm, index = ['Tomato_Bacterial_spot','Tomato_Late_blight','Tomato_Septoria_leaf_spot',
 'Tomato_healthy'],
                     columns = ['Tomato_Bacterial_spot','Tomato_Late_blight','Tomato_Septoria_leaf_spot',
 'Tomato_healthy'])

plt.figure(figsize = (6,6))
sns.heatmap(cm_df, annot = True)
plt.title('CNN PlantPest Classify')
plt.ylabel('True Label')
plt.xlabel('Prediction label')
plt.show()

enter image description here

$\endgroup$
  • 2
    $\begingroup$ It seems like you have the number of samples in each cell. I'd recommend the accuracy. After a quick look, I don't see the issue otherwise? $\endgroup$ – Carl Rynegardh May 12 at 12:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.