2017-10-25 8 views
1

を(ターゲットをチェックするときのエラー)を標的とするために余分な次元を追加:モデルのKerasが、私はこのコードで定義されたシャムKerasモデルを持っている

image1 = Input(shape=(128,128,3)) 
image2 = Input(shape=(128,128,3)) 

mobilenet = keras.applications.mobilenet.MobileNet(
     input_shape=(128,128,3), 
     alpha=0.25, 
     depth_multiplier=1, 
     dropout=1e-3, 
     include_top=False, 
     weights='imagenet', 
     input_tensor=None, 
     pooling='avg') 

out1 = mobilenet(image1) 
out2 = mobilenet(image2) 

diff = subtract([out1, out2]) 

distance = Lambda(lambda x: K.sqrt(K.sum(K.square(x), axis=1)))(diff) 

model = Model(inputs=[image1, image2], outputs=distance) 
model.compile(optimizer='rmsprop', 
        loss='hinge', 
        metrics=['accuracy']) 

概要は、次のようになります。

____________________________________________________________________________________________________ 
Layer (type)      Output Shape   Param #  Connected to      
==================================================================================================== 
input_1 (InputLayer)    (None, 128, 128, 3) 0            
____________________________________________________________________________________________________ 
input_2 (InputLayer)    (None, 128, 128, 3) 0            
____________________________________________________________________________________________________ 
mobilenet_0.25_128 (Model)  (None, 256)   218544  input_1[0][0]      
                    input_2[0][0]      
____________________________________________________________________________________________________ 
subtract_1 (Subtract)   (None, 256)   0   mobilenet_0.25_128[1][0]   
                    mobilenet_0.25_128[2][0]   
____________________________________________________________________________________________________ 
lambda_1 (Lambda)    (None,)    0   subtract_1[0][0]     
==================================================================================================== 
Total params: 218,544 
Trainable params: 213,072 
Non-trainable params: 5,472 
____________________________________________________________________________________________________ 

私はモデルを訓練しようとする。私のトレーニングルーチンは、次のようになります。

for i in range(1000): 
    X1,X2,y = data_source.getTrainingBatch(10, sameProb=0.5) 
    y = y[:,0] // grab ground truth for class 0 
    print(y.shape) // (10,) 
    loss=model.train_on_batch([X1,X2], y) 

X1及びX2は、形状(10, 128, 128, 3)を持っています。

yは、形状が(10,2)であり、2つのクラスの1ホットコード化ベクトルのリストです。私は最初のクラスの真実を取り上げ、それをモデルにフィードしようとします。

print(y.shape)ステートメントプリント(10,)ですので、配列は1Dです。私はモデルが対象で、このケース(10)に、1次元を持って期待していますが、形状の2Dターゲットを受け取る理解では10,1(

ValueError        Traceback (most recent call last) 
<ipython-input-2-bf89243ee200> in <module>() 
----> 1 n=net.SiamNet("drug-net") 

~/development/drug_master/net_keras.py in __init__(self, model_name, training) 
    16       print(self.model.summary()) 
    17       self.data_source = data.BoxComparisonData() 
---> 18       self.train() 
    19       self.save() 
    20     else: 

~/development/drug_master/net_keras.py in train(self) 
    75       X1,X2,y = self.data_source.getTrainingBatch(10, sameProb=0.5) 
    76       print(y.shape) 
---> 77       loss=self.model.train_on_batch([X1,X2], y[:,0].flatten()) # starts training 
    78       print("Loss (%d):" % i, loss) 
    79       if(i%20 == 0): 

~/anaconda3/lib/python3.6/site-packages/keras/engine/training.py in train_on_batch(self, x, y, sample_weight, class_weight) 
    1754    sample_weight=sample_weight, 
    1755    class_weight=class_weight, 
-> 1756    check_batch_axis=True) 
    1757   if self.uses_learning_phase and not isinstance(K.learning_phase(), int): 
    1758    ins = x + y + sample_weights + [1.] 

~/anaconda3/lib/python3.6/site-packages/keras/engine/training.py in _standardize_user_data(self, x, y, sample_weight, class_weight, check_batch_axis, batch_size) 
    1380          output_shapes, 
    1381          check_batch_axis=False, 
-> 1382          exception_prefix='target') 
    1383   sample_weights = _standardize_sample_weights(sample_weight, 
    1384              self._feed_output_names) 

~/anaconda3/lib/python3.6/site-packages/keras/engine/training.py in _standardize_input_data(data, names, shapes, check_batch_axis, exception_prefix) 
    130         ' to have ' + str(len(shapes[i])) + 
    131         ' dimensions, but got array with shape ' + 
--> 132         str(array.shape)) 
    133    for j, (dim, ref_dim) in enumerate(zip(array.shape, shapes[i])): 
    134     if not j and not check_batch_axis: 

ValueError: Error when checking target: expected lambda_1 to have 1 dimensions, but got array with shape (10, 1) 

:私は、コードを実行したときに、私は次のエラーを取得します)。 Kerasが私の目標に余分な次元を加えるようだ。私は何が欠けていますか?

Kerasバージョンは、私はこれは奇妙であるバックエンド(1.3.0)

+1

これは変です.... yのような音は実際には '(10、)'ではありません。とにかく 'K.sum'で' keepdims = True'を使って、期待される出力を '(10,1)'にすることができます。 –

+0

ありがとうございます。 'keepdims = True'を追加するとコードが実行されます。しかし、Kerasがなぜターゲット変数に余分な次元を追加するのか不思議です。 – lojzezust

答えて

0

としてtensorflow使用2.0.8

です。

yは実際には(10,1)と思われます。

K.sumkeepdims=Trueを使用すると、kerasが(10,1)の配列を期待するようにすることができます。


原因がわかりません。おそらくあなたは古いY vars(おそらく大文字ですか?)が消去されておらず、それらを偶然使用していますか?

+0

ええ、私はそれをすでに確認しました。また、別の変数に代入し、その変数をターゲットとして渡しました。同じ結果。ソリューションは機能しますが、ヒンジ損失機能の仕組みが変わります。どのように使用するのかはわかりませんが、[実装](https://github.com/fchollet/keras/blob/master/keras/losses.py)は最後の次元の平均を計算し、余分な次元が追加されると、これは無用になります(1つの要素の平均は要素そのものです)。私は自分自身の損失関数を使ってそれを回避することができますが、それが意図された使用法であることを知ることはまだ素晴らしいです。 – lojzezust

関連する問題