Related
I'm trying to build a Siamese Neural Network to analyze the MNIST dataset, however when trying to fit the model to the dataset I encounter this problem according to which I have training data and labels shapes' mismatch. I tried changing the loss function as well as tried to squeeze the labels array, and neither of "solutions" worked.
Here are the train and labels arrays' shapes:
pairTrain shape: (120000, 2, 28, 28, 1)
labelTrain shape: (120000, 1)
Here's my model:
def build_model(input_shape, embedDim=48):
inputs = Input(input_shape)
x = Conv2D(64, (2, 2), padding="same", activation="relu", input_shape=input_shape)(inputs)
x = MaxPooling2D()(x)
x = Dropout(0.3)(x)
x = Conv2D(32, (2, 2), padding="same", activation="relu")(x)
x = MaxPooling2D()(x)
x = Dropout(0.3)(x)
x = Conv2D(16, (2, 2), padding="same", activation="relu")(x)
x = MaxPooling2D()(x)
x = Dropout(0.3)(x)
outputs = Flatten()(x)
outputs = Dense(embedDim)(outputs)
model = Model(inputs, outputs)
return model
And finally here's the code that generates the error itself:
imgA = Input(shape=(28, 28, 1))
imgB = Input(shape=(28, 28, 1))
featA = build_model((28, 28, 1))(imgA)
featB = build_model((28, 28, 1))(imgB)
distance = Lambda(euclidean_distance)([featA, featB])
output = Dense(1, activation="sigmoid")(distance)
model = Model([imgA, imgB], output)
model.compile(optimizer="adam", loss="categorical_crossentropy", metrics=["accuracy"])
history = model.fit(
[pairTrain[:, 0], pairTrain[:, 1]], labelTrain,
validation_data=[[pairTest[:, 0], pairTest[:, 1]], labelTest],
batch_size=64,
epochs=10
)
model.save("output/siamese_model")
Please help me to resolve the problem.
I was not able to reproduce the error using the below code. I suspect that your labels shape is different than the one you reported or it does not contain strictly binary data (0s and 1s) only.
Also, you should use tf.keras.losses.BinaryCrossentropy instead of tf.keras.losses.CategoricalCrossentropy as your labels should be binary with the sigmoid activation in the last layer.
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Dropout, Input, Flatten, Dense, Lambda
from tensorflow.keras.models import Model
import tensorflow as tf
def build_model(input_shape, embedDim=48):
inputs = Input(input_shape)
x = Conv2D(64, (2, 2), padding="same", activation="relu", input_shape=input_shape)(inputs)
x = MaxPooling2D()(x)
x = Dropout(0.3)(x)
x = Conv2D(32, (2, 2), padding="same", activation="relu")(x)
x = MaxPooling2D()(x)
x = Dropout(0.3)(x)
x = Conv2D(16, (2, 2), padding="same", activation="relu")(x)
x = MaxPooling2D()(x)
x = Dropout(0.3)(x)
outputs = Flatten()(x)
outputs = Dense(embedDim)(outputs)
model = Model(inputs, outputs)
return model
imgA = Input(shape=(28, 28, 1))
imgB = Input(shape=(28, 28, 1))
featA = build_model((28, 28, 1))(imgA)
featB = build_model((28, 28, 1))(imgB)
distance = Lambda(lambda x: x[0]-x[1])([featA, featB])
output = Dense(1, activation="sigmoid")(distance)
model = Model([imgA, imgB], output)
pairTrain = tf.random.uniform((10, 2, 28, 28, 1))
labelTrain = tf.random.uniform(shape=(10, 1), minval=0, maxval=2, dtype=tf.int32)
pairTest = tf.random.uniform((10, 2, 28, 28, 1))
labelTest = tf.random.uniform(shape=(10, 1), minval=0, maxval=2, dtype=tf.int32)
model.compile(optimizer="adam", loss="sparse_categorical_crossentropy", metrics=["accuracy"])
history = model.fit(
[pairTrain[:, 0], pairTrain[:, 1]], labelTrain,
validation_data=[[pairTest[:, 0], pairTest[:, 1]], labelTest],
batch_size=64,
epochs=10
)
model.save("output/siamese_model")
Epoch 1/10
1/1 [==============================] - 2s 2s/step - loss: 0.7061 - accuracy: 0.5000 - val_loss: 0.6862 - val_accuracy: 0.7000
Epoch 2/10
1/1 [==============================] - 0s 80ms/step - loss: 0.7882 - accuracy: 0.4000 - val_loss: 0.6751 - val_accuracy: 0.6000
Epoch 3/10
1/1 [==============================] - 0s 81ms/step - loss: 0.6358 - accuracy: 0.5000 - val_loss: 0.6755 - val_accuracy: 0.6000
Epoch 4/10
1/1 [==============================] - 0s 79ms/step - loss: 0.7027 - accuracy: 0.5000 - val_loss: 0.6759 - val_accuracy: 0.6000
Epoch 5/10
1/1 [==============================] - 0s 82ms/step - loss: 0.6970 - accuracy: 0.4000 - val_loss: 0.6752 - val_accuracy: 0.6000
Epoch 6/10
1/1 [==============================] - 0s 83ms/step - loss: 0.7564 - accuracy: 0.4000 - val_loss: 0.6779 - val_accuracy: 0.6000
Epoch 7/10
1/1 [==============================] - 0s 73ms/step - loss: 0.7123 - accuracy: 0.6000 - val_loss: 0.6818 - val_accuracy: 0.6000
Good morning everyone, I want to ask in this group, I have built a mode from my learning results but I'm having problems in the training section, when I try to train my model it produces los with nonsensical values and val_los which doesn't make sense but on acuracy produces a normal value. this happened when I added a class, in the first experiment with two classes, I managed to do it with 95% accuracy and 93% validation accuracy but after I added 2 classes I received results that didn't make sense, as for some solutions I tried but didn't help me, I've tried to use softmax and categorical_crosscetropy but that doesn't work. when i try to add num_class on dense screen part i get "ValueError: logits and labels must have the same shape ((None, 3) vs (None, 1))". Hope someone can help me . thank you. Here I attach my code
Load Datashet
training_dir = r"Dataset/train/"
validation_dir = r"Dataset/val/"
testing_dir = r"Dataset/test/"
categories = ['class_A', 'class_B', 'class_C', 'class_D']
Created Data Training
img_size = (128,128)
training_data = []
validation_data = []
testing_data = []
def create_training_data():
for category in categories:
path = os.path.join(training_dir,category)
class_num = categories.index(category)
for img in os.listdir(path):
try:
img_array = cv2.imread(os.path.join(path,img))
new_array = cv2.resize(img_array,img_size)
training_data.append([new_array,class_num])
except Exception as e:
pass
def create_validation_data():
for category in categories:
path = os.path.join(validation_dir,category)
class_num = categories.index(category)
for img in os.listdir(path):
try:
img_array = cv2.imread(os.path.join(path,img))
new_array = cv2.resize(img_array,img_size)
validation_data.append([new_array,class_num])
except Exception as e:
pass
def create_testing_data():
for category in categories:
path = os.path.join(testing_dir,category)
class_num = categories.index(category)
for img in os.listdir(path):
try:
img_array = cv2.imread(os.path.join(path,img))
new_array = cv2.resize(img_array,img_size)
testing_data.append([new_array,class_num])
except Exception as e:
pass
create_training_data()
Normalization of data to range 0-1 and labeling data
X_train = []
Y_train = []
for features,label in training_data:
X_train.append(features)
Y_train.append(label)
X_train = np.array(X_train).reshape(-1,128,128)
X_train = X_train.astype('float32')/255.0
X_train = X_train.reshape(-1,128,128,3)
print(X_train.shape)
X_val = []
Y_val = []
for features,label in validation_data:
X_val.append(features)
Y_val.append(label)
X_val = np.array(X_val).reshape(-1,128,128)
X_val = X_val.astype('float32')/255.0
X_val = X_val.reshape(-1,128,128,3)
print(X_val.shape)
X_test = []
Y_test = []
for features,label in testing_data:
X_test.append(features)
Y_test.append(label)
X_test = np.array(X_test).reshape(-1,128,128)
X_test = X_test.astype('float32')/255.0
X_test = X_test.reshape(-1,128,128,3)
print(X_test.shape)
Labeling Data using label encoder for Y_train/val/test
lb = LabelEncoder()
Y_train = lb.fit_transform(Y_train)
Y_val = lb.fit_transform(Y_val)
Y_test = lb.fit_transform(Y_test)
ImageDataGenerator
datagen = ImageDataGenerator(
rotation_range = 30,
zoom_range = 0.1,
width_shift_range=0.1,
height_shift_range=0.1,
horizontal_flip=True,
vertical_flip=False)
hyperparameter Tuning
HP_APL_DROPOUT = hp.HParam('dropout_apl', hp.RealInterval(0.05, 0.1))
HP_NUM_UNITS = hp.HParam('num_units', hp.Discrete([64, 128]))
HP_DROPOUT = hp.HParam('dropout', hp.RealInterval(0.25, 0.5))
HP_OPTIMIZER = hp.HParam('optimizer', hp.Discrete(['adam', 'sgd', 'adamax']))
METRIC_ACCURACY = 'accuracy'
with tf.summary.create_file_writer('logs/hparam_tuning').as_default():
hp.hparams_config(
hparams=[HP_APL_DROPOUT, HP_NUM_UNITS, HP_DROPOUT, HP_OPTIMIZER],
metrics=[hp.Metric(METRIC_ACCURACY, display_name='Accuracy')],
)
Define Traini Model
def train_test_model(hparams):
model = Sequential([
Input(shape=(128,128,3)),
Conv2D(filters=32, kernel_size=3, strides=1, padding='same', activation='swish'),
BatchNormalization(),
MaxPooling2D(pool_size = (2,2)),
Conv2D(filters=64, kernel_size=3, strides=1, padding='same', activation='swish'),
BatchNormalization(),
Conv2D(filters=64, kernel_size=3, strides=1, padding='same', activation='swish'),
MaxPooling2D(pool_size = (2,2)),
Dropout(hparams[HP_APL_DROPOUT]),
Conv2D(filters=128, kernel_size=3, strides=1, padding='same', activation='swish'),
BatchNormalization(),
MaxPooling2D(pool_size = (2,2)),
Conv2D(filters=128, kernel_size=3, strides=1, padding='same', activation='swish'),
BatchNormalization(),
MaxPooling2D(pool_size = (2,2)),
Dropout(hparams[HP_APL_DROPOUT]),
Conv2D(filters=256, kernel_size=3, strides=1, padding='same', activation='swish'),
BatchNormalization(),
MaxPooling2D(pool_size = (2,2)),
Dropout(0.05),
Conv2D(filters=256, kernel_size=3, strides=1, padding='same', activation='swish'),
BatchNormalization(),
MaxPooling2D(pool_size = (2,2)),
Dropout(hparams[HP_APL_DROPOUT]),
GlobalMaxPool2D(),
Flatten(),
Dense(hparams[HP_NUM_UNITS], activation="swish"),
Dense(128, activation = 'swish'),
Dropout(hparams[HP_DROPOUT]),
Dense(1, activation='sigmoid')
]
)
model.compile(
optimizer=hparams[HP_OPTIMIZER],
loss='binary_crossentropy',
metrics=['accuracy'],
)
datagen.fit(X_train)
history = model.fit_generator(
datagen.flow(X_train,Y_train, batch_size=batch_size),
epochs = 5,
validation_data = datagen.flow(X_val,Y_val))
_, accuracy = model.evaluate(X_val, Y_val)
return accuracy
Running Model
def run(run_dir, hparams):
with tf.summary.create_file_writer(run_dir).as_default():
hp.hparams(hparams)
accuracy = train_test_model(hparams)
tf.summary.scalar(METRIC_ACCURACY, accuracy, step=50)
session_num = 0
for dropout_apl_rate in (HP_APL_DROPOUT.domain.min_value, HP_APL_DROPOUT.domain.max_value):
for num_units in HP_NUM_UNITS.domain.values:
for dropout_rate in (HP_DROPOUT.domain.min_value, HP_DROPOUT.domain.max_value):
for optimizer in HP_OPTIMIZER.domain.values:
hparams = {
HP_APL_DROPOUT: dropout_apl_rate,
HP_NUM_UNITS: num_units,
HP_DROPOUT: dropout_rate,
HP_OPTIMIZER: optimizer,
}
run_name = "run-%d" % session_num
print('--- Starting trial: %s' % run_name)
print({h.name: hparams[h] for h in hparams})
run('logs/hparam_tuning/' + run_name, hparams)
session_num += 1
Error Log
--- Starting trial: run-0
{'dropout_apl': 0.05, 'num_units': 64, 'dropout': 0.25, 'optimizer': 'adam'}
C:\anaconda3\envs\sub_base_one\lib\site-packages\keras\engine\training.py:1972: UserWarning: `Model.fit_generator` is deprecated and will be removed in a future version. Please use `Model.fit`, which supports generators.
warnings.warn('`Model.fit_generator` is deprecated and '
Epoch 1/5
478/478 [==============================] - 57s 111ms/step - loss: -1034990.9375 - accuracy: 0.3468 - val_loss: -3408716.0000 - val_accuracy: 0.2863
Epoch 2/5
478/478 [==============================] - 52s 109ms/step - loss: -27187870.0000 - accuracy: 0.3779 - val_loss: -70205120.0000 - val_accuracy: 0.3440
Epoch 3/5
478/478 [==============================] - 53s 111ms/step - loss: -159927984.0000 - accuracy: 0.3481 - val_loss: -305764640.0000 - val_accuracy: 0.4137
Epoch 4/5
478/478 [==============================] - 55s 114ms/step - loss: -513765920.0000 - accuracy: 0.3257 - val_loss: -822113920.0000 - val_accuracy: 0.2790
Epoch 5/5
478/478 [==============================] - 54s 113ms/step - loss: -1208896128.0000 - accuracy: 0.3155 - val_loss: -1744491776.0000 - val_accuracy: 0.3015
60/60 [==============================] - 1s 17ms/step - loss: -1766485504.0000 - accuracy: 0.3639
--- Starting trial: run-1
{'dropout_apl': 0.05, 'num_units': 64, 'dropout': 0.25, 'optimizer': 'adamax'}
Epoch 1/5
478/478 [==============================] - 56s 115ms/step - loss: -34721.3828 - accuracy: 0.3015 - val_loss: -56985.7461 - val_accuracy: 0.2465
Epoch 2/5
478/478 [==============================] - 55s 115ms/step - loss: -642847.1875 - accuracy: 0.3482 - val_loss: -1573540.5000 - val_accuracy: 0.4442
Epoch 3/5
478/478 [==============================] - 55s 114ms/step - loss: -3433380.0000 - accuracy: 0.4208 - val_loss: -6417029.0000 - val_accuracy: 0.4373
Epoch 4/5
478/478 [==============================] - 55s 115ms/step - loss: -10932957.0000 - accuracy: 0.3973 - val_loss: -16847372.0000 - val_accuracy: 0.3382
Epoch 5/5
478/478 [==============================] - 56s 117ms/step - loss: -26557560.0000 - accuracy: 0.3720 - val_loss: -38307184.0000 - val_accuracy: 0.4483
60/60 [==============================] - 1s 17ms/step - loss: -39560612.0000 - accuracy: 0.4704
--- Starting trial: run-2
{'dropout_apl': 0.05, 'num_units': 64, 'dropout': 0.25, 'optimizer': 'sgd'}
Epoch 1/5
478/478 [==============================] - 56s 114ms/step - loss: nan - accuracy: 0.2530 - val_loss: nan - val_accuracy: 0.2533
Epoch 2/5
478/478 [==============================] - 54s 113ms/step - loss: nan - accuracy: 0.2532 - val_loss: nan - val_accuracy: 0.2533
Epoch 3/5
148/478 [========>.....................] - ETA: 33s - loss: nan - accuracy: 0.2544
I hope someone can help solve the problem and tell me the cause and solution . Thank you for helping
# We have 2 inputs, 1 for each picture
left_input = Input(img_size)
right_input = Input(img_size)
# We will use 2 instances of 1 network for this task
convnet = Sequential([
Conv2D(4,3, input_shape=img_size, padding='same'),
Activation('relu'),
MaxPooling2D(),
Conv2D(4,3, padding='same'),
Activation('relu'),
MaxPooling2D(),
Conv2D(4,3, padding='same'),
Activation('relu'),
MaxPooling2D(),
Conv2D(4,3, padding='same'),
Activation('relu'),
Flatten(),
Dropout(0.3),
Dense(18),
Activation('sigmoid')
])
# Connect each 'leg' of the network to each input
# Remember, they have the same weights
encoded_l = convnet(left_input)
encoded_r = convnet(right_input)
# Getting the L1 Distance between the 2 encodings
L1_layer = Lambda(lambda tensor:K.abs(tensor[0] - tensor[1]))
# Add the distance function to the network
L1_distance = L1_layer([encoded_l, encoded_r])
prediction = Dense(1,activation='sigmoid')(L1_distance)
siamese_net = Model(inputs=[left_input,right_input],outputs=prediction)
optimizer = Adam(lr, decay=2.5e-4)
#//TODO: get layerwise learning rates and momentum annealing scheme described in paperworking
siamese_net.compile(loss=tfa.losses.contrastive.contrastive_loss,optimizer=optimizer,metrics=['acc'])
siamese_net.summary()
my accuracy is decreasing eventhough loss value is decreasing?
I have got output like this
Epoch 1/10 6368/6368 [==============================] - 647s 102ms/step - loss: 0.1762 - acc: 0.2134 - val_loss: 0.1590 - val_acc: 0.1784
Epoch 2/10 6368/6368 [==============================] - 1094s 172ms/step - loss: 0.1649 - acc: 0.1881 - val_loss: 0.1548 - val_acc: 0.1784
Epoch 3/10 6368/6368 [==============================] - 1440s 226ms/step - loss: 0.1573 - acc: 0.1779 - val_loss: 0.1515 - val_acc: 0.1790
may i know what is the reason why my accuracy is reducing even though the loss function is reducing?
I'm trying to create a binary classifier that can differentiate between MRIs of alzheimer's patients and healthy individuals.
These are the stats so far:
1032 training images
400 validation images
Running a simple model as shown below
I have both the raw 160x160 images as well as the images after edge detection
Model:
model = Sequential([
Conv2D(filters=16, kernel_size=(5, 5), activation='relu', padding = 'same', input_shape=(160,160,3)),
MaxPool2D(pool_size=(2, 2), strides=2),
Flatten(),
Dense(units=2, activation='softmax')
])
As you can see - it's very simple, something I've done purposefully to try and remedy the issue of overfitting.
Output:
11/11 [==============================] - 2s 194ms/step - loss: 0.7604 - accuracy: 0.5155 - val_loss: 0.7081 - val_accuracy: 0.5000
Epoch 2/20
11/11 [==============================] - 2s 185ms/step - loss: 0.6885 - accuracy: 0.5223 - val_loss: 0.6942 - val_accuracy: 0.4839
Epoch 3/20
11/11 [==============================] - 2s 185ms/step - loss: 0.6802 - accuracy: 0.5854 - val_loss: 0.6985 - val_accuracy: 0.4931
Epoch 4/20
11/11 [==============================] - 2s 185ms/step - loss: 0.6717 - accuracy: 0.5932 - val_loss: 0.6996 - val_accuracy: 0.4677
Epoch 5/20
11/11 [==============================] - 2s 195ms/step - loss: 0.6512 - accuracy: 0.6175 - val_loss: 0.7124 - val_accuracy: 0.5115
Epoch 6/20
11/11 [==============================] - 2s 185ms/step - loss: 0.6345 - accuracy: 0.6476 - val_loss: 0.7073 - val_accuracy: 0.5253
Epoch 7/20
11/11 [==============================] - 2s 185ms/step - loss: 0.6118 - accuracy: 0.6680 - val_loss: 0.6920 - val_accuracy: 0.5207
Epoch 8/20
11/11 [==============================] - 2s 185ms/step - loss: 0.5817 - accuracy: 0.7068 - val_loss: 0.6964 - val_accuracy: 0.5207
Epoch 9/20
11/11 [==============================] - 2s 184ms/step - loss: 0.5528 - accuracy: 0.7272 - val_loss: 0.7123 - val_accuracy: 0.5161
Epoch 10/20
11/11 [==============================] - 2s 193ms/step - loss: 0.5239 - accuracy: 0.7417 - val_loss: 0.7397 - val_accuracy: 0.5392
Epoch 11/20
11/11 [==============================] - 2s 186ms/step - loss: 0.5106 - accuracy: 0.7427 - val_loss: 0.7551 - val_accuracy: 0.5461
Epoch 12/20
11/11 [==============================] - 2s 197ms/step - loss: 0.4920 - accuracy: 0.7650 - val_loss: 0.7402 - val_accuracy: 0.5438
Epoch 13/20
11/11 [==============================] - 2s 190ms/step - loss: 0.4741 - accuracy: 0.7835 - val_loss: 0.7564 - val_accuracy: 0.5507
Epoch 14/20
11/11 [==============================] - 2s 188ms/step - loss: 0.4591 - accuracy: 0.7767 - val_loss: 0.7445 - val_accuracy: 0.5300
Epoch 15/20
11/11 [==============================] - 2s 185ms/step - loss: 0.4486 - accuracy: 0.7767 - val_loss: 0.7712 - val_accuracy: 0.5415
Epoch 16/20
11/11 [==============================] - 2s 185ms/step - loss: 0.4503 - accuracy: 0.7806 - val_loss: 0.7446 - val_accuracy: 0.5346
Epoch 17/20
11/11 [==============================] - 2s 188ms/step - loss: 0.4404 - accuracy: 0.7670 - val_loss: 0.7669 - val_accuracy: 0.5553
Epoch 18/20
11/11 [==============================] - 2s 184ms/step - loss: 0.4169 - accuracy: 0.8078 - val_loss: 0.7804 - val_accuracy: 0.5576
Epoch 19/20
11/11 [==============================] - 2s 184ms/step - loss: 0.3987 - accuracy: 0.7971 - val_loss: 0.7846 - val_accuracy: 0.5507
Epoch 20/20
11/11 [==============================] - 2s 192ms/step - loss: 0.3977 - accuracy: 0.7981 - val_loss: 0.8060 - val_accuracy: 0.5461
Things I've tried so far:
resizing the image to a smaller input
adding dropout layers
using preprocessed images where it's just the edges shown
ensuring both classes in both training and validation datasets are evenly distributed
changing learning rate
reducing number of parameters to be of the same magnitude of the number of training images i have
I am literally out of ideas, I'm not sure how to move forward with this so I would appreciate any tips or advice.
All my code:
# Use ImageDataGenerator to create 3 lots of batches
train_batches = ImageDataGenerator(
rescale=1/255).flow_from_directory(directory=train_path,
target_size=(80,80), classes=['cn', 'ad'], batch_size=100,
color_mode="rgb")
valid_batches = ImageDataGenerator(
rescale=1/255).flow_from_directory(directory=valid_path,
target_size=(80,80), classes=['cn', 'ad'], batch_size=100,
color_mode="rgb")
# test_batches = ImageDataGenerator(
# rescale=1/255).flow_from_directory(directory=test_path,
# target_size=(224,224), classes=['cn', 'ad'], batch_size=10,
# color_mode="rgb")
imgs, labels = next(train_batches)
# Test to see normalisation has occurred properly
print(imgs[1][8])
# Define method to plot MRIs
def plotImages(images_arr):
fig, axes = plt.subplots(1, 10, figsize=(20,20))
axes = axes.flatten()
for img, ax in zip( images_arr, axes):
ax.imshow(img)
ax.axis('off')
plt.tight_layout()
plt.show()
# Plot a sample of MRIs
plotImages(imgs)
# # Define the model
# # VGG16
# model = Sequential()
# model.add(Conv2D(input_shape=(160,160,3),filters=64,kernel_size=(3,3),padding="same", activation="relu"))
# model.add(Conv2D(filters=64,kernel_size=(3,3),padding="same", activation="relu"))
# model.add(MaxPool2D(pool_size=(2,2),strides=(2,2)))
# model.add(Conv2D(filters=128, kernel_size=(3,3), padding="same", activation="relu"))
# model.add(Conv2D(filters=128, kernel_size=(3,3), padding="same", activation="relu"))
# model.add(MaxPool2D(pool_size=(2,2),strides=(2,2)))
# model.add(Conv2D(filters=256, kernel_size=(3,3), padding="same", activation="relu"))
# model.add(Conv2D(filters=256, kernel_size=(3,3), padding="same", activation="relu"))
# model.add(Conv2D(filters=256, kernel_size=(3,3), padding="same", activation="relu"))
# model.add(MaxPool2D(pool_size=(2,2),strides=(2,2)))
# model.add(Conv2D(filters=512, kernel_size=(3,3), padding="same", activation="relu"))
# model.add(Conv2D(filters=512, kernel_size=(3,3), padding="same", activation="relu"))
# model.add(Conv2D(filters=512, kernel_size=(3,3), padding="same", activation="relu"))
# model.add(MaxPool2D(pool_size=(2,2),strides=(2,2)))
# model.add(Conv2D(filters=512, kernel_size=(3,3), padding="same", activation="relu"))
# model.add(Conv2D(filters=512, kernel_size=(3,3), padding="same", activation="relu"))
# model.add(Conv2D(filters=512, kernel_size=(3,3), padding="same", activation="relu"))
# model.add(MaxPool2D(pool_size=(2,2),strides=(2,2)))
# model.add(Flatten())
# model.add(Dense(units=1024,activation="relu"))
# model.add(Dense(units=128,activation="relu"))
# model.add(Dense(units=2, activation="softmax"))
# # Model from the paper
# model = Sequential([
# Conv2D(filters=32, kernel_size=(3, 3), activation='relu', padding = 'same', input_shape=(160,160,3)),
# Conv2D(filters=32, kernel_size=(3, 3), activation='relu', padding='same'),
# MaxPool2D(pool_size=(2, 2), strides=2),
# Flatten(),
# Dense(units=2, activation='softmax')
# ])
## Model from Dr Paul
# static_conv_layer=Conv2D(filters=16, kernel_size=(5, 5), activation='relu', padding = 'same')
#
# model = Sequential([
# Conv2D(filters=16, kernel_size=(5, 5), activation='relu', padding = 'same', input_shape=(32,32,3)),
# MaxPool2D(pool_size=(2, 2), strides=2),
# Dropout(0.1),
# static_conv_layer,
# MaxPool2D(pool_size=(2, 2), strides=2),
# Dropout(0.1),
# Flatten(),
# Dense(units=2, activation='softmax')
# ])
# This model hits around 75% train acc, 54% val acc
model = Sequential([
Conv2D(filters=16, kernel_size=(5, 5), activation='relu', padding = 'same', input_shape=(80,80,3)),
MaxPool2D(pool_size=(2, 2), strides=2),
# Dropout(0.1),
# Conv2D(filters=16, kernel_size=(3, 3), activation='relu', padding='same'),
# MaxPool2D(pool_size=(2, 2), strides=2),
# Conv2D(filters=16, kernel_size=(3, 3), activation='relu', padding='same'),
# MaxPool2D(pool_size=(2, 2), strides=2),
Flatten(),
Dense(units=2, activation='softmax')
])
# model = Sequential([
# Conv2D(filters=32, kernel_size=(3, 3), activation='relu', padding = 'same', input_shape=(160,160,3)),
# Conv2D(filters=32, kernel_size=(3, 3), activation='relu', padding='same'),
# MaxPool2D(pool_size=(2, 2), strides=2),
# Conv2D(filters=32, kernel_size=(3, 3), activation='relu', padding='same'),
# Flatten(),
# Dense(units=2, activation='softmax')
# ])
## Basic model with dropouts
# model = Sequential([
# Conv2D(filters=32, kernel_size=(3, 3), activation='relu', padding = 'same', input_shape=(224,224,3)),
# MaxPool2D(pool_size=(2, 2), strides=2),
# Dropout(0.1),
# Conv2D(filters=64, kernel_size=(3, 3), activation='relu', padding='same'),
# MaxPool2D(pool_size=(2, 2), strides=2),
# Dropout(0.2),
# Conv2D(filters=128, kernel_size=(3, 3), activation='relu', padding='same'),
# MaxPool2D(pool_size=(2, 2), strides=2),
# Dropout(0.3),
# Flatten(),
# Dense(units=1, activation='sigmoid')
# ])
# Summarise each layer of the model
print(model.summary())
# Compile and train the model
model.compile(optimizer=Adam(), loss='binary_crossentropy', metrics=['accuracy'])
model.fit(x=train_batches,
steps_per_epoch=len(train_batches),
validation_data=valid_batches,
validation_steps=len(valid_batches),
epochs=20,
verbose=1
)
EDIT:
This paper seems to be doing much better than me and completing a very similar task, it may be useful to look at the methodology for:
Things you can try.
It's a nice way to start with transfer learning. Using image net weights helps you to train just last layers and give much better accuracy.
Adding early stopping and learning rate reduction with validation accuracy as constraint.
Taking advantage of ImageDataGenerator and add much more data augmentation techniques.
Make your model much deeper and also try different optimizer(RMSprop), run for more epochs with early stopping.
Add callbacks and plot training validation accuracy graphs with respective to learning rate to see which lr proves best for the data.
It looks like your model is overfitting due to a lack of data. You can do some data augmentation to increase how many images you have. If you don't care about your aspect ratio you can warp the images, if you don't always need the full image you can crop it and you can rotate it if orientation is not important. These things can dramatically increase your dataset size and help mitigate overfitting.
Here is an example from the tensorflow documentation:
batch_size = 32
AUTOTUNE = tf.data.experimental.AUTOTUNE
def prepare(ds, shuffle=False, augment=False):
# Resize and rescale all datasets
ds = ds.map(lambda x, y: (resize_and_rescale(x), y),
num_parallel_calls=AUTOTUNE)
if shuffle:
ds = ds.shuffle(1000)
# Batch all datasets
ds = ds.batch(batch_size)
# Use data augmentation only on the training set
if augment:
ds = ds.map(lambda x, y: (data_augmentation(x, training=True), y),
num_parallel_calls=AUTOTUNE)
# Use buffered prefecting on all datasets
return ds.prefetch(buffer_size=AUTOTUNE)
Also, here is a great video to watch from the TensorFlow developers youtube channel which explains the idea of image augmentation and shows an example of how to implement it.
I've been looking at other tutorials and they're able to get up to 90% accuracy after just 10 epochs. So I'm guessing there's something wrong in my implementation because my Accuracy is really low, it's less than 1% after 10 epochs and barely increasing. I'm using the MNIST dataset and any help would be greatly appreciated
from PIL import Image
from tensorflow.keras import datasets, layers, models
from keras.layers import Dense, Dropout, Flatten
import matplotlib.pyplot as plt
import numpy as np
import keras
(X_train, y_train), (X_test, y_test) = tf.keras.datasets.mnist.load_data()
X_train = X_train/255
X_test = X_test/255
X_train_processed = np.reshape(X_train,[X_train.shape[0],X_train.shape[1],X_train.shape[2],1])
X_test_processed = np.reshape(X_test,[X_test.shape[0],X_test.shape[1],X_test.shape[2],1])
X_train_processed = np.pad(X_train_processed, ((0,0),(2,2),(2,2),(0,0)), 'constant')
X_test_processed = np.pad(X_test_processed, ((0,0),(2,2),(2,2),(0,0)), 'constant')
X_train_processed = tf.image.resize(
images = X_train_processed,
size = np.array([32,32])
)
X_test_processed = tf.image.resize(
images = X_test_processed,
size = np.array([32,32])
)
Y_train_processed = tf.one_hot(y_train,10)
Y_test_processed = tf.one_hot(y_test,10)
Lnet = tf.keras.Sequential()
#First Layer
Lnet.add(
tf.keras.layers.Conv2D(
filters = 6,
kernel_size = (5,5),
strides = (1,1),
padding = 'valid',
activation = 'relu',
#kernel_initializer = keras.initializers.glorot_normal(seed=0)
)
)
Lnet.add(
tf.keras.layers.AveragePooling2D(
pool_size = (2,2),
strides = (2,2),
padding = 'valid'
)
)
#Second Layer
Lnet.add(
tf.keras.layers.Conv2D(
filters = 16,
kernel_size = (5,5),
strides = (1,1),
padding = 'valid',
activation = 'relu'#,
#kernel_initializer = keras.initializers.glorot_normal(seed=0)
)
)
Lnet.add(
tf.keras.layers.AveragePooling2D(
pool_size = (2,2),
strides = (2,2),
padding = 'valid'
)
)
Lnet.add(tf.keras.layers.Flatten())
Lnet.add(
tf.keras.layers.Dense(
units = 120,
activation = 'relu'
)
)
Lnet.add(tf.keras.layers.Flatten())
Lnet.add(
tf.keras.layers.Dense(
units = 84,
activation = 'relu'
)
)
Lnet.add(
tf.keras.layers.Dense(
units = 10,
activation = 'softmax'
)
)
Lnet.compile(
loss = keras.losses.categorical_crossentropy,
optimizer = 'Adam',
metrics = ['Accuracy']
)
Lnet.fit(
x = X_train_processed,
y = Y_train_processed,
batch_size = 128,
epochs = 10,
)
score = Lnet.evaluate(
x = X_test_processed,
y = Y_test_processed
)
print(score[1])
Ouptut:
Epoch 1/10
469/469 [==============================] - 8s 18ms/step - loss: 0.3533 - accuracy: 0.0000e+00
Epoch 2/10
469/469 [==============================] - 8s 18ms/step - loss: 0.1013 - accuracy: 5.1667e-05
Epoch 3/10
469/469 [==============================] - 8s 18ms/step - loss: 0.0730 - accuracy: 2.3167e-04
Epoch 4/10
469/469 [==============================] - 10s 21ms/step - loss: 0.0582 - accuracy: 4.8833e-04
Epoch 5/10
469/469 [==============================] - 9s 19ms/step - loss: 0.0478 - accuracy: 9.3333e-04
Epoch 6/10
469/469 [==============================] - 11s 23ms/step - loss: 0.0405 - accuracy: 0.0019
Epoch 7/10
469/469 [==============================] - 12s 25ms/step - loss: 0.0371 - accuracy: 0.0026
Epoch 8/10
469/469 [==============================] - 11s 23ms/step - loss: 0.0301 - accuracy: 0.0057
Epoch 9/10
469/469 [==============================] - 12s 25ms/step - loss: 0.0280 - accuracy: 0.0065
Epoch 10/10
469/469 [==============================] - 11s 24ms/step - loss: 0.0260 - accuracy: 0.0085
313/313 [==============================] - 1s 3ms/step - loss: 0.0323 - accuracy: 0.0080
0.008030000142753124
I changed couple of imports and metric from Accuracy to 'accuracy`. Please check the changes below. With these small modification, accuracy is coming out as 98.7% (see below). One suggestion is don't mix functions from two different packages (Keras and Tensorflow).
from PIL import Image
from tensorflow.keras import datasets, layers, models
from tensorflow.keras.layers import Dense, Dropout, Flatten
import matplotlib.pyplot as plt
import numpy as np
import keras
(X_train, y_train), (X_test, y_test) = tf.keras.datasets.mnist.load_data()
X_train = X_train/255
X_test = X_test/255
X_train_processed = np.reshape(X_train,[X_train.shape[0],X_train.shape[1],X_train.shape[2],1])
X_test_processed = np.reshape(X_test,[X_test.shape[0],X_test.shape[1],X_test.shape[2],1])
X_train_processed = np.pad(X_train_processed, ((0,0),(2,2),(2,2),(0,0)), 'constant')
X_test_processed = np.pad(X_test_processed, ((0,0),(2,2),(2,2),(0,0)), 'constant')
X_train_processed = tf.image.resize(
images = X_train_processed,
size = np.array([32,32])
)
X_test_processed = tf.image.resize(
images = X_test_processed,
size = np.array([32,32])
)
Y_train_processed = tf.one_hot(y_train,10)
Y_test_processed = tf.one_hot(y_test,10)
Lnet = tf.keras.Sequential()
#First Layer
Lnet.add(
tf.keras.layers.Conv2D(
filters = 6,
kernel_size = (5,5),
strides = (1,1),
padding = 'valid',
activation = 'relu',
#kernel_initializer = keras.initializers.glorot_normal(seed=0)
)
)
Lnet.add(
tf.keras.layers.AveragePooling2D(
pool_size = (2,2),
strides = (2,2),
padding = 'valid'
)
)
#Second Layer
Lnet.add(
tf.keras.layers.Conv2D(
filters = 16,
kernel_size = (5,5),
strides = (1,1),
padding = 'valid',
activation = 'relu'#,
#kernel_initializer = keras.initializers.glorot_normal(seed=0)
)
)
Lnet.add(
tf.keras.layers.AveragePooling2D(
pool_size = (2,2),
strides = (2,2),
padding = 'valid'
)
)
Lnet.add(tf.keras.layers.Flatten())
Lnet.add(
tf.keras.layers.Dense(
units = 120,
activation = 'relu'
)
)
Lnet.add(tf.keras.layers.Flatten())
Lnet.add(
tf.keras.layers.Dense(
units = 84,
activation = 'relu'
)
)
Lnet.add(
tf.keras.layers.Dense(
units = 10,
activation = 'softmax'
)
)
Lnet.compile(
loss = tf.keras.losses.categorical_crossentropy,
optimizer = 'Adam',
metrics = ['accuracy']
)
Lnet.fit(
x = X_train_processed,
y = Y_train_processed,
batch_size = 128,
epochs = 10,
)
score = Lnet.evaluate(
x = X_test_processed,
y = Y_test_processed
)
print(score[1])
Epoch 9/10
469/469 [==============================] - 30s 64ms/step - loss: 0.0260 - accuracy: 0.9916
Epoch 10/10
469/469 [==============================] - 30s 64ms/step - loss: 0.0239 - accuracy: 0.9922
313/313 [==============================] - 3s 10ms/step - loss: 0.0394 - accuracy: 0.9876
0.9876000285148621
Complete code is here.