I am trying to design a model for binary image classification, this is my first classifier and I am following an online tutorial but the model always predicts class 0
My dataset contains 3620 and 3651 images of each class respectively, I don't suppose the problem is due to an imbalanced dataset as the model is predicting only the class with lower number of sample in the dataset.
My code
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
from keras import backend as K
img_hieght, img_width = 150,150
train_data_dir = 'dataset/train'
#validation_data_dir = 'dataset/validation'
nb_train_samples = 3000
#nb_validation_samples = 500
epochs = 10
batch_size = 16
if K.image_data_format() == 'channels_first':
input_shape = (3, img_width, img_hieght)
else:
input_shape = (img_width, img_hieght, 3)
model = Sequential()
model.add(Conv2D(32,(3,3), input_shape = input_shape))
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())
model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(1))
model.add(Activation('sigmoid'))
model.compile(loss = 'binary_crossentropy', optimizer = 'rmsprop', metrics = ['accuracy'])
train_datagen = ImageDataGenerator(
rescale = 1. /255,
shear_range = 0.2,
zoom_range = 0.2,
horizontal_flip = True)
train_generator = train_datagen.flow_from_directory(
train_data_dir,
target_size = (img_width,img_hieght),
batch_size = batch_size,
class_mode = 'binary')
model.fit_generator(train_generator,
steps_per_epoch = nb_train_samples//batch_size,
epochs = epochs)
model.save('classifier.h5')
I have tried checking the model summary as well, but couldn't detect anything notable
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_1 (Conv2D) (None, 148, 148, 32) 896
_________________________________________________________________
activation_1 (Activation) (None, 148, 148, 32) 0
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 74, 74, 32) 0
_________________________________________________________________
conv2d_2 (Conv2D) (None, 72, 72, 32) 9248
_________________________________________________________________
activation_2 (Activation) (None, 72, 72, 32) 0
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 36, 36, 32) 0
_________________________________________________________________
conv2d_3 (Conv2D) (None, 34, 34, 64) 18496
_________________________________________________________________
activation_3 (Activation) (None, 34, 34, 64) 0
_________________________________________________________________
max_pooling2d_3 (MaxPooling2 (None, 17, 17, 64) 0
_________________________________________________________________
flatten_1 (Flatten) (None, 18496) 0
_________________________________________________________________
dense_1 (Dense) (None, 64) 1183808
_________________________________________________________________
activation_4 (Activation) (None, 64) 0
_________________________________________________________________
dropout_1 (Dropout) (None, 64) 0
_________________________________________________________________
dense_2 (Dense) (None, 1) 65
_________________________________________________________________
activation_5 (Activation) (None, 1) 0
=================================================================
Total params: 1,212,513
Trainable params: 1,212,513
Non-trainable params: 0
_________________________________________________________________
None
I have not used validation dataset, I am using only training data and testing the model manually using:
import tensorflow as tf
from keras.preprocessing.image import ImageDataGenerator
batch_size = 16
path = 'dataset/test'
imgen = ImageDataGenerator(rescale=1/255.)
testGene = imgen.flow_from_directory(directory=path,
target_size=(150, 150,),
shuffle=False,
class_mode='binary',
batch_size=batch_size,
save_to_dir=None
)
model = tf.keras.models.load_model("classifier.h5")
pred = model.predict_generator(testGene, steps=testGene.n/batch_size)
print(pred)
Here are the accuracy and loss values per epochs:
Epoch 1/10
187/187 [==============================] - 62s 330ms/step - loss: 0.5881 - accuracy: 0.7182
Epoch 2/10
187/187 [==============================] - 99s 529ms/step - loss: 0.4102 - accuracy: 0.8249
Epoch 3/10
187/187 [==============================] - 137s 733ms/step - loss: 0.3266 - accuracy: 0.8646
Epoch 4/10
187/187 [==============================] - 159s 851ms/step - loss: 0.3139 - accuracy: 0.8620
Epoch 5/10
187/187 [==============================] - 112s 597ms/step - loss: 0.2871 - accuracy: 0.8873
Epoch 6/10
187/187 [==============================] - 60s 323ms/step - loss: 0.2799 - accuracy: 0.8847
Epoch 7/10
187/187 [==============================] - 66s 352ms/step - loss: 0.2696 - accuracy: 0.8870
Epoch 8/10
187/187 [==============================] - 57s 303ms/step - loss: 0.2440 - accuracy: 0.8947
Epoch 9/10
187/187 [==============================] - 56s 299ms/step - loss: 0.2478 - accuracy: 0.8994
Epoch 10/10
187/187 [==============================] - 53s 285ms/step - loss: 0.2448 - accuracy: 0.9047
You use only 3000 samples per epoch (see line nb_train_samples = 3000), while having 3620 and 3651 images for the each class. Given that model gets 90% accuracy and predicts only zeros, I suppose that you pass only class-zero images to the network during training. Consider increasing nb_train_samples.
Related
my training variable shape is (264, 120, 120, 3)
trying to give numpy array of images as input
model = Sequential()
model.add(Conv2D(8, (3, 3), activation='relu', strides=2,input_shape=(image_height,image_width,channels)))
model.add(Conv2D(16, (3, 3), activation='relu'))
model.summary()
model.compile(optimizer='rmsprop', loss='mse')
model.fit(x=X_train, y=y_train, batch_size=1, epochs=1, verbose=1)
below is the error message
________________________________________________________________
Layer (type) Output Shape Param
=================================================================
conv2d_36 (Conv2D) (None, 59, 59, 8) 224
_________________________________________________________________
conv2d_37 (Conv2D) (None, 57, 57, 16) 1168
=================================================================
Total params: 1,392
Trainable params: 1,392
Non-trainable params: 0
ValueError: Error when checking target: expected conv2d_37 to have shape (57, 57, 16) but got array with shape (120, 120, 3)
This error was because of mismatch in shape between model output and training data.
Please refer sample code in below
#Import Dependencies
import keras
from keras.models import Model, Sequential
from keras.layers import Conv2D, Flatten, Dense
# Model Building
model = Sequential()
model.add(Conv2D(8, (3, 3), activation='relu', strides=2, input_shape=(28,28,1)))
model.add(Conv2D(16, (3, 3), activation='relu'))
model.add(Flatten())
model.add(Dense(10, activation='softmax'))
model.compile(optimizer='rmsprop',
loss='binary_crossentropy',
metrics=['mse'])
# Generate dummy data
import numpy as np
data = np.random.random((100, 28, 28, 1))
labels = np.random.randint(2, size=(100, 10))
# Train the model, iterating on the data in batches of 32 samples
model.fit(data, labels, epochs=5, batch_size=32)
Output:
Epoch 1/5
100/100 [==============================] - 0s 1ms/step - loss: 1.2342 - mse: 0.4195
Epoch 2/5
100/100 [==============================] - 0s 234us/step - loss: 1.2183 - mse: 0.4167
Epoch 3/5
100/100 [==============================] - 0s 222us/step - loss: 1.2104 - mse: 0.4151
Epoch 4/5
100/100 [==============================] - 0s 255us/step - loss: 1.2019 - mse: 0.4131
Epoch 5/5
100/100 [==============================] - 0s 239us/step - loss: 1.1938 - mse: 0.4120
How do you know when you've successfully frozen a layer in Keras? Below is a snippet of my model where I am trying to freeze the entire DenseNet121 layer; however, I'm unsure if that is actually occurring since the outputs to the console don't indicate what's happening.
I've tried two methods (1) densenet.trainable = False and (2) model.layers[0].trainable = False.
Furthermore, if I load the model again and add model.layers[0].trainable = True, will this unfreeze the layer?
densenet = DenseNet121(
weights='/{}'.format(WEIGHTS_FILE_NAME),
include_top=False,
input_shape=(IMG_SIZE, IMG_SIZE, 3)
)
model = Sequential()
model.add(densenet)
model.add(layers.GlobalAveragePooling2D())
model.add(layers.Dropout(0.5))
model.add(layers.Dense(NUM_CLASSES, activation='sigmoid'))
model.summary()
# This is how I freeze my layers, I decided to do it twice because I wasn't sure if it was working
densenet.trainable = False
model.layers[0].trainable = False
history = model.fit_generator(
datagen.flow(x_train, y_train, batch_size=BATCH_SIZE),
steps_per_epoch=len(x_train) / BATCH_SIZE,
epochs=NUM_EPOCHS,
validation_data=(x_test, y_test),
callbacks=callbacks_list,
max_queue_size=2
)
Below is the output of model.summary(), which I would expect to indicate if a layer has been successfully frozen or not.
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
densenet121 (Model) (None, 8, 8, 1024) 7037504
_________________________________________________________________
global_average_pooling2d_3 ( (None, 1024) 0
_________________________________________________________________
dropout_2 (Dropout) (None, 1024) 0
_________________________________________________________________
dense_2 (Dense) (None, 5) 5125
=================================================================
Total params: 7,042,629
Trainable params: 5,125
Non-trainable params: 7,037,504
_________________________________________________________________
Epoch 1/100
354/353 [==============================] - 203s 573ms/step - loss: 0.4374 - acc: 0.8098 - val_loss: 0.3785 - val_acc: 0.8290
val_kappa: 0.0440
Epoch 2/100
354/353 [==============================] - 199s 561ms/step - loss: 0.3738 - acc: 0.8457 - val_loss: 0.3575 - val_acc: 0.8310
val_kappa: 0.0463
Epoch 3/100
however, I'm unsure if that is actually occurring since the outputs to
the console don't indicate what's happening.
It does, as can be seen from the number of trainable parameters. As expected, only the parameters(5125) of the last Dense layer are trainable.
Total params: 7,042,629
Trainable params: 5,125
Non-trainable params: 7,037,504
You can find whether a layer is frozen by looking at it's config:
>>> model.get_layer("dense_2").get_config()
{'name': 'dense_2',
'trainable': True,
...
If trainable is True, it is unfrozen.
I am new to python, deep learning and keras. I known many people asked similar questions before and i tried to read through them but my issues is still not solve. could someone please give me a hand
I want to build a 6 inputs and 1 output model. below are my codes. your help or hint will be truly appreciated.
input and output shape:
print(x_train.shape, y_train.shape)
output:
(503, 6) (503, 1)
model codes:
inputList={}
lstmList={}
for i in range (x_train.shape[1]):
inputList[varList[i]]=Input(shape=(x_train.shape[0], 1), name=varList[i])
lstmList[varList[i]]=LSTM(64, activation='relu', return_sequences=None, dropout=0.2)(inputList[varList[i]])
z=concatenate([lstmList[i] for i in varList])
output=Dense(next_number_prediction, activation='softmax')(z)
model = Model(inputs=[inputList[i] for i in varList], outputs=[output])
model.compile(optimizer='rmsprop',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
model.summary()
the output is:
Layer (type) Output Shape Param # Connected to
==================================================================================================
open (InputLayer) (None, 503, 1) 0
__________________________________________________________________________________________________
high (InputLayer) (None, 503, 1) 0
__________________________________________________________________________________________________
low (InputLayer) (None, 503, 1) 0
__________________________________________________________________________________________________
close (InputLayer) (None, 503, 1) 0
__________________________________________________________________________________________________
change (InputLayer) (None, 503, 1) 0
__________________________________________________________________________________________________
pct (InputLayer) (None, 503, 1) 0
__________________________________________________________________________________________________
lstm_7 (LSTM) (None, 64) 16896 open[0][0]
__________________________________________________________________________________________________
lstm_8 (LSTM) (None, 64) 16896 high[0][0]
__________________________________________________________________________________________________
lstm_9 (LSTM) (None, 64) 16896 low[0][0]
__________________________________________________________________________________________________
lstm_10 (LSTM) (None, 64) 16896 close[0][0]
__________________________________________________________________________________________________
lstm_11 (LSTM) (None, 64) 16896 change[0][0]
__________________________________________________________________________________________________
lstm_12 (LSTM) (None, 64) 16896 pct[0][0]
__________________________________________________________________________________________________
concatenate_1 (Concatenate) (None, 384) 0 lstm_7[0][0]
lstm_8[0][0]
lstm_9[0][0]
lstm_10[0][0]
lstm_11[0][0]
lstm_12[0][0]
__________________________________________________________________________________________________
dense_1 (Dense) (None, 1) 385 concatenate_1[0][0]
==================================================================================================
Total params: 101,761
Trainable params: 101,761
Non-trainable params: 0
__________________________________________________________________________________________________
Data treatment and model.fit:
Data={}
for i in range (x_train.shape[1]):
Data[varList[i]]=np.expand_dims(x_train[:, i], axis=0)
Data[varList[i]]=np.reshape(Data[varList[i]], (1,x_train.shape[0],1))
model.fit(
[Data[i] for i in varList],
[y_train],
epochs=10)
and the error is
ValueError Traceback (most recent call last)
<ipython-input-21-392e0052f15a> in <module>()
1 model.fit(
2 [Data[i] for i in varList],
----> 3 [y_train],
epochs=10)
/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py in fit(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, max_queue_size, workers, use_multiprocessing, **kwargs)
1534 steps_name='steps_per_epoch',
1535 steps=steps_per_epoch,
-> 1536 validation_split=validation_split)
1537
1538 # Prepare validation data.
/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py in _standardize_user_data(self, x, y, sample_weight, class_weight, batch_size, check_steps, steps_name, steps, validation_split)
990 x, y, sample_weight = next_element
991 x, y, sample_weights = self._standardize_weights(x, y, sample_weight,
--> 992 class_weight, batch_size)
993 return x, y, sample_weights
994
/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py in _standardize_weights(self, x, y, sample_weight, class_weight, batch_size)
1167 # Check that all arrays have the same length.
1168 if not self._distribution_strategy:
-> 1169 training_utils.check_array_lengths(x, y, sample_weights)
1170 if self._is_graph_network and not context.executing_eagerly():
1171 # Additional checks to avoid users mistakenly using improper loss fns.
/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training_utils.py in check_array_lengths(inputs, targets, weights)
424 'the same number of samples as target arrays. '
425 'Found ' + str(list(set_x)[0]) + ' input samples '
--> 426 'and ' + str(list(set_y)[0]) + ' target samples.')
427 if len(set_w) > 1:
428 raise ValueError('All sample_weight arrays should have '
ValueError: Input arrays should have the same number of samples as target arrays. Found 1 input samples and 503 target samples.
The feed input and output dimension
print (Data[varList[i]].shape)
print (np.array([Data[i] for i in varList]).shape)
print (y_train.shape)
output:
(1, 503, 1)
(6, 1, 503, 1)
(503, 1)
tried new codes:
input = Input(shape=(x_train.shape))
lstm = LSTM(64, activation='relu', return_sequences=True, dropout=0.2)(input)
output = Dense(1)(lstm)
model2 = Model(inputs=input, outputs=output)
model2.compile(optimizer='rmsprop',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
model2.fit(x_train[np.newaxis,:,:], y_train[np.newaxis,:,:])
gives a untrained model:
Epoch 1/10
1/1 [==============================] - 4s 4s/step - loss: 0.0000e+00 - acc: 0.0000e+00
Epoch 2/10
1/1 [==============================] - 0s 385ms/step - loss: 0.0000e+00 - acc: 0.0000e+00
Epoch 3/10
1/1 [==============================] - 0s 387ms/step - loss: 0.0000e+00 - acc: 0.0000e+00
Epoch 4/10
1/1 [==============================] - 0s 386ms/step - loss: 0.0000e+00 - acc: 0.0000e+00
Epoch 5/10
1/1 [==============================] - 0s 390ms/step - loss: 0.0000e+00 - acc: 0.0000e+00
Epoch 6/10
1/1 [==============================] - 0s 390ms/step - loss: 0.0000e+00 - acc: 0.0000e+00
Epoch 7/10
1/1 [==============================] - 0s 390ms/step - loss: 0.0000e+00 - acc: 0.0000e+00
Epoch 8/10
1/1 [==============================] - 0s 389ms/step - loss: 0.0000e+00 - acc: 0.0000e+00
Epoch 9/10
1/1 [==============================] - 0s 387ms/step - loss: 0.0000e+00 - acc: 0.0000e+00
Epoch 10/10
1/1 [==============================] - 0s 391ms/step - loss: 0.0000e+00 - acc: 0.0000e+00
<tensorflow.python.keras.callbacks.History at 0x7f4c97583e80>
where the max and min of the data are:
print (max(y_train), x_train.max(axis=0))
print (min(y_train), x_train.min(axis=0))
output:
[0.79951533] [0.79930947 0.79750822 0.79934846 0.79951533 0.72939786 0.99697845]
[0.19443386] [1.94643871e-01 1.96481512e-01 1.94604099e-01 1.94433856e-01
2.52289062e-04 3.70721060e-01]
Your network expects only a single label for the whole sequence. If I adapt the code like this it runs:
model.fit(
[Data[i] for i in varList],
[y_train[0:1]],
epochs=10)
Of course you need to decide whether this reflects your attention or whether you need to restructure your network so it accepts one label for every element in the sequence.
By the way: This is how I would have constructed the network. So if you are new to this, maybe this is the architecture that you actually want:
input = Input(shape=(x_train.shape))
lstm = LSTM(64, activation='relu', return_sequences=True, dropout=0.2)(input)
output = Dense(1)(lstm)
model2 = Model(inputs=input, outputs=output)
model2.compile(optimizer='rmsprop',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
model2.fit(x_train[np.newaxis,:,:], y_train[np.newaxis,:,:])
I have 10000 images 5000 diseased Medical images and 5000 healthy images,
I used vgg16 and modified last layers as follows
Layer (type) Output Shape Param #
=================================================================
input_1 (InputLayer) (None, 224, 224, 3) 0
_________________________________________________________________
block1_conv1 (Conv2D) (None, 224, 224, 64) 1792
_________________________________________________________________
block1_conv2 (Conv2D) (None, 224, 224, 64) 36928
_________________________________________________________________
block1_pool (MaxPooling2D) (None, 112, 112, 64) 0
_________________________________________________________________
block2_conv1 (Conv2D) (None, 112, 112, 128) 73856
_________________________________________________________________
block2_conv2 (Conv2D) (None, 112, 112, 128) 147584
_________________________________________________________________
block2_pool (MaxPooling2D) (None, 56, 56, 128) 0
_________________________________________________________________
block3_conv1 (Conv2D) (None, 56, 56, 256) 295168
_________________________________________________________________
block3_conv2 (Conv2D) (None, 56, 56, 256) 590080
_________________________________________________________________
block3_conv3 (Conv2D) (None, 56, 56, 256) 590080
_________________________________________________________________
block3_pool (MaxPooling2D) (None, 28, 28, 256) 0
_________________________________________________________________
block4_conv1 (Conv2D) (None, 28, 28, 512) 1180160
_________________________________________________________________
block4_conv2 (Conv2D) (None, 28, 28, 512) 2359808
_________________________________________________________________
block4_conv3 (Conv2D) (None, 28, 28, 512) 2359808
_________________________________________________________________
block4_pool (MaxPooling2D) (None, 14, 14, 512) 0
_________________________________________________________________
block5_conv1 (Conv2D) (None, 14, 14, 512) 2359808
_________________________________________________________________
block5_conv2 (Conv2D) (None, 14, 14, 512) 2359808
_________________________________________________________________
block5_conv3 (Conv2D) (None, 14, 14, 512) 2359808
_________________________________________________________________
block5_pool (MaxPooling2D) (None, 7, 7, 512) 0
_________________________________________________________________
flatten (Flatten) (None, 25088) 0
_________________________________________________________________
fc1 (Dense) (None, 256) 6422784
_________________________________________________________________
fc2 (Dense) (None, 128) 32896
_________________________________________________________________
output (Dense) (None, 2) 258
=================================================================
Total params: 21,170,626
Trainable params: 6,455,938
Non-trainable params: 14,714,688
My code is as follows
import numpy as np
import os
import time
from vgg16 import VGG16
from keras.preprocessing import image
from imagenet_utils import preprocess_input, decode_predictions
from keras.layers import Dense, Activation, Flatten
from keras.layers import merge, Input
from keras.models import Model
from keras.utils import np_utils
from sklearn.utils import shuffle
from sklearn.cross_validation import train_test_split
# Loading the training data
PATH = '/mount'
# Define data path
data_path = PATH
data_dir_list = os.listdir(data_path)
img_data_list=[]
y=0;
for dataset in data_dir_list:
img_list=os.listdir(data_path+'/'+ dataset)
print ('Loaded the images of dataset-'+'{}\n'.format(dataset))
for img in img_list:
img_path = data_path + '/'+ dataset + '/'+ img
img = image.load_img(img_path, target_size=(224, 224))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = preprocess_input(x)
x = x/255
y=y+1
print('Input image shape:', x.shape)
print(y)
img_data_list.append(x)
from keras.optimizers import SGD
sgd = SGD(lr=1e-3, decay=1e-6, momentum=0.9, nesterov=True)
img_data = np.array(img_data_list)
#img_data = img_data.astype('float32')
print (img_data.shape)
img_data=np.rollaxis(img_data,1,0)
print (img_data.shape)
img_data=img_data[0]
print (img_data.shape)
# Define the number of classes
num_classes = 2
num_of_samples = img_data.shape[0]
labels = np.ones((num_of_samples,),dtype='int64')
labels[0:5001]=0
labels[5001:]=1
names = ['YES','NO']
# convert class labels to on-hot encoding
Y = np_utils.to_categorical(labels, num_classes)
#Shuffle the dataset
x,y = shuffle(img_data,Y, random_state=2)
# Split the dataset
X_train, X_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=2)
image_input = Input(shape=(224, 224, 3))
model = VGG16(input_tensor=image_input, include_top=True,weights='imagenet')
model.summary()
last_layer = model.get_layer('block5_pool').output
x= Flatten(name='flatten')(last_layer)
x = Dense(256, activation='relu', name='fc1')(x)
x = Dense(128, activation='relu', name='fc2')(x)
out = Dense(num_classes, activation='softmax', name='output')(x)
custom_vgg_model2 = Model(image_input, out)
custom_vgg_model2.summary()
# freeze all the layers except the dense layers
for layer in custom_vgg_model2.layers[:-3]:
layer.trainable = False
custom_vgg_model2.summary()
custom_vgg_model2.compile(loss='categorical_crossentropy',optimizer=sgd,metrics=['accuracy'])
t=time.time()
# t = now()
hist = custom_vgg_model2.fit(X_train, y_train, batch_size=128, epochs=50, verbose=1, validation_data=(X_test, y_test))
print('Training time: %s' % (t - time.time()))
(loss, accuracy) = custom_vgg_model2.evaluate(X_test, y_test, batch_size=10, verbose=1)
print("[INFO] loss={:.4f}, accuracy: {:.4f}%".format(loss,accuracy * 100))
model.save("vgg_10000.h5")
The result i'm posting first 5 and last 5 epochs
Epoch 1/50
8000/8000 [==============================] - 154s - loss: 0.6960 - acc: 0.5354 - val_loss: 0.6777 - val_acc: 0.5745
Epoch 2/50
8000/8000 [==============================] - 134s - loss: 0.6684 - acc: 0.5899 - val_loss: 0.6866 - val_acc: 0.5490
Epoch 3/50
8000/8000 [==============================] - 134s - loss: 0.6608 - acc: 0.6040 - val_loss: 0.6625 - val_acc: 0.5925
Epoch 4/50
8000/8000 [==============================] - 134s - loss: 0.6518 - acc: 0.6115 - val_loss: 0.6668 - val_acc: 0.5810
Epoch 5/50
8000/8000 [==============================] - 134s - loss: 0.6440 - acc: 0.6280 - val_loss: 0.6990 - val_acc: 0.5580
last 5
Epoch 25/50
8000/8000 [==============================] - 134s - loss: 0.5944 - acc: 0.6720 - val_loss: 0.6271 - val_acc: 0.6485
Epoch 26/50
8000/8000 [==============================] - 134s - loss: 0.5989 - acc: 0.6699 - val_loss: 0.6483 - val_acc: 0.6135
Epoch 27/50
8000/8000 [==============================] - 134s - loss: 0.5950 - acc: 0.6789 - val_loss: 0.7130 - val_acc: 0.5785
Epoch 28/50
8000/8000 [==============================] - 134s - loss: 0.5853 - acc: 0.6838 - val_loss: 0.6263 - val_acc: 0.6395
The results are not that great I tweked around using 128 and 128 nodes in last two layers using adam optimizer etc still results are not that convincing. Any help is much appriciated.
You can try the following:
Perform a stratified train_test_split
train_test_split(x, y, stratify=y, test_size=0.2, random_state=2)
Look into your data, and see if there are outliers in the images.
Use adam optimizer: from keras.optimizers import Adam instead of SGD
Try other seeds wherever applicable, i.e instead of random_state=2, use something else:
X_train, X_test, y_train, y_test = train_test_split(
x, y, test_size=0.2, random_state=382938)
Try with include_top=False:
model = VGG16(input_tensor=image_input, include_top=False,weights='imagenet')
Use (train, validation, test) sets or (cross-validation, holdout) sets to get a more reliable performance metric.
I am running the tutorial example cifar10_cnn.py from here.
Here is the environment/configuration for the test:
Windows 10
Keras 1.2.0
Theano 0.8.2
Numpy 1.11.2
Enthought/Canopy/MKL(2017.0.1-1)
.theanorc [blas] ldflags -L... -lmk2_rt
The program took about one and half day to finish 200 epochs. The following figure shows the header and the last three epochs.
Using Theano backend
X_train shape: (50000L, 32L, 32L, 3L) ...
Epoch 198/200
50000/50000 [==============================] - 639s - loss: 1.7894 - acc: 0.3497 - val_loss: 1.5930 - val_acc: 0.3968
Epoch 199/200
50000/50000 [==============================] - 617s - loss: 1.8111 - acc: 0.3446 - val_loss: 1.6960 - val_acc: 0.3824
Epoch 200/200
50000/50000 [==============================] - 612s - loss: 1.8005 - acc: 0.3497 - val_loss: 1.6164 - val_acc: 0.4041
I have two questions here:
The accuracy (0.34/0.40) is too bad. Does anyone have similar problems?
The shape of X_train as (50000, 32, 32, 3) seems strange to me because
other keras/cifar examples give the shape of X_train as (50000, 3, 32, 32). If I add "set_image_dim_ordering('th')" to the code, the shape will become (50000, 3, 32, 32) but the program will give even lower accuracy as "Epoch 80/200 50000/50000 - 635s - loss: 14.5010 - acc: 0.1003 - val_loss: 14.5063 - val_acc: 0.1000" How to explain the effect of set dim here?
Thanks for any comments.
That may not be the answer for the whole subject, but in order to get the correct image shape, you should just verify whether the image channel is the first or the last item of the shape. You can do it the following way, considering Keras 2:
from keras import backend as K
def image_input_shape(img_width, img_height):
if K.image_data_format() == 'channels_first':
input_shape = (3, img_width, img_height)
else:
input_shape = (img_width, img_height, 3)
return input_shape
Just pass the image width and height and it will give back the correct ordering of the shape.
From there you can discard or validate you hypothesis for the "strange" shape.
The problem I posted might be related to Keras 1.2.0 only. Since Keras has upgraded to 2.x and the official file cifar10_cnn.py has also changed, the problem I posted might not happen in new Keras. As a result, I would like to close this issue. Bytheway, one more piece info is that set_image_dim_ordering will create a different network architecture. The following output show the difference with this function and without this function.
Using Theano backend.
with K.set_image_dim_ordering('th')
X_train shape: (50000L, 3L, 32L, 32L)
50000 train samples
10000 test samples
InputLayer (None, 3L, 32L, 32L)
Convolution2D (None, 32, 32L, 32L)
Relu (None, 32, 32L, 32L)
Convolution2D (None, 32, 30L, 30L)
Relu (None, 32, 30L, 30L)
MaxPooling2D (None, 32, 15L, 15L)
Dropout (None, 32, 15L, 15L)
Convolution2D (None, 64, 15L, 15L)
Relu (None, 64, 15L, 15L)
Convolution2D (None, 64, 13L, 13L)
Relu (None, 64, 13L, 13L)
MaxPooling2D (None, 64, 6L, 6L)
Dropout (None, 64, 6L, 6L)
Flatten (None, 2304)
Dense (None, 512)
Relu (None, 512)
Dropout (None, 512)
Dense (None, 10)
Softmax (None, 10)
Using Theano backend.
without K.set_image_dim_ordering('th')
X_train shape: (50000L, 32L, 32L, 3L)
50000 train samples
10000 test samples
InputLayer (None, 32L, 32L, 3L)
Convolution2D (None, 32L, 32L, 32)
Relu (None, 32L, 32L, 32)
Convolution2D (None, 30L, 30L, 32)
Relu (None, 30L, 30L, 32)
MaxPooling2D (None, 15L, 15L, 32)
Dropout (None, 15L, 15L, 32)
Convolution2D (None, 15L, 15L, 64)
Relu (None, 15L, 15L, 64)
Convolution2D (None, 13L, 13L, 64)
Relu (None, 13L, 13L, 64)
MaxPooling2D (None, 6L, 6L, 64)
Dropout (None, 6L, 6L, 64)
Flatten (None, 2304)
Dense (None, 512)
Relu (None, 512)
Dropout (None, 512)
Dense (None, 10)
Softmax (None, 10)