2017-04-01 72 views
1

我目前正在執行一個CNN其目的是進行分類,但由於某種原因,我是不是能夠定義我的輸出尺寸爲1無法設置輸出層分類

下面是一個例子代碼:

import keras 
from keras.layers.merge import Concatenate 
from keras.models import Model 
from keras.layers import Input, Dense 
from keras.layers import Dropout 
from keras.layers.core import Dense, Activation, Lambda, Reshape,Flatten 
from keras.layers import Conv2D, MaxPooling2D, Reshape, ZeroPadding2D 
import numpy as np 

train_data_1 = np.random.randint(100,size=(100,3,6,3)) 
train_data_2 = np.random.randint(100,size=(100,3,6,3)) 
test_data_1 = np.random.randint(100,size=(10,3,6,3)) 
test_data_2 = np.random.randint(100,size=(10,3,6,3)) 
labels_train_data =np.random.randint(145,size=100) 
labels_test_data =np.random.randint(145,size=10) 


input_img_1 = Input(shape=(3, 6, 3)) 
input_img_2 = Input(shape=(3, 6, 3)) 

conv2d_1_1 = Conv2D(filters = 32, kernel_size = (3,3) , padding = "same" , activation = 'relu' , name = "conv2d_1_1")(input_img_1) 
conv2d_2_1 = Conv2D(filters = 64, kernel_size = (3,3) , padding = "same" , activation = 'relu')(conv2d_1_1) 
conv2d_3_1 = Conv2D(filters = 64, kernel_size = (3,3) , padding = "same" , activation = 'relu')(conv2d_2_1) 
conv2d_4_1 = Conv2D(filters = 32, kernel_size = (1,1) , padding = "same" , activation = 'relu')(conv2d_3_1) 
conv2d_4_1_flatten = Flatten()(conv2d_4_1) 

conv2d_1_2 = Conv2D(filters = 32, kernel_size = (3,3) , padding = "same" , activation = 'relu' , name = "conv2d_1_2")(input_img_2) 
conv2d_2_2 = Conv2D(filters = 64, kernel_size = (3,3) , padding = "same" , activation = 'relu')(conv2d_1_2) 
conv2d_3_2 = Conv2D(filters = 64, kernel_size = (3,3) , padding = "same" , activation = 'relu')(conv2d_2_2) 
conv2d_4_2 = Conv2D(filters = 32, kernel_size = (1,1) , padding = "same" , activation = 'relu')(conv2d_3_2) 
conv2d_4_2_flatten = Flatten()(conv2d_4_2) 


merge = keras.layers.concatenate([conv2d_4_1_flatten, conv2d_4_2_flatten]) 

dense1 = Dense(100, activation = 'relu')(merge) 
dense2 = Dense(50,activation = 'relu')(dense1) 
dense3 = Dense(1 ,activation = 'softmax')(dense2) 


model = Model(inputs = [input_img_1, input_img_2] , outputs = dense3) 
model.compile(loss="sparse_categorical_crossentropy", optimizer="adam") 

print model.summary() 

labels_train = keras.utils.to_categorical(labels_train_data, num_classes=145) 
labels_test = keras.utils.to_categorical(labels_test_data, num_classes=145) 

hist_current = model.fit(x = [train_data_1, train_data_2], 
        y = labels_train, 
        shuffle=False, 
        validation_data=([test_data_1 ,test_data_2], labels_test), 
        validation_split=0.1, 
        epochs=150000, 
        batch_size = 15, 
        verbose=1) 

和錯誤消息是:

Traceback (most recent call last): 
    File "test_model.py", line 57, in <module> 
    verbose=1) 
    File "/usr/local/lib/python2.7/dist-packages/keras/engine/training.py", line 1405, in fit 
    batch_size=batch_size) 
    File "/usr/local/lib/python2.7/dist-packages/keras/engine/training.py", line 1299, in _standardize_user_data 
    exception_prefix='model target') 
    File "/usr/local/lib/python2.7/dist-packages/keras/engine/training.py", line 133, in _standardize_input_data 
    str(array.shape)) 
ValueError: Error when checking model target: expected dense_3 to have shape (None, 1) but got array with shape (100, 145) 

回答

1

幾個不一致的模型:

  1. dense3 = Dense(1 ,activation = 'softmax')(dense2):你不能在一個神經元上單獨使用softmax。 softmax對層的輸出進行歸一化處理,使它總和爲1 ...在這種情況下,如果單獨對一個值進行歸一化處理,它將始終輸出1.但是,這不是您爲什麼得到錯誤的原因,只是有多少種類你有?從你的網絡中,你輸出一個值(最後一層是密集(1)),所以我期望你想要預測2個類(輸出1或0)。但是在這裏我們看到你的輸出是一個有145種可能性的分類......你的label_train數組是100個長度爲145的熱矢量,所以我假設你想把100個樣本分爲145個不同的類別......這就是爲什麼keras抱怨,你的網絡輸出(100,1)和你的目標(標籤)是(100,145)。你真的想做什麼?

編輯:

繼評論,因爲你要predictif圖像屬於145類之一,你將不得不輸出145個值。所以你將不得不改變網絡的最上層,這樣你的最後一層就是Dense(145, activation='softmax')。所以,我建議你更換

dense1 = Dense(100, activation = 'relu')(merge) 
dense2 = Dense(50,activation = 'relu')(dense1) 
dense3 = Dense(1 ,activation = 'softmax')(dense2) 

dense1 = Dense(200, activation = 'relu')(merge) 
dense2 = Dense(150, activation = 'relu')(dense1) 
dense3 = Dense(145, activation = 'softmax')(dense2) 

如果你真的想有3緻密層,否則你可以只取出中間的一個...這將取決於你的用例,所以隱藏層的體系結構取決於您。我只是堅持認爲你的最後一層應該是Dense(145, activation='softmax')

有意義嗎?

編輯2:

最重要的是,你不應該編碼您的目標(標籤)作爲categoricals,當您使用sparse_categorical_crossentropy,它的引擎蓋下自動完成。

因此,無論你用你的目標keras.utils.to_categoricalloss=categorical_crossentropy

,或者你不keras.utils.to_categorical改造目標,並使用loss=sparse_categorical_crossentropy

它在我的機器上運行。

+0

1.謝謝! - 這肯定需要更正 2.我基本上是在圖像上進行分類,我有145個班級,training_data的數量肯定大於100(251058 ..),但出於問題的目的,我做了這個快速示例。圖像分爲幾個部分,部分是圖像的某些部分,其中執行了一定的卷積。某種意義上說,重量只在這個地方共享。合併而不是concat所有功能,以及完全連接的層應該根據輸入執行分類。 –

+0

我編輯了我的答案。爲了記錄,當您使用密集(1)時,使用'sigmoid'激活來預測兩個類別之間或密集(2,激活='softmax'),這是相同的。 –

+0

它是有道理的..但我仍然得到同樣的錯誤。 –