I am doing a binary classification problem where I have 440 images in total. I am training CNN using the "train_on_batch" function for each batch. I know for train_on_batch is used for large datasets but I am using it on a small dataset for test purposes. I am training my model (ResNet50V2) for 5 epochs with a batch size of 32 and I am receiving the same batch accuracy and same batch loss for each epoch. What could be the reason for that?
Dataset Structure:
dataset
with_mask
220 images
without_mask
220 images
File: train_on_batch.py
# importing libraries
import os
import cv2
from glob import glob
import tensorflow as tf
from tensorflow.keras.preprocessing.image import img_to_array
from tensorflow.keras.optimizers import Adam
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelBinarizer
import numpy as np
from vgg16_keras import VGG16
import warnings
warnings.filterwarnings('ignore')
def load_data():
# initialize the data and labels
data = []
labels = []
images_list = glob("E:/ai/Mask Detection/dataset/*/*.PNG")
# loop over the input images
for imagePath in images_list:
image = cv2.imread(imagePath)
#image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
image = cv2.resize(image, (224, 224))
image = img_to_array(image)
data.append(image)
label = imagePath.split(os.path.sep)[-2]
labels.append(label)
print("Data and Labels are ready to use")
data = np.array(data, dtype = "float") / 255.0
labels = np.array(labels)
return data, labels
def optimizer():
return Adam(lr = 0.001)
def create_cnn():
model = VGG16.build(224, 224, 3, 1)
model.compile(loss = "binary_crossentropy", optimizer = optimizer(), metrics = ["accuracy"])
return model
def get_batch(batch_size, trainX, trainY):
size = len(trainX)
n_batch = size // batch_size
i = 0
while(i < n_batch):
batchY = trainY[(i * n_batch):(i * n_batch + batch_size)]
batchX = trainX[(i * n_batch):(i * n_batch + batch_size)]
batchX = batchX.reshape(batch_size, 224, 224, 3)
i += 1
yield batchX, batchY
def training(epoch = 5, batch_size = 32):
data, labels = load_data()
# partition the data into training and testing with 80% data to training and 20% to testing
(trainX, testX, trainY, testY) = train_test_split(data, labels, test_size = 0.2)
# convert the labels from integers to vectors
lb = LabelBinarizer()
trainY = lb.fit_transform(trainY)
testY = lb.fit_transform(testY)
model = create_cnn()
n_epochs = epoch
for epoch in range(1, n_epochs+1):
print("=" * 100)
print("Epoch:{}/{}".format(epoch, n_epochs))
train_acc = []
for batchX, batchY in get_batch(batch_size, trainX, trainY):
loss, acc = model.train_on_batch(batchX, batchY)
print("batch accuracy: {}, batch loss: {}".format(acc, loss))
train_acc.append(acc)
print("Train accuracy", np.mean(train_acc))
training(epoch = 5, batch_size=32)
File: vgg16_keras
# importing libraries
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D
from tensorflow.keras.layers import Activation, Dense, Flatten, Dropout
from tensorflow.keras import backend as K
class VGG16:
@staticmethod
def build(width, height, depth, classes):
# initialize the model along with input shape to be "channels last" and the
# channels dimensions itself
model = Sequential()
input_shape = (height, width, depth)
if K.image_data_format() == "channels_first":
input_shape = (depth, height, width)
# Block 1: CONV => RELU => CONV => RELU => POOL layer set
model.add(Conv2D(64, (3, 3), input_shape=input_shape, padding='same'))
model.add(Activation("relu"))
model.add(Conv2D(64, (3, 3), padding='same'))
model.add(Activation("relu"))
model.add(MaxPooling2D(pool_size = (2,2), strides = (2, 2)))
# Block 2: CONV => RELU => CONV => RELU => POOL layer set
model.add(Conv2D(128, (3, 3), padding='same'))
model.add(Activation("relu"))
model.add(Conv2D(128, (3, 3), padding='same'))
model.add(Activation("relu"))
model.add(MaxPooling2D(pool_size = (2,2), strides = (2, 2)))
# Block 3: CONV => RELU => CONV => RELU => CONV => RELU => POOL layer set
model.add(Conv2D(256, (3, 3), padding='same'))
model.add(Activation("relu"))
model.add(Conv2D(256, (3, 3), padding='same'))
model.add(Activation("relu"))
model.add(Conv2D(256, (3, 3), padding='same'))
model.add(Activation("relu"))
model.add(MaxPooling2D(pool_size = (2,2), strides = (2, 2)))
# Block 4: CONV => RELU => CONV => RELU => CONV => RELU => POOL layer set
model.add(Conv2D(512, (3, 3), padding='same'))
model.add(Activation("relu"))
model.add(Conv2D(512, (3, 3), padding='same'))
model.add(Activation("relu"))
model.add(Conv2D(512, (3, 3), padding='same'))
model.add(Activation("relu"))
model.add(MaxPooling2D(pool_size = (2,2), strides = (2, 2)))
# Block 5: CONV => RELU => CONV => RELU => CONV => RELU => POOL layer set
model.add(Conv2D(512, (3, 3), padding='same'))
model.add(Activation("relu"))
model.add(Conv2D(512, (3, 3), padding='same'))
model.add(Activation("relu"))
model.add(Conv2D(512, (3, 3), padding='same'))
model.add(Activation("relu"))
model.add(MaxPooling2D(pool_size = (2,2), strides = (2, 2)))
# Block 6: first set of FC => RELU layers
model.add(Flatten())
model.add(Dense(4096))
model.add(Activation("relu"))
model.add(Dropout(0.5))
# Block 7: second set of FC => RELU layers
model.add(Dense(4096))
model.add(Activation("relu"))
model.add(Dropout(0.5))
# Softmax classifier
model.add(Dense(classes))
model.add(Activation("softmax"))
return model
output:
Epoch:1/5
batch accuracy: 0.5625, batch loss: 6.708292007446289
batch accuracy: 0.40625, batch loss: 9.104110717773438
batch accuracy: 0.40625, batch loss: 9.104110717773438
batch accuracy: 0.375, batch loss: 9.583274841308594
batch accuracy: 0.375, batch loss: 9.583274841308594
batch accuracy: 0.3125, batch loss: 10.54160213470459
batch accuracy: 0.34375, batch loss: 10.06243896484375
batch accuracy: 0.4375, batch loss: 8.624947547912598
batch accuracy: 0.53125, batch loss: 7.187456130981445
batch accuracy: 0.625, batch loss: 5.749964714050293
batch accuracy: 0.625, batch loss: 5.749964714050293
====================================================================================================
Epoch:2/5
batch accuracy: 0.5625, batch loss: 6.708292007446289
batch accuracy: 0.40625, batch loss: 9.104110717773438
batch accuracy: 0.40625, batch loss: 9.104110717773438
batch accuracy: 0.375, batch loss: 9.583274841308594
batch accuracy: 0.375, batch loss: 9.583274841308594
batch accuracy: 0.3125, batch loss: 10.54160213470459
batch accuracy: 0.34375, batch loss: 10.06243896484375
batch accuracy: 0.4375, batch loss: 8.624947547912598
batch accuracy: 0.53125, batch loss: 7.187456130981445
batch accuracy: 0.625, batch loss: 5.749964714050293
batch accuracy: 0.625, batch loss: 5.749964714050293
====================================================================================================
Epoch:3/5
batch accuracy: 0.5625, batch loss: 6.708292007446289
batch accuracy: 0.40625, batch loss: 9.104110717773438
batch accuracy: 0.40625, batch loss: 9.104110717773438
batch accuracy: 0.375, batch loss: 9.583274841308594
batch accuracy: 0.375, batch loss: 9.583274841308594
batch accuracy: 0.3125, batch loss: 10.54160213470459
batch accuracy: 0.34375, batch loss: 10.06243896484375
batch accuracy: 0.4375, batch loss: 8.624947547912598
batch accuracy: 0.53125, batch loss: 7.187456130981445
batch accuracy: 0.625, batch loss: 5.749964714050293
batch accuracy: 0.625, batch loss: 5.749964714050293
====================================================================================================
Epoch:4/5
batch accuracy: 0.5625, batch loss: 6.708292007446289
batch accuracy: 0.40625, batch loss: 9.104110717773438
batch accuracy: 0.40625, batch loss: 9.104110717773438
batch accuracy: 0.375, batch loss: 9.583274841308594
batch accuracy: 0.375, batch loss: 9.583274841308594
batch accuracy: 0.3125, batch loss: 10.54160213470459
batch accuracy: 0.34375, batch loss: 10.06243896484375
batch accuracy: 0.4375, batch loss: 8.624947547912598
batch accuracy: 0.53125, batch loss: 7.187456130981445
batch accuracy: 0.625, batch loss: 5.749964714050293
batch accuracy: 0.625, batch loss: 5.749964714050293
====================================================================================================
Epoch:5/5
batch accuracy: 0.5625, batch loss: 6.708292007446289
batch accuracy: 0.40625, batch loss: 9.104110717773438
batch accuracy: 0.40625, batch loss: 9.104110717773438
batch accuracy: 0.375, batch loss: 9.583274841308594
batch accuracy: 0.375, batch loss: 9.583274841308594
batch accuracy: 0.3125, batch loss: 10.54160213470459
batch accuracy: 0.34375, batch loss: 10.06243896484375
batch accuracy: 0.4375, batch loss: 8.624947547912598
batch accuracy: 0.53125, batch loss: 7.187456130981445
batch accuracy: 0.625, batch loss: 5.749964714050293
batch accuracy: 0.625, batch loss: 5.749964714050293
Train accuracy 0.625
If I change the learning rate after each epoch It will still give me the same result. I am using TensorFlow version 1.14
I need to train the classification model using train_on_batch on custom batches. If you can refer to some examples doing the same.
I hope it is not too late. I think when you add
acc
to the vectortrain_acc
is not inside the 'for'.