Validierungsverlust und Genauigkeit bleiben konstant

12

Ich versuche, dieses Papier auf einer Reihe von medizinischen Bildern umzusetzen . Ich mache es in Keras. Das Netzwerk besteht im Wesentlichen aus 4 Conv- und Max-Pool-Schichten, gefolgt von einer vollständig verbundenen Schicht und einem Soft-Max-Klassifikator.

Soweit ich weiß, bin ich der in der Zeitung erwähnten Architektur gefolgt. Der Validierungsverlust und die Genauigkeit bleiben jedoch durchgehend unverändert. Die Genauigkeit scheint auf ~ 57,5% festgelegt zu sein.

Jede Hilfe, wo ich falsch liegen könnte, wäre sehr dankbar.

Mein Code:

from keras.models import Sequential
from keras.layers import Activation, Dropout, Dense, Flatten  
from keras.layers import Convolution2D, MaxPooling2D
from keras.optimizers import SGD
from keras.utils import np_utils
from PIL import Image
import numpy as np
from sklearn.utils import shuffle
from sklearn.cross_validation import train_test_split
import theano
import os
import glob as glob
import cv2
from matplotlib import pyplot as plt

nb_classes = 2
img_rows, img_cols = 100,100
img_channels = 3


#################### DATA DIRECTORY SETTING######################

data = '/home/raghuram/Desktop/data'
os.chdir(data)
file_list = os.listdir(data)
##################################################################

## Test lines
#I = cv2.imread(file_list[1000])
#print np.shape(I)
####
non_responder_file_list = glob.glob('0_*FLAIR_*.png')
responder_file_list = glob.glob('1_*FLAIR_*.png')
print len(non_responder_file_list),len(responder_file_list)

labels = np.ones((len(file_list)),dtype = int)
labels[0:len(non_responder_file_list)] = 0
immatrix = np.array([np.array(cv2.imread(data+'/'+image)).flatten() for image in file_list])
#img = immatrix[1000].reshape(100,100,3)
#plt.imshow(img,cmap = 'gray')


data,Label = shuffle(immatrix,labels, random_state=2)
train_data = [data,Label]
X,y = (train_data[0],train_data[1])
# Also need to look at how to preserve spatial extent in the conv network
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=4)
X_train = X_train.reshape(X_train.shape[0], 3, img_rows, img_cols)
X_test = X_test.reshape(X_test.shape[0], 3, img_rows, img_cols)
X_train = X_train.astype('float32')
X_test = X_test.astype('float32')

X_train /= 255
X_test /= 255

Y_train = np_utils.to_categorical(y_train, nb_classes)
Y_test = np_utils.to_categorical(y_test, nb_classes)

model = Sequential()

## First conv layer and its activation followed by the max-pool layer#
model.add(Convolution2D(16,5,5, border_mode = 'valid', subsample = (1,1), init = 'glorot_normal',input_shape = (3,100,100))) # Glorot normal is similar to Xavier initialization
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size = (2,2),strides = None))
# Output is 48x48

print 'First layer setup'
###########################Second conv layer#################################
model.add(Convolution2D(32,3,3,border_mode = 'same', subsample = (1,1),init = 'glorot_normal'))
model.add(Activation('relu'))
model.add(Dropout(0.6))
model.add(MaxPooling2D(pool_size = (2,2),strides = None))
#############################################################################

print ' Second layer setup'
# Output is 2x24

##########################Third conv layer###################################
model.add(Convolution2D(64,3,3, border_mode = 'same', subsample = (1,1), init = 'glorot_normal'))
model.add(Activation('relu'))
model.add(Dropout(0.6))
model.add(MaxPooling2D(pool_size = (2,2),strides = None))
#############################################################################
# Output is 12x12

print ' Third layer setup'
###############################Fourth conv layer#############################
model.add(Convolution2D(128,3,3, border_mode = 'same', subsample = (1,1), init = 'glorot_normal'))
model.add(Activation('relu'))
model.add(Dropout(0.6))
model.add(MaxPooling2D(pool_size = (2,2),strides = None))
############################################################################# 

print 'Fourth layer setup'

# Output is 6x6x128
# Create the FC layer of size 128x6x6#
model.add(Flatten()) 
model.add(Dense(2,init = 'glorot_normal',input_dim = 128*6*6))
model.add(Dropout(0.6))
model.add(Activation('softmax'))

print 'Setting up fully connected layer'
print 'Now compiling the network'
sgd = SGD(lr=0.01, decay=1e-4, momentum=0.6, nesterov=True)
model.compile(loss = 'mse',optimizer = 'sgd', metrics=['accuracy'])

# Fit the network to the data#
print 'Network setup successfully. Now fitting the network to the data'
model. fit(X_train,Y_train,batch_size = 100, nb_epoch = 20, validation_split = None,verbose = 1)
print 'Testing'
loss,accuracy = model.evaluate(X_test,Y_test,batch_size = 32,verbose = 1)
print "Test fraction correct (Accuracy) = {:.2f}".format(accuracy)
Raghuram
quelle
Geht der Trainingsverlust zurück?
Jan van der Vegt
Nein, der Trainingsverlust bleibt auch durchgehend konstant.
Raghuram
Sie haben in Ihrem Fit-Aufruf keine Validierungsdaten oder validation_split festgelegt. Worauf würde es validieren? Oder meintest du Test?
Jan van der Vegt
Das ist nach dem Experimentieren. Ich habe validation_split = 0.2 gesetzt, bevor ich es auf None gesetzt habe, und auch damit experimentiert.
Raghuram
2
Können Sie häufig eine Charge einsetzen, um festzustellen, ob der Trainingsverlust geringer sein kann?
Jan van der Vegt

Antworten:

4

Es scheint, dass Sie MSE als Verlustfunktion verwenden. Nach einem Blick auf das Papier scheint es, dass sie NLL (Cross Entropy) verwenden. MSE ist unter anderem anfällig für Datenungleichgewichte und kann die Ursache für das Problem sein, das Sie haben Erfahrungsgemäß würde ich in Ihrem Fall versuchen, mit kategorialem Kreuzentropieverlust zu trainieren. Außerdem scheint die Lernrate von 0,01 zu groß zu sein. Ich würde versuchen, damit zu spielen und 0,001 oder sogar 0,0001 zu versuchen

koltun
quelle
2

Obwohl ich hier etwas spät dran bin, möchte ich meine zwei Cent einsetzen, da es mir kürzlich geholfen hat, ein ähnliches Problem zu lösen. Was mir zu Hilfe kam, war die Skalierung der Merkmale in den Bereich (0,1) neben dem kategorialen Kreuzentropieverlust. Es ist jedoch anzumerken, dass die Merkmalsskalierung nur dann hilfreich ist, wenn die Merkmale zu unterschiedlichen Metriken gehören und viel mehr Variationen (in Größenordnungen) relativ zueinander aufweisen, wie dies in meinem Fall der Fall war. Eine Skalierung kann auch sehr nützlich sein, wenn man den hingeVerlust verwendet, da Klassifizierer mit maximaler Marge im Allgemeinen empfindlich auf die Abstände zwischen Merkmalswerten reagieren. Hoffe das hilft einigen zukünftigen Besuchern!

Saurav--
quelle