分類

2017-04-01 24 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):1つのニューロンのみでsoftmaxを使用することはできません。 softmax normalize層の出力が1になるようにします。この場合、1つの値だけを正規化すると、常に1が出力されます。しかし、これはエラーが発生する理由ではありません。
  2. ありますか?あなたのネットワークから、あなたは2つのクラス(出力1または0)を予測したいと思うので、1つの値を出力します(最後のレイヤーはDense(1)です)。しかし、ここではあなたの出力が145の可能性を持つカテゴリであることがわかります... label_train配列は長さ145の100個のホットベクトルの100個ですので、100個のサンプルを145個の異なるカテゴリに分類したいとします。あなたのネットワーク出力(100,1)とターゲット(ラベル)は(100,145)です。あなたは本当に何をしたいですか?

編集:コメントに続いて

、あなたが画像をpredictifしたいので、145クラスのいずれかに属している、あなたは、出力145の値になります。したがって、最後のレイヤーがDense(145, activation='softmax')になるように、ネットワークの最上位レイヤーを変更する必要があります。だから私はあなたが本当に3つの緻密層を持ちたい場合は、あなたがそうでなければあなただけの真ん中を削除することができ、

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) 

と交換することを提案している...これはそう、あなたのユースケースに依存します隠された層のアーキテクチャはあなた次第です。私はあなたの最後の層がDense(145, activation='softmax')であることを主張しています。

意味がありますか?

編集2:その上で

は、あなたがsparse_categorical_crossentropyを使用する場合、それはボンネットの下で自動的に行われ、categoricalsとしてあなたのターゲット(ラベル)をコードべきではありません。

だから、loss=categorical_crossentropy

であなたの目標にkeras.utils.to_categoricalを使用するか、keras.utils.to_categoricalでターゲットを変換し、loss=sparse_categorical_crossentropyを使用していないのいずれか。

私のマシンで動作しています。

+0

1.ありがとうございました! - それは間違いなく修正する必要があります 2.私は基本的に画像上の分類をしています、私は145のクラスを持っています、training_dataの数は間違いなく100(251058 ..)より大きいですが、質問の目的のために私はこの簡単な例を作った。画像はセクションに分割され、セクションは画像の特定の部分であり、そこではある畳み込みが行われる。特定の意味では、体重はこの地域でのみ共有されます。すべてのフィーチャーを連結するよりもマージし、入力に基づいて分類を実行する完全に接続されたレイヤー。 –

+0

私は自分の答えを編集しました。レコードの場合、Dense(1)を使用する場合は、 'Sigmoid'アクティベーションを使用して2つのクラス間の予測を行うか、Dense(2、activation = 'softmax')を予測します。 –

+0

意味がありますが、私はまだ同じエラーが発生します。 –