2017-07-28 88 views
5

Keras CNN kullanarak bir ikili sınıflandırıcı oluşturmak istiyorum. Şöyle giriş verilerinin yaklaşık 6000 satır var:Neden bir ikili Keras CNN her zaman 1 öngörüyor?

>> print(X_train[0]) 
[[[-1.06405307 -1.06685851 -1.05989663 -1.06273152] 
    [-1.06295958 -1.06655996 -1.05969803 -1.06382503] 
    [-1.06415248 -1.06735609 -1.05999593 -1.06302975] 
    [-1.06295958 -1.06755513 -1.05949944 -1.06362621] 
    [-1.06355603 -1.06636092 -1.05959873 -1.06173742] 
    [-1.0619655 -1.06655996 -1.06039312 -1.06412326] 
    [-1.06415248 -1.06725658 -1.05940014 -1.06322857] 
    [-1.06345662 -1.06377347 -1.05890365 -1.06034568] 
    [-1.06027557 -1.06019084 -1.05592469 -1.05537518] 
    [-1.05550398 -1.06038988 -1.05225064 -1.05676692]]] 
>>> print(y_train[0]) 
[1] 

Sonra bu arada bir CNN inşa ettik:

model = Sequential() 
model.add(Convolution1D(input_shape = (10, 4), 
         nb_filter=16, 
         filter_length=4, 
         border_mode='same')) 
model.add(BatchNormalization()) 
model.add(LeakyReLU()) 
model.add(Dropout(0.2)) 

model.add(Convolution1D(nb_filter=8, 
         filter_length=4, 
         border_mode='same')) 
model.add(BatchNormalization()) 
model.add(LeakyReLU()) 
model.add(Dropout(0.2)) 

model.add(Flatten()) 

model.add(Dense(64)) 
model.add(BatchNormalization()) 
model.add(LeakyReLU()) 

model.add(Dense(1)) 
model.add(Activation('softmax')) 

reduce_lr = ReduceLROnPlateau(monitor='val_acc', factor=0.9, patience=30, min_lr=0.000001, verbose=0) 

model.compile(optimizer='adam', 
       loss='binary_crossentropy', 
       metrics=['accuracy']) 

history = model.fit(X_train, y_train, 
      nb_epoch = 100, 
      batch_size = 128, 
      verbose=0, 
      validation_data=(X_test, y_test), 
      callbacks=[reduce_lr], 
      shuffle=True) 

y_pred = model.predict(X_test) 

Ama şu döndürür:

>> print(confusion_matrix(y_test, y_pred)) 
[[ 0 362] 
[ 0 608]] 

Neden tüm tahminler birer? CNN neden bu kadar kötü performans gösteriyor? İşte kayıp ve doğru grafikler: enter image description here

+1

Saatin yaklaşık 2/3'ü doğrudur; ve -1.06 sabit olmaya yakın girdi verilerini görüyorum. Bu, tüm veriler için geçerliyse, giriş alanının bölümlenememesi ve hangi sınıfın en iyi şekilde gerçekleştiğine göre optimize edilmesidir (normalleşme çağrınızın bunu çözebileceğini düşünmeme rağmen). Çalışan bir örnek olmadan doğrulayamıyorum. <- Bu davranış için çok yaygın bir neden, öğrenme oranı ile ilgili bir sorundur, öğrenme oranını kuvvetlice artırmaya çalışabilir misiniz? – Uvar

+0

Şerefe! Öğrenme oranlarını 0,001'den 0,1'e değiştirmeyi denedim, ama aynı çıktıyı elde ediyorum. :(Başka bir fikrin var mı? – harrison4

cevap

7

Ağınızdaki çıktı nedeniyle her zaman bir tane tahmin eder. Bir Softmax etkinleştirme ile bir nöron ile yoğun bir katman var. Softmax, her bir çıktının üstelinin toplamı ile normalleşir. Tek bir çıkış olduğundan, olası tek çıktı 1.0'dır.

İkili bir sınıflandırıcı için "binary_crossentropy" kaybıyla bir sigmoid aktivasyonu kullanabilir veya son katmana iki çıkış birimi yerleştirebilir, softmax kullanmaya devam edebilir ve kaybı categorical_crossentropy olarak değiştirebilirsiniz.

+0

Teşekkürler! Bir çekicilik gibi çalışır! :) sigmoid + binary ve softmax + kategorik arasında bir fark var mı? – harrison4

+1

@ harrison4 Teoride bunlar aynıdır ancak uygulamada farklılıklar vardır, en azından bazı testlerim softmax'ın daha üstün olduğunu gösterdi. Sadece kayıtlar için –

+0

, benim testinde, biraz daha derin bir mimari ile, var: sigmoid + binary_crossentropy: 'val_acc = 0.9422' ' val_loss = 0.16' 'val_rmse = 0.0909' SoftMax + sparse_categorical_crossentropy: ' val_acc = 0.9409' 'val_loss = 0.1725' ' val_rmse = 0,68' Sigmoid biraz daha iyi (rmse'de değil) biraz daha iyi performans gösteriyor. – bio