[Python] CNN predicting the same class everytime

Discussão em 'Python' iniciado por Stack, Agosto 31, 2025.

  1. Stack

    Stack Membro Participativo

    I have tried building a CNN from scratch and testing it one the plant village datatset, it has 96% accuracy and 93% validation accuracy but when i try testing it with the testing images its always prediciting the same class... but then again it evaluates correctly if i use the validation set.

    I am using the Plant Village dataset, this is how im preprocessing the data

    trainDf = tf.keras.preprocessing.image_dataset_from_directory(
    trainDir,
    image_size=(64, 64),
    batch_size=8,
    shuffle=True,
    labels="inferred"
    )

    valDf = tf.keras.preprocessing.image_dataset_from_directory(
    valDir,
    image_size=(64, 64),
    batch_size=8,
    shuffle=False,
    labels="inferred"
    )


    augmentation:


    rescale_and_resize = tf.keras.Sequential([
    layers.Resizing(64, 64),
    layers.Rescaling(1./255)
    ])

    data_augmentation = tf.keras.Sequential([
    layers.RandomFlip("horizontal_and_vertical"),
    layers.RandomRotation(0.1),
    layers.RandomZoom(0.1),
    layers.RandomTranslation(0.1, 0.1),
    layers.RandomContrast(0.1),
    ])


    model:

    #Model
    model = models.Sequential([
    rescale_and_resize,
    data_augmentation,

    layers.Conv2D(32, 3, activation='relu', padding='same'),
    layers.BatchNormalization(),
    layers.MaxPooling2D(),

    layers.Conv2D(64, 3, activation='relu', padding='same'),
    layers.BatchNormalization(),
    layers.MaxPooling2D(),

    layers.Conv2D(128, 3, activation='relu', padding='same'),
    layers.BatchNormalization(),
    layers.MaxPooling2D(),

    layers.Conv2D(128, 3, activation='relu', padding='same'),
    layers.BatchNormalization(),
    layers.MaxPooling2D(),

    layers.Conv2D(256, 3, activation='relu', padding='same'),
    layers.BatchNormalization(),
    layers.MaxPooling2D(),

    layers.Flatten(),
    layers.Dropout(0.5),
    layers.Dense(38)
    ])

    model.compile(
    optimizer=tf.keras.optimizers.Adam(1e-4),
    loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
    metrics=['accuracy']
    )

    model.summary()

    stop_early = tf.keras.callbacks.EarlyStopping(
    monitor='val_loss',
    patience=5,
    restore_best_weights=True
    )

    #Training the model

    history = model.fit(
    trainDf,
    validation_data=valDf,
    epochs=50,
    callbacks=[stop_early]
    )

    model.save("model1.keras")


    model summary after training:

    ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
    ┃ Layer (type) ┃ Output Shape ┃ Param # ┃
    ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
    │ sequential (Sequential) │ (None, 64, 64, 3) │ 0 │
    ├─────────────────────────────────┼────────────────────────┼───────────────┤
    │ sequential_1 (Sequential) │ (None, 64, 64, 3) │ 0 │
    ├─────────────────────────────────┼────────────────────────┼───────────────┤
    │ conv2d (Conv2D) │ (None, 64, 64, 32) │ 896 │
    ├─────────────────────────────────┼────────────────────────┼───────────────┤
    │ batch_normalization │ (None, 64, 64, 32) │ 128 │
    │ (BatchNormalization) │ │ │
    ├─────────────────────────────────┼────────────────────────┼───────────────┤
    │ max_pooling2d (MaxPooling2D) │ (None, 32, 32, 32) │ 0 │
    ├─────────────────────────────────┼────────────────────────┼───────────────┤
    │ conv2d_1 (Conv2D) │ (None, 32, 32, 64) │ 18,496 │
    ├─────────────────────────────────┼────────────────────────┼───────────────┤
    │ batch_normalization_1 │ (None, 32, 32, 64) │ 256 │
    │ (BatchNormalization) │ │ │
    ├─────────────────────────────────┼────────────────────────┼───────────────┤
    │ max_pooling2d_1 (MaxPooling2D) │ (None, 16, 16, 64) │ 0 │
    ├─────────────────────────────────┼────────────────────────┼───────────────┤
    │ conv2d_2 (Conv2D) │ (None, 16, 16, 128) │ 73,856 │
    ├─────────────────────────────────┼────────────────────────┼───────────────┤
    │ batch_normalization_2 │ (None, 16, 16, 128) │ 512 │
    │ (BatchNormalization) │ │ │
    ├─────────────────────────────────┼────────────────────────┼───────────────┤
    │ max_pooling2d_2 (MaxPooling2D) │ (None, 8, 8, 128) │ 0 │
    ├─────────────────────────────────┼────────────────────────┼───────────────┤
    │ conv2d_3 (Conv2D) │ (None, 8, 8, 128) │ 147,584 │
    ├─────────────────────────────────┼────────────────────────┼───────────────┤
    │ batch_normalization_3 │ (None, 8, 8, 128) │ 512 │
    │ (BatchNormalization) │ │ │
    ├─────────────────────────────────┼────────────────────────┼───────────────┤
    │ max_pooling2d_3 (MaxPooling2D) │ (None, 4, 4, 128) │ 0 │
    ├─────────────────────────────────┼────────────────────────┼───────────────┤
    │ conv2d_4 (Conv2D) │ (None, 4, 4, 256) │ 295,168 │
    ├─────────────────────────────────┼────────────────────────┼───────────────┤
    │ batch_normalization_4 │ (None, 4, 4, 256) │ 1,024 │
    │ (BatchNormalization) │ │ │
    ├─────────────────────────────────┼────────────────────────┼───────────────┤
    │ max_pooling2d_4 (MaxPooling2D) │ (None, 2, 2, 256) │ 0 │
    ├─────────────────────────────────┼────────────────────────┼───────────────┤
    │ flatten (Flatten) │ (None, 1024) │ 0 │
    ├─────────────────────────────────┼────────────────────────┼───────────────┤
    │ dropout (Dropout) │ (None, 1024) │ 0 │
    ├─────────────────────────────────┼────────────────────────┼───────────────┤
    │ dense (Dense) │ (None, 38) │ 38,950 │
    └─────────────────────────────────┴────────────────────────┴───────────────┘


    the training stopped around here:

    Epoch 24/50 8787/8787 ━━━━━━━━━━━━━━━━━━━━ 630s 72ms/step - accuracy: 0.9667 - loss: 0.0985 - val_accuracy: 0.9380 - val_loss: 0.1975

    this is how im testing the data:

    model = keras.models.load_model("model1.keras")

    imgs=[os.path.join(testDir,fpath) for fpath in os.listdir(testDir)]
    images=[]
    for path in imgs:
    img = image.load_img(path,target_size=(64,64))
    arr=image.img_to_array(img)
    arr=arr/255.0
    images.append(arr)

    images=np.array(images)

    pred=model.predict(images)
    p=np.argmax(pred,axis=1)
    print(p)


    but the output is:

    2/2 ━━━━━━━━━━━━━━━━━━━━ 0s 168ms/step [8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8]

    its always predicting the same class even if i try it individual images.. why is that so?

    Continue reading...

Compartilhe esta Página