Keras always predict the conclusion of the same value in multi-classification

here is my code. I want to do multi-classification with Keras. vcl_acc trains better, but the forecast value is always the same. I'm confused, please help me

train.py

# coding: UTF-8 # author: Sun Yongke ( sunyongke@gmail.com ) from keras.preprocessing.image import ImageDataGenerator from keras.callbacks import EarlyStopping from keras.models import Sequential from keras.layers import Dense, Dropout, Activation, Flatten from keras.layers import Convolution2D, MaxPooling2D from keras.optimizers import SGD # Dense(64) is a fully-connected layer with 64 hidden units. # in the first layer, you must specify the expected input data shape: # here, 20-dimensional vectors. # dimensions of our images. img_width, img_height = 300, 300 nb_epoch=20 train_data_dir = '../picture/samples_300_2/train' validation_data_dir = '../picture/samples_300_2/validation' # this is the augmentation configuration we will use for training train_datagen = ImageDataGenerator( rescale=1./255, shear_range=0.2, zoom_range=0.2, horizontal_flip=True) # this is the augmentation configuration we will use for testing: # only rescaling test_datagen = ImageDataGenerator(rescale=1./255) train_generator = train_datagen.flow_from_directory( train_data_dir, target_size=(img_width, img_height), batch_size=40000, color_mode='grayscale', save_format="jpg", save_to_dir="after/train", class_mode='categorical') validation_generator = test_datagen.flow_from_directory( validation_data_dir, target_size=(img_width, img_height), batch_size=500, color_mode='grayscale', save_format="jpg", save_to_dir="after/test", class_mode='categorical') model = Sequential() # input: 100x100 images with 3 channels -> (3, 100, 100) tensors. # this applies 32 convolution filters of size 3x3 each. model.add(Convolution2D(32, 3, 3, border_mode='valid', input_shape=(img_width, img_height,1))) model.add(Activation('relu')) model.add(Convolution2D(32, 3, 3)) model.add(Activation('relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Dropout(0.25)) model.add(Convolution2D(64, 3, 3, border_mode='valid')) model.add(Activation('relu')) model.add(Convolution2D(64, 3, 3)) model.add(Activation('relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Dropout(0.25)) model.add(Flatten()) # Note: Keras does automatic shape inference. model.add(Dense(256)) model.add(Activation('relu')) model.add(Dropout(0.5)) model.add(Dense(14)) model.add(Activation('softmax')) sgd = SGD(lr=0.1, decay=1e-6, momentum=0.9, nesterov=True) model.compile(loss='categorical_crossentropy', optimizer=sgd) nb_train_samples=len(train_generator.filenames) nb_validation_samples=len(validation_generator.filenames) early_stopping = EarlyStopping(monitor='val_loss', patience=2) model.fit_generator( train_generator, samples_per_epoch=nb_train_samples, nb_epoch=nb_epoch, validation_data=validation_generator, nb_val_samples=nb_validation_samples, callbacks=[early_stopping]) #save model model.save("sykm.2.h5") 

learning outcome following

 Epoch 2/50 3005/3005 [==============================] - 270s - loss: 0.2227 - acc: 0.9294 - val_loss: 0.1985 - val_acc: 0.9316 Epoch 3/50 3005/3005 [==============================] - 269s - loss: 0.2105 - acc: 0.9310 - val_loss: 0.1858 - val_acc: 0.9338 Epoch 4/50 3005/3005 [==============================] - 271s - loss: 0.1964 - acc: 0.9333 - val_loss: 0.3572 - val_acc: 0.9160 Epoch 5/50 3005/3005 [==============================] - 268s - loss: 0.1881 - acc: 0.9349 - val_loss: 0.1513 - val_acc: 0.9413 Epoch 6/50 3005/3005 [==============================] - 268s - loss: 0.1935 - acc: 0.9342 - val_loss: 0.1581 - val_acc: 0.936 

predict.py

 # coding: UTF-8 # author: Sun Yongke ( sunyongke@gmail.com ) from keras.models import load_model model = load_model('sykm.2.h5') img_width, img_height = 300, 300 from keras.preprocessing.image import ImageDataGenerator test_datagen = ImageDataGenerator(rescale=1./255) validation_data_dir = 'samples_300/validation' validation_generator = test_datagen.flow_from_directory( validation_data_dir, target_size=(img_width, img_height), batch_size=32, class_mode='categorical') nb_validation_samples=len(validation_generator.filenames) out=model.predict_generator(validation_generator,nb_validation_samples) print "out" print out 

the output is always the same, even I use a different image for verification, following

 Using TensorFlow backend. Found 60 images belonging to 2 classes. out [[ 0.06170857 0.06522226 0.06400252 0.08250671 0.07548683 0.07643672 0.07131153 0.07487586 0.07607967 0.04719007 0.07641899 0.08824327 0.05421595 0.08630092] [ 0.06170857 0.06522226 0.06400252 0.08250671 0.07548683 0.07643672 0.07131153 0.07487586 0.07607967 0.04719007 0.07641899 0.08824327 0.05421595 0.08630092] ....] 
+6
source share
2 answers

It seems that your problem is caused by a huge class imbalance in your dataset. You can see that assigning class 0 for each example gives you more than 90% accuracy. To deal with this, you can use the following strategies:

  • Rebalance your dataset: either by upsampling a less frequent class, or downsampling a more frequent class.

  • Adjust class weights: by setting a higher weight class for less frequent activities. You will be promoting your online training to focus more on the downsampling class.

  • Increase the learning time: in many cases - after a long period of training, the network begins to concentrate more on less frequent classes.
+6
source

So, after 1 month of finding a solution, I tried everything: lower the learning speed, change the optimizer, use a larger data set, increase and decrease the complexity of the model, change the input form to smaller and larger images, change the import from keras import to from tensorflow.keras import and further from tensorflow.python.keras import , changing the activation function of each layer, combining them, trying other data sets, etc. Nothing helped. Even if I used a network like VGG16 / 19, my results would be the same. But yesterday I read a book (deep learning with Keras - Antonio Gulli, Sujit Pal) and realized that the authors use import as follows:

 from keras.layers.core import Dense, Flatten, Dropout 

and not so

 from keras.layers import Dense, Flatten, Dropout 

same for Conv, I used:

 from keras.layers import Conv2D, MaxPooling2D, SeparableConv2D 

and the authors use:

 from keras.layers.convolutional import Conv2D, MaxPooling2D, SeparableConv2D 

And when I changed the import, it finally worked! I don’t know if this is a mistake or something like this, because now my models always work even in datasets that predicted the same class. So now I use imports like this, for example:

 from keras.layers.core import Dense, Dropout, Flatten from keras.layers.convolutional import Conv2D, MaxPooling2D, SeparableConv2D 

Try this if it doesn’t work, see if your dataset is balanced, for example, if you have a problem with the classification of images of cats and dogs, and you have 200 images of cats and 800 images of dogs, try using several images that are not so different because this can cause problems: your model can “think” well if I say that 10/10 images are dogs, so I get 80% accuracy, but that’s not what we want. You can use class_weight if you have no more images to balance your data set and everything will be fine, you can also use data increase. You can also use callbacks such as ReduceLROnPlateau which slow down your learning speed when your loss does not get lower. You can increase your batch_size , do not forget to shuffle the data in ImageDataGenerator and normalize your images, for example like this:

 g2 = ImageDataGenerator(rescale=1./255) 

All these things are very important, but nothing helped me. The only thing that worked was importing keras.layers.core and keras.layers.convolutional , maybe this will help you too!

0
source

Source: https://habr.com/ru/post/1263403/


All Articles