#keras #deep-learning #classification #conv-neural-network #multiclass-classification
#keras #глубокое обучение #классификация #conv-нейронная сеть #мультиклассовая классификация
Вопрос:
Я пытаюсь классифицировать изображения, принадлежащие к 16 классам. Изображения имеют разные геометрические формы (см. рис. 2). Обучающий набор состоит из 16 x 320 = 5120 изображений, набор для проверки содержит 16 x 160 = 2560 изображений, а тестовый набор содержит 16 x 2 = 32 изображения.
Я использую приведенный ниже код для построения CNN и выполнения прогнозов.
import numpy as np
np.random.seed(0)
import keras
from keras.models import Sequential,Input,Model
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras.layers.normalization import BatchNormalization
from keras.layers.advanced_activations import LeakyReLU
from keras import regularizers
from keras.layers import Activation
num_classes = 16
classifier = Sequential()
classifier.add(Conv2D(32, kernel_size=(3, 3),activation='relu',input_shape=(64, 64, 3),padding='same'))
classifier.add(MaxPooling2D((2, 2),padding='same'))
classifier.add(Dropout(0.2))
classifier.add(Conv2D(64, (3, 3), activation='relu',padding='same'))
#classifier.add(LeakyReLU(alpha=0.1))
classifier.add(MaxPooling2D(pool_size=(2, 2),padding='same'))
classifier.add(Dropout(0.2))
classifier.add(Conv2D(64, (3, 3), activation='relu',padding='same'))
classifier.add(MaxPooling2D(pool_size=(2, 2),padding='same'))
classifier.add(Dropout(0.25))
classifier.add(Conv2D(128, (3, 3), activation='relu',padding='same'))
classifier.add(MaxPooling2D(pool_size=(2, 2),padding='same'))
classifier.add(Dropout(0.25))
classifier.add(Flatten())
classifier.add(Dense(128, activation='relu'))
classifier.add(Dropout(0.25))
classifier.add(Dense(num_classes, activation='softmax'))
# Compiling the CNN
classifier.compile(optimizer = 'adam', loss = 'categorical_crossentropy', metrics = ['accuracy'])
from keras.preprocessing.image import ImageDataGenerator
from IPython.display import display
from PIL import Image
train_datagen = ImageDataGenerator(rescale = 1./255,
shear_range = 0.2,
zoom_range = 0.2,
width_shift_range=0.1,
height_shift_range=0.1)
test_datagen = ImageDataGenerator(rescale = 1./255)
training_set = train_datagen.flow_from_directory('dataset/training_set',
target_size = (64, 64),
batch_size = 32,
class_mode = 'categorical')
test_set = test_datagen.flow_from_directory('dataset/test_set',
target_size = (64, 64),
batch_size = 32,
class_mode = 'categorical')
from keras.callbacks import ModelCheckpoint
from keras.callbacks import EarlyStopping
STEP_SIZE_TRAIN = training_set.n//training_set.batch_size
STEP_SIZE_TEST = test_set.n//test_set.batch_size
early_stopping_callback = EarlyStopping(monitor='val_loss', patience=3)
checkpoint_callback = ModelCheckpoint('model' '.h5', monitor='val_loss', verbose=1, save_best_only=True, mode='min')
classifier.fit_generator(training_set,
steps_per_epoch = STEP_SIZE_TRAIN,
epochs = 10,
validation_data = test_set,
validation_steps = STEP_SIZE_TEST,
callbacks=[early_stopping_callback, checkpoint_callback],
workers = 32)
from keras.models import load_model
model = load_model('model.h5')
# Part 3 - making new predictions
import numpy as np
from keras.preprocessing import image
for i in range(1,33):
test_image = image.load_img('dataset/single_prediction/Image ' str(i) '.bmp', target_size = (64, 64))
test_image = image.img_to_array(test_image)
test_image = np.expand_dims(test_image, axis = 0)
#print(model.predict(test_image)[0])
print(model.predict(test_image)[0].argmax() 1)
Я получаю следующий результат для точности обучения и проверки и потери.
Epoch 1/10
160/160 [==============================] - 29s 179ms/step - loss: 1.3693 - acc: 0.5299 - val_loss: 0.1681 - val_acc: 0.9297
Epoch 00001: val_loss improved from inf to 0.16809, saving model to model.h5
Epoch 2/10
160/160 [==============================] - 18s 112ms/step - loss: 0.2668 - acc: 0.8984 - val_loss: 0.0773 - val_acc: 0.9699
Epoch 00002: val_loss improved from 0.16809 to 0.07725, saving model to model.h5
Epoch 3/10
160/160 [==============================] - 18s 111ms/step - loss: 0.1469 - acc: 0.9482 - val_loss: 0.0133 - val_acc: 1.0000
Epoch 00003: val_loss improved from 0.07725 to 0.01327, saving model to model.h5
Epoch 4/10
160/160 [==============================] - 18s 111ms/step - loss: 0.0990 - acc: 0.9650 - val_loss: 0.0147 - val_acc: 1.0000
Epoch 00004: val_loss did not improve from 0.01327
Epoch 5/10
160/160 [==============================] - 18s 113ms/step - loss: 0.0700 - acc: 0.9740 - val_loss: 7.3014e-04 - val_acc: 1.0000
Epoch 00005: val_loss improved from 0.01327 to 0.00073, saving model to model.h5
Epoch 6/10
160/160 [==============================] - 18s 114ms/step - loss: 0.0545 - acc: 0.9809 - val_loss: 0.0012 - val_acc: 1.0000
Epoch 00006: val_loss did not improve from 0.00073
Epoch 7/10
160/160 [==============================] - 18s 111ms/step - loss: 0.0374 - acc: 0.9865 - val_loss: 0.0101 - val_acc: 1.0000
Epoch 00007: val_loss did not improve from 0.00073
Epoch 8/10
160/160 [==============================] - 18s 111ms/step - loss: 0.0489 - acc: 0.9832 - val_loss: 0.0200 - val_acc: 0.9992
При попытке протестировать модель на 32 изображениях тестового набора я получил только 3 правильных прогноза. Итак, мои вопросы:
1) Почему я получаю хорошую точность при проверке, но модели терпят неудачу в наборе тестов?
2) Как я могу отобразить случайную выборку набора проверки (скажем, 10 изображений) с их предсказанными классами, чтобы иметь представление о том, как CNN справляется с набором проверки?
3) Какие-либо общие советы о том, как повысить точность в наборе тестов?
Любая помощь приветствуется! Большое спасибо 🙂
Комментарии:
1. значение acc проверки равно 1 для некоторых эпох. Возможность утечки данных из поезда в действительный.
2. @Sreeram TP : у вас случайно нет идеи о том, как решить эту проблему?
3. 3 набора данных являются независимыми. Я имею в виду, изображения назначаются абсолютно случайным образом каждому из них? Если да, другой возможностью может быть переоснащение набора проверки. Попробуйте использовать очень мало изображений в наборе проверки и посмотрите, как это работает. Затем постепенно увеличивайте его размер и посмотрите, достигнете ли вы точки, в которой точность набора тестов уменьшается, а точность проверки увеличивается. Также вы можете попробовать досрочную остановку.
4. @DavideVisentin: Я использую раннюю остановку в своем коде. Дело в том, что я немного новичок, я не знаю, достаточно ли количества выборок для обучения и проверки. Что вы подразумеваете под «изображения назначаются абсолютно случайным образом каждому из них»? У меня есть три папки, и я помещаю изображения в каждую из них случайным образом. Имеет ли это смысл?
5. Любая помощь со вторым вопросом? Спасибо 🙂
Ответ №1:
Это могло произойти по многим причинам, но я рассмотрю одну из них, которая заключается в различии в распределении данных между вашим составом, наборами проверки и наборами тестов.
В идеальной ситуации у вас должны быть наборы train, validation и test из одного дистрибутива. Хотя это концепция, на практике это может означать не только одинаковое количество точек данных для каждого класса, но и среди многих других измерений. Таким измерением может быть качество изображений для каждого разделения, т. Е. вам следует избегать наличия качественных изображений в вашем наборе поездов и допустимом наборе, в то время как тестовый набор содержит изображения низкого качества. И есть еще много подобных измерений, по которым распределения в идеале должны быть одинаковыми.
Следовательно, это игра на удачу, и вы хотите избежать вероятности того, что из-за невезения и независимо от того, насколько мала вероятность такого события, в конечном итоге получится тестовый набор, который отличается от остальных разделений.
Чтобы преодолеть это:
1) Выберите другое начальное значение при перетасовке данных перед разделением
2) Выберите равный размер разделения для ваших наборов тестов и проверки
3) Используйте k-кратную перекрестную проверку
Вы можете выполнить один или любой из вышеперечисленных шагов отдельно или в комбинации. Подробнее об этом можно прочитать здесь:
https://cs230-stanford.github.io/train-dev-test-split.html
Надеюсь, это поможет