Что я делаю, чтобы улучшить мою модель Keras CNN VGG16 - PullRequest
3 голосов
/ 27 сентября 2019

Я работаю в проекте, который имеет 700 изображений для 2 классов (всего 1400).Я использую VGG16, но я новичок в этой модели, и я не знаю, что я могу сделать, чтобы улучшить эту модель ..

Это моя модель:

vgg16_model = VGG16(weights="imagenet", include_top=True)

# (1) visualize layers
print("VGG16 model layers")
for i, layer in enumerate(vgg16_model.layers):
    print(i, layer.name, layer.output_shape)

# (2) remove the top layer
base_model = Model(input=vgg16_model.input, 
                   output=vgg16_model.get_layer("block5_pool").output)

# (3) attach a new top layer
base_out = base_model.output
base_out = Reshape((25088,))(base_out)
top_fc1 = Dense(256, activation="relu")(base_out)
top_fc1 = Dropout(0.5)(top_fc1)
# output layer: (None, 5)
top_preds = Dense(1, activation="sigmoid")(top_fc1)

# (4) freeze weights until the last but one convolution layer (block4_pool)
for layer in base_model.layers[0:14]:
    layer.trainable = False

# (5) create new hybrid model
model = Model(input=base_model.input, output=top_preds)

# (6) compile and train the model
sgd = SGD(lr=1e-4, momentum=0.9)
model.compile(optimizer=sgd, loss="binary_crossentropy", metrics=["accuracy"])

history = model.fit([data], [labels], nb_epoch=NUM_EPOCHS, 
                    batch_size=BATCH_SIZE, validation_split=0.1)

# evaluate final model
vlabels = model.predict(np.array(valid))

model.save('model.h5')

... это дает мне следующее возвращение:

Train on 1260 samples, validate on 140 samples
Epoch 1/5
1260/1260 [==============================] - 437s 347ms/step - loss: 0.2200 - acc: 0.9746 - val_loss: 2.4432e-05 - val_acc: 1.0000
Epoch 2/5
1260/1260 [==============================] - 456s 362ms/step - loss: 0.0090 - acc: 0.9984 - val_loss: 1.5452e-04 - val_acc: 1.0000
Epoch 3/5
1260/1260 [==============================] - 438s 347ms/step - loss: 1.3702e-07 - acc: 1.0000 - val_loss: 8.4489e-05 - val_acc: 1.0000
Epoch 4/5
1260/1260 [==============================] - 446s 354ms/step - loss: 4.2592e-06 - acc: 1.0000 - val_loss: 7.6768e-05 - val_acc: 1.0000
Epoch 5/5
1260/1260 [==============================] - 457s 363ms/step - loss: 0.0017 - acc: 0.9992 - val_loss: 1.1921e-07 - val_acc: 1.0000

Кажется, это немного переобучает ..

Мой предсказание.py:

def fix_layer0(filename, batch_input_shape, dtype):
    with h5py.File(filename, 'r+') as f:
        model_config = json.loads(f.attrs['model_config'].decode('utf-8'))
        layer0 = model_config['config']['layers'][0]['config']
        layer0['batch_input_shape'] = batch_input_shape
        layer0['dtype'] = dtype
        f.attrs['model_config'] = json.dumps(model_config).encode('utf-8')

fix_layer0('model.h5', [None, 224, 224, 3], 'float32')

model = load_model('model.h5')

for filename in os.listdir(r'v/'):
    if filename.endswith(".jpg") or filename.endswith(".ppm") or filename.endswith(".jpeg") or filename.endswith(".png"):
        ImageCV = cv2.resize(cv2.imread(os.path.join(TEST_DIR) + filename), (224,224))
        ImageCV = cv2.addWeighted(ImageCV,4, cv2.GaussianBlur(ImageCV,(0,0), 224/25), -4, 120) #The same process made when I get data in train
        ImageCV = ImageCV.reshape(-1,224,224,3)
        print(model.predict(ImageCV))

И результатыстранно, потому что только 2 первых изображения относятся к «классу 0» .. остальные относятся к «классу 1»:

[[0.99905235]]
[[0.]]
[[1.]]
[[0.012198]]
[[0.]]
[[1.]]
[[1.6363418e-07]]
[[0.99997246]]
[[0.00433112]]
[[0.9996668]]
[[1.]]
[[6.183685e-08]]

Что я могу сделать, чтобы улучшить его?Я немного растерялся ..

Ответы [ 2 ]

2 голосов
/ 27 сентября 2019
ImageCV = cv2.addWeighted(ImageCV,4, cv2.GaussianBlur(ImageCV,(0,0),
                          224/25), -4, 120)

Не уверен, почему вы делаете это для тестовых данных.Для данных проверки / тестирования обычно выполняется только нормализация.Также во время обучения вам необходимо применить ту же нормализацию, что и на последнем этапе, перед подачей данных в сеть.

См. Этот пример для тонкой настройки VGG16 для задачи двух классов (собаки против кошек) https://gist.github.com/fchollet/7eb39b44eb9e16e59632d25fb3119975

https://blog.keras.io/building-powerful-image-classification-models-using-very-little-data.html

Чтобы уменьшить переоснащение, вы можете выполнить увеличение данных для обучающих данных, то есть подать исходные данные и дополненные данные (применять операции, такие как переворачивание, масштабирование и т. Д.).Keras ImageDataGenerator s позволяет легко делать дополнения.Также рассматривается в приведенном выше руководстве.

https://keras.io/preprocessing/image/

1 голос
/ 27 сентября 2019

Прежде всего, Keras predict вернет баллы регрессии (вероятности для каждого класса), а предикаты_классов вернут наиболее вероятный класс вашего прогноза.Например, если вы классифицируете кошек и собак, predict может вывести 0,2 для кошки и 0,8 для собаки.Поэтому, если вы используете predict, для каждого класса должно быть два значения, по одному для каждого класса.

Причина, по которой у вас есть только одно значение, заключается в том, что в вашей сети есть только один выходной нейрон.Должно быть два, так как есть два класса.

top_preds = Dense(2, activation="sigmoid")(top_fc1)

Если вы хотите увидеть наиболее вероятный класс, а не вероятности, вы должны использовать predict_classes.

...