2017-07-28 83 views
5

我想用Keras CNN構建一個二元分類器。 我有大約6000行的輸入數據,看起來像這樣:爲什麼二進制Keras CNN總是預測1?

>> 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] 

然後,我已經通過這種方式建立一個CNN:

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) 

但它返回下列信息:

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

爲什麼所有的預測都是?爲什麼CNN表現如此糟糕? 這裏是損失和acc圖表: enter image description here

+1

約2/3的時間是正確的;我看到輸入數據接近常數-1.06。如果這適用於所有數據,那麼它可能只是因爲它不能分割輸入空間並優化哪個類最多,因爲這是最好的選擇(儘管我認爲你的標準化調用可能會解決這個問題)。我無法驗證,沒有一個工作的例子。 < - 這就是說,這種行爲的一個非常普遍的原因是學習率的問題,你可以嘗試有力地提高學習率嗎? – Uvar

+0

乾杯!我試着將學習率從0.001改爲0.1,但我得到了相同的輸出。 :(還有其他想法嗎? – harrison4

回答

7

它總是預測因爲您的網絡輸出。你有一個密集的層與一個神經元,與Softmax激活。 Softmax通過每個輸出的指數之和進行歸一化。由於有一個輸出,唯一可能的輸出是1.0。

對於二元分類器,您可以使用帶有「binary_crossentropy」損失的sigmoid激活,或在最後一層放置兩個輸出單位,繼續使用softmax並將損失更改爲categorical_crossentropy。

+0

謝謝!像魅力一樣工作!:) sigmoid + binary和softmax + categorical之間有什麼區別嗎? – harrison4

+1

@ harrison4理論上它們是相同的,但實際上存在差異,至少我做過的一些測試顯示softmax是優越的。 –

+0

從記錄上來看,在我的測試中,用略深的建築,我有: 乙狀結腸+ 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執行一點(不是很少在rmse)更好。 – bio