I am trying to make an emotion classifier using face expressions with FER2013 dataset. It contains of 35887 samples with 2304 features each and an integer label 0-6 for emotions. When I was using Conv1D with shape (2304,1) then it achieved training accuracy of ~86% but wasn't doing well on any unseen test image. So I thought of reshaping it to (48,48,1) for each sample and using Conv2D on it. But now it just gets stuck on 0.2505 while training after the 2nd epoch and never increases. What's happening?
import pandas as pd
import numpy as np
from PIL import Image
import matplotlib.image as mpimg
from skimage import transform
import random
import matplotlib.pyplot as plt
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
emotion = {0 : 'Angry', 1 : 'Disgust',2 : 'Fear',3 : 'Happy',
4 : 'Sad',5 : 'Surprise',6 : 'Neutral'}
df=pd.read_csv('fer.csv')
faces=df.values[:,1]
faces=faces.tolist()
emos=df.values[:,0]
for i in range(len(faces)):
faces[i]=[int(x) for x in faces[i].split()]
emos[i]=int(emos[i])
faces=np.array(faces)
faces=transform.resize(faces, (35887,48,48))
faces=np.expand_dims(faces, axis=3)
model = Sequential()
model.add(Conv2D(48, (3,3), padding='same', input_shape=(48,48,1), activation='relu'))
model.add(Conv2D(48, (3,3), padding='same', activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Conv2D(96, (3,3), padding='same', activation='relu'))
model.add(Conv2D(96, (3,3), padding='same', activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Conv2D(192, (3,3), padding='same', activation='relu'))
model.add(Conv2D(192, (3,3), padding='same', activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Conv2D(384, (3,3), padding='same', activation='relu'))
model.add(Conv2D(384, (3,3), padding='same', activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Flatten())
model.add(Dense(384, activation='relu'))
model.add(Dropout(0.4))
model.add(Dense(192, activation='relu'))
model.add(Dropout(0.4))
model.add(Dense(96, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(7, activation='softmax'))
model.compile(loss='sparse_categorical_crossentropy',
optimizer='adam',
metrics=['accuracy'])
model.fit(faces,emos,epochs=100,batch_size=48)
model.save_weights('model.h5')
Model Accuracy Curves
Model Loss Curves
Normalizing the output batch after each layer fixes the issue.
Just add
model.add(BatchNormalization())
after every layer.
EDIT :
Thought that I should add more information here.
So, this was the final model I ended up making.
model = Sequential()
model.add(Conv2D(32, (3, 3), input_shape=(200,200,3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(32, (3, 3), activation='relu'))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(BatchNormalization())
model.add(Dropout(0.25))
model.add(Conv2D(128, (3, 3), activation='relu'))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Conv2D(256, (3, 3), activation='relu'))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(512, activation='relu'))
model.add(BatchNormalization())
model.add(Dropout(0.3))
model.add(Dense(256, activation='relu'))
model.add(BatchNormalization())
model.add(Dropout(0.4))
model.add(Dense(128, activation='relu'))
model.add(BatchNormalization())
model.add(Dropout(0.5))
model.add(Dense(len(classes), activation='softmax'))
model.compile(loss='sparse_categorical_crossentropy',
optimizer='nadam',
metrics=['accuracy'])
And these were the results I got with it.
I increased the nodes and changed the optimizer too but it was the batch normalisation which gave a dramatic increase in accuracy. Using more nodes and nadam optimizer further helped a bit.
Related
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'))
As far as I understand, model.add(Conv2D(32, (3, 3), input_shape=input_shape)) is the input layer here and model.add(Activation('sigmoid')) is the output layer.
There are a total 13 other layers between the input and output layers. So are there 13 hidden layers in the model? Or less? What are the names of the layers that should be counted as hidden layers?
I am confused about whether Activation or MaxPooling2D or Dropout should be counted as a single hidden layer or not.
Activation functions are not the hidden layers.
Layers will be - Conv2D,MaxPooling2D,Flatten,Dense
You can use below code to get the model architecture details.
model.summary()
I have built a simple CNN using tensorflow-gpu 2.4.0 for cifar10
# Set constent
num_classes = len(label_names) # The number of classes
input_shape = (32, 32, 3) # The input shape 32 * 32 pixels, 3 RGB brightness for each pixel
# Construct a sequential model
model = Sequential()
# Starting add layers to the model
# First VGG blockes
model.add(Conv2D(16, (3, 3), padding='same', activation='relu', input_shape=input_shape))
model.add(BatchNormalization()) # BatchNormalization after convolutional layer
model.add(Conv2D(16, (3, 3), padding='same', activation='relu'))
model.add(BatchNormalization()) # BatchNormalization after convolutional layer
model.add(MaxPooling2D((2, 2))) # MaxPooling2D to keep important features as well as shirnk info size
model.add(Dropout(0.1)) # Drop some portion of nodes to increase generality of model
# Second VGG blockes
model.add(Conv2D(32, (3, 3), padding='same', activation='relu'))
model.add(BatchNormalization())
model.add(Conv2D(32, (3, 3), padding='same', activation='relu'))
model.add(BatchNormalization())
model.add(MaxPooling2D((2, 2)))
model.add(Dropout(0.2))
# Third VGG blockes
model.add(Conv2D(64, (3, 3), padding='same', activation='relu'))
model.add(BatchNormalization())
model.add(Conv2D(64, (3, 3), padding='same', activation='relu'))
model.add(BatchNormalization())
model.add(MaxPooling2D((2, 2)))
model.add(Dropout(0.3))
# Fourth VGG blockes
model.add(Conv2D(128, (3, 3), padding='same', activation='relu'))
model.add(BatchNormalization())
model.add(Conv2D(128, (3, 3), padding='same', activation='relu'))
model.add(BatchNormalization())
model.add(MaxPooling2D((2, 2)))
model.add(Dropout(0.4))
# Flat and dense layer
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
# Final softmax layer
model.add(Dense(num_classes, activation='softmax'))
# The optimizer gives the learning rate lr and some other parameters.
opt = Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=None, decay=0.0, amsgrad=False)
# Model complie
model.compile(loss='categorical_crossentropy',
optimizer=opt,
metrics=['accuracy'])
And while I am training this model:
#Train model
epochs = 100
batch_size = 128
# create data generator
datagen = ImageDataGenerator(horizontal_flip=True,
width_shift_range=5,
height_shift_range=5,
rotation_range=20)
history = model.fit(datagen.flow(x_training, y_training, batch_size=batch_size),
epochs=epochs,
validation_data=(x_validate, y_validate),
verbose=1,
shuffle=True)
The RAM of my computer keeps grow until the training process crashes. Adding python garbage collector for at end of each epoch did not work. Disabling eager detection did not work.
I using
tensorflow-gpu 2.4.0
CUDA 11.0
cuDNN 8.0
i'm trying to make a simple classification model for the cifar-10 dataset. The model fails when it gets to Maxpooling fuction. It says that it has the incorrect Syntax but for the life of me i cannot figure out whats wrong.
Is it the version of keras i'm using? when i add maxpooling to the model with a size of 2, 2 it don't work and in the documentation, i am doing the exact same thing which makes me think its a version problem.
Sorry if the problem is obvious
model = Sequential()
model.add(Conv2D(32, (3,3), padding = 'same', input_shape=(32,32,3)))
model.add(Activation('relu')
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(512))
model.add(Activation('relu')
model.add(Dropout(0.5))
model.add(Dense(10))
model.add(Activation('softmax'))
model.summary()
Max pooling does not have any issue.your issue is you are missing some brackets in the previous line. find below the corrected code
model = Sequential()
model.add(Conv2D(32, (3,3), padding = 'same', input_shape=(32,32,3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(10))
model.add(Activation('softmax'))
model.summary()
Hope this helps.
I've used Floyd hub to to train the following model and saved it
# Create the model
model = Sequential()
model.add(Conv2D(32, (3, 3), input_shape=(3, 32, 32), activation='relu', padding='same'))
model.add(Dropout(0.2))
model.add(Conv2D(32, (3, 3), activation='relu', padding='same'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(64, (3, 3), activation='relu', padding='same'))
model.add(Dropout(0.2))
model.add(Conv2D(64, (3, 3), activation='relu', padding='same'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(128, (3, 3), activation='relu', padding='same'))
model.add(Dropout(0.2))
model.add(Conv2D(128, (3, 3), activation='relu', padding='same'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dropout(0.2))
model.add(Dense(1024, activation='relu', kernel_constraint=maxnorm(3)))
model.add(Dropout(0.2))
model.add(Dense(512, activation='relu', kernel_constraint=maxnorm(3)))
model.add(Dropout(0.2))
model.add(Dense(num_classes, activation='softmax'))
# Compile model
epochs = 50
adammax = keras.optimizers.Adamax(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.0)
model.compile(loss='categorical_crossentropy', optimizer=adammax, metrics=['accuracy'])
print(model.summary())
When I try to load it on my PC, it's working fine. But when I load it on the Raspberry Pi I get the following error. I tried also to save just the weights and load them, but it didn't work and I got the same error. I am using the same version of Tensorflow as Floyd hub on the Raspberry Pi.
As mentioned above, you're passing T=DT_INT64, while that is not one of the supported kernels for this op. You could see if the int64 version is just not shipped in the .so file, write the op kernel yourself, or try casting to tf.int32 right before this op in the python code. The last one worked well for me.
I want to create VGG model with Keras.
However, following error was displayed:
expected lstm_input_2 to have 4 dimensions, but got array with shape
(60000, 10)
I created the following sequential model:
model = Sequential()
model.add(Conv2D(16, kernel_size=(3, 3),
padding='same',
input_shape=input_shape))
model.add(Activation('relu'))
model.add(Conv2D(16, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(32, (3, 3), padding='same', activation='relu'))
model.add(Conv2D(32, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(64, (3, 3), padding='same', activation='relu'))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dense(50, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes))
model.add(Dropout(0.5))
model.add(Activation('softmax'))
Please tell me why this error created.
You just need to add a Flatten layer like so:
…
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten()) # <-- this layer is missing in your code
model.add(Dense(50, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes))
model.add(Dropout(0.5))
model.add(Activation('softmax'))
…
This transforms your last 2d layer (MaxPooling2D) to a 1-dimensional shape that you than can feed into your Dense layer.