2017-12-13 9 views
0

Ich baue ein Keras CNN-Modell mit ResNet50 unter Verwendung von Transfer Lernen. Aus irgendeinem Grund sind meine Genauigkeit und mein Verlust für jede Epoche genau gleich. Seltsamerweise sehe ich das gleiche Verhalten mit ähnlichem Code, aber mit VGG19. Dies führt mich zu der Annahme, dass das Problem nicht mit dem tatsächlichen Modellcode und irgendwo in der Vorverarbeitung zusammenhängt. Ich habe versucht, Lernraten anzupassen, Optimierer, Bildauflösung, Einfrieren von Ebenen usw. zu ändern und die Punktzahlen ändern sich nicht. Ich ging in meine Bildverzeichnisse, um zu prüfen, ob meine zwei verschiedenen Klassen gemischt sind, und das sind sie nicht. Was ist das Problem? Ich möchte nur im Voraus Danke sagen.Keras CNN Genauigkeit und Verlust sind konstant

P.S. Ich trainiere auf ~ 2000 Bildern und habe zwei Klassen.

import numpy as np 
import pandas as pd 

import tensorflow as tf 
from keras.preprocessing.image import ImageDataGenerator 
from keras.callbacks import ModelCheckpoint, ReduceLROnPlateau 
from keras.models import Sequential, Model, load_model 
from keras.layers import Conv2D, GlobalAveragePooling2D 
from keras.layers import Activation, Dropout, Flatten, Dense 
from keras import applications 
from keras import optimizers 

img_height, img_width, img_channel = 400, 400, 3 #change chanel to 1 instead of three since it is black and white 

base_model = applications.ResNet50(weights='imagenet', include_top=False, input_shape=(img_height, img_width, img_channel)) 

# add a global spatial average pooling layer 
x = base_model.output 
x = GlobalAveragePooling2D()(x) 
# let's add a fully-connected layer 
x = Dense(512, activation='relu',name='fc-1')(x) 
#x = Dropout(0.5)(x) 
x = Dense(256, activation='relu',name='fc-2')(x) 
#x = Dropout(0.5)(x) 
# and a logistic layer -- let's say we have 2 classes 
predictions = Dense(1, activation='softmax', name='output_layer')(x) 

model = Model(inputs=base_model.input, outputs=predictions) 
model.compile(loss='binary_crossentropy', optimizer=optimizers.SGD(lr=0.1), 
       metrics=['accuracy']) 

model.summary() 

from keras.preprocessing.image import ImageDataGenerator 
from keras.callbacks import ModelCheckpoint 

batch_size = 6 

# prepare data augmentation configuration 
train_datagen = ImageDataGenerator(
     rescale=1./255, 
     rotation_range=20, 
     width_shift_range=0.1, 
     height_shift_range=0.1, 
     shear_range=0.1, 
     zoom_range=0.1, 
     horizontal_flip=True, 
     vertical_flip=True) 


test_datagen = ImageDataGenerator(rescale=1./255) 

#possibely resize the image 
train_generator = train_datagen.flow_from_directory(
     "../Train/", 
     target_size=(img_height, img_width), 
     batch_size=batch_size, 
     class_mode='binary', 
     shuffle=True 
) 

validation_generator = test_datagen.flow_from_directory(
     "../Test/", 
     target_size=(img_height, img_width), 
     batch_size=batch_size, 
     class_mode='binary', 
     shuffle=True) 

epochs = 10 

history = model.fit_generator(
     train_generator, 
     steps_per_epoch=2046 // batch_size, 
     epochs=epochs, 
     validation_data=validation_generator, 
     validation_steps=512 // batch_size, 
     callbacks=[ModelCheckpoint('snapshots/ResNet50-transferlearning.model', monitor='val_acc', save_best_only=True)]) 

Dies ist die Ausgabe von Keras gegeben:

Epoch 1/10 
341/341 [==============================] - 59s 172ms/step - loss: 7.0517 - acc: 0.5577 - val_loss: 7.0334 - val_acc: 0.5588 
Epoch 2/10 
341/341 [==============================] - 57s 168ms/step - loss: 7.0517 - acc: 0.5577 - val_loss: 7.0334 - val_acc: 0.5588 
Epoch 3/10 
341/341 [==============================] - 56s 165ms/step - loss: 7.0517 - acc: 0.5577 - val_loss: 7.0334 - val_acc: 0.5588 
Epoch 4/10 
341/341 [==============================] - 57s 168ms/step - loss: 7.0517 - acc: 0.5577 - val_loss: 7.0334 - val_acc: 0.5588 
Epoch 5/10 
341/341 [==============================] - 57s 167ms/step - loss: 7.0517 - acc: 0.5577 - val_loss: 7.0334 - val_acc: 0.5588 

Antwort

0

Die letzte Schicht eine ‚Sigmoid‘ Aktivierung statt softmax haben sollte, da es binäre Klassifizierung ist.

+0

Ihre letzte dichte Schicht sollte eine Einheit pro Klasse, so die Prognosen = Dense (** 2 **, Aktivierung = 'softmax' name = 'output_layer') (x). Die Aktivierung der Funktion "softmax" ist auch für die binäre Klassifizierung in Ordnung. – Toyo

0
predictions = Dense(1, activation='softmax', name='output_layer')(x) 

Die dichte Schicht repräsentiert, wie viele verschiedene Klassen gibt es, die Sie und damit auch für binäre Klassifikation klassifizieren wollen, erhalten Sie 2 benötigen, wo Sie diese Zeile So 1.

ändern geschrieben haben.

predictions = Dense(2, activation='softmax', name='output_layer')(x) 

Nur eine Notiz, versucht immer, eine Variable zu halte Anzahl der Klassen zu handhaben, so etwas wie

predictions = Dense(num_classes, activation='softmax', name='output_layer')(x) 

und dann num_classes für bessere Flexibilität und Lesbarkeit zu Beginn des Codes definieren.

Sie können Dokumentation über dichte Schicht hier überprüfen: https://faroit.github.io/keras-docs/2.0.0/layers/core/

Verwandte Themen