2017-07-15 10 views
2

私はトランスファーラーニングとVGG16 NNに関する非常に簡単な質問があります。ここでKerasの伝達学習:ValueError:ターゲットをチェックするときのエラー:dense_26が形状(なし、3)を持っているが、形状(3000,1)を持つ配列を持っている

は私のコードです:

import numpy as np 
    from keras.preprocessing.image import ImageDataGenerator 
    from keras.models import Sequential 
    from keras.layers import Dropout, Flatten, Dense 
    from keras import applications 
    from keras import optimizers 
    from keras.applications.vgg16 import VGG16 
    from keras.applications.vgg16 import preprocess_input 

    img_width, img_height = 150, 150 
    top_model_weights_path = 'full_hrct_model_weights.h5' 
    train_dir = 'hrct_data_small/train' 
    validation_dir = 'hrct_data_small/validation' 
    nb_train_samples = 3000 
    nb_validation_samples = 600 
    epochs = 50 
    batch_size = 20 


    def save_bottleneck_features(): 
     datagen = ImageDataGenerator(rescale=1./255) 

     # build the vgg16 model 
     model = applications.VGG16(include_top=False, weights='imagenet') 

     generator = datagen.flow_from_directory(
      train_dir, 
      target_size=(img_width, img_height), 
      shuffle=False, 
      class_mode=None, 
      batch_size=batch_size 
     ) 


     bottleneck_features_train = model.predict_generator(generator=generator, steps=nb_train_samples // batch_size) 

     np.save(file="bottleneck_features_train_ternary_class.npy", arr=bottleneck_features_train) 


     generator = datagen.flow_from_directory(
      validation_dir, 
      target_size=(img_width, img_height), 
      shuffle=False, 
      class_mode=None, 
      batch_size=batch_size,  
     ) 

     bottleneck_features_validation = model.predict_generator(generator, nb_validation_samples // batch_size) 

     np.save(file="bottleneck_features_validate_ternary_class.npy", arr=bottleneck_features_validation) 

    save_bottleneck_features() 
  • "3000枚の画像は3つのクラスに属するが見つかりました。"

  • "3つのクラスに属する600個の画像が見つかりました。

    def train_top_model(): 
    
        train_data = np.load(file="bottleneck_features_train_ternary_class.npy") 
        train_labels = np.array([0] * (nb_train_samples // 2) + [1] * (nb_train_samples // 2)) 
    
        validation_data = np.load(file="bottleneck_features_validate_ternary_class.npy") 
        validation_labels = np.array([0] * (nb_validation_samples // 2) + [1] * (nb_validation_samples // 2)) 
    
        model = Sequential() 
        model.add(Flatten(input_shape=train_data.shape[1:])) # don't need to tell batch size in input shape 
        model.add(Dense(256, activation='relu')) 
         model.add(Dense(3, activation='sigmoid')) 
    
        print(model.summary) 
    
        model.compile(optimizer='Adam', loss='binary_crossentropy', metrics=['accuracy']) 
    
        model.fit(train_data, train_labels, 
           epochs=epochs, 
           batch_size=batch_size, 
           validation_data=(validation_data, validation_labels)) 
    
        model.save_weights(top_model_weights_path) 
    
    train_top_model() 
    

私が取得エラーは、この次のとおりです。ここで


ValueError        Traceback (most recent call last) 
    <ipython-input-52-33db5c28e162> in <module>() 
     2    epochs=epochs, 
     3    batch_size=batch_size, 
    ----> 4    validation_data=(validation_data, validation_labels))  

    /Users/simonalice/anaconda/lib/python3.5/site-packages/keras/models.py in fit(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, **kwargs) 
     854        class_weight=class_weight, 
     855        sample_weight=sample_weight, 
    --> 856        initial_epoch=initial_epoch) 
     857 
     858  def evaluate(self, x, y, batch_size=32, verbose=1, 

    /Users/simonalice/anaconda/lib/python3.5/site-packages/keras/engine/training.py in fit(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, **kwargs) 
    1427    class_weight=class_weight, 
    1428    check_batch_axis=False, 
    -> 1429    batch_size=batch_size) 
    1430   # Prepare validation data. 
    1431   if validation_data: 

    /Users/simonalice/anaconda/lib/python3.5/site-packages/keras/engine/training.py in _standardize_user_data(self, x, y, sample_weight, class_weight, check_batch_axis, batch_size) 
    1307          output_shapes, 
    1308          check_batch_axis=False, 
    -> 1309          exception_prefix='target') 
    1310   sample_weights = _standardize_sample_weights(sample_weight, 
    1311              self._feed_output_names) 

    /Users/simonalice/anaconda/lib/python3.5/site-packages/keras/engine/training.py in _standardize_input_data(data, names, shapes, check_batch_axis, exception_prefix) 
     137        ' to have shape ' + str(shapes[i]) + 
     138        ' but got array with shape ' + 
    --> 139        str(array.shape)) 
     140  return arrays 
     141 

    ValueError: Error when checking target: expected dense_32 to have shape (None, 3) but got array with shape (3000, 1) 

は、モデルの要約である:ここ

Layer (type)     Output Shape    Param # 
    ================================================================= 
    flatten_16 (Flatten)   (None, 8192)    0   
    _________________________________________________________________ 
    dense_31 (Dense)    (None, 256)    2097408 
    _________________________________________________________________ 
    dropout_16 (Dropout)   (None, 256)    0   
    _________________________________________________________________ 
    dense_32 (Dense)    (None, 3)     771  
    ================================================================= 
    Total params: 2,098,179 
    Trainable params: 2,098,179 
    Non-trainable params: 0 

私の難しさは、私の部分に根本的な誤解を強調私は疑うが、私は非常に簡単な説明が必要です。私はこのトレーニングで3つのクラスを持っています。 'hrct_data_small/train'には3つのフォルダがあり、 'hrct_data_small/validation'には3つのフォルダが含まれています。

まず:私はトップモデルの最後の層と考えることで正しい午前:私は3つのクラスを持っているよう

model.add(Dense(3, activation='sigmoid')) 

が「3」でなければなりません。

第二:

私は

print("Train data shape", train_data.shape) 
    print("Train_labels shape", train_labels.shape) 
    print("Validation_data shape", validation_labels.shape) 
    print("Validation_labels", validation_labels.shape) 

その後

train_data = np.load(file="bottleneck_features_train_ternary_class.npy") 
    train_labels = np.array([0] * (nb_train_samples // 2) + [1] * (nb_train_samples // 2)) 
    validation_data =np.load(file="bottleneck_features_validate_ternary_class.npy") 
    validation_labels = np.array([0] * (nb_validation_samples // 2) + [1] * (nb_validation_samples // 2)) 

を調査するために、データの形状をつかんで、結果はそう

Train data shape (3000, 4, 4, 512) 
    Train_labels shape (3000,) 
    Validation_data shape (600,) 
    Validation_labels (600,) 

で、「電車のデータべき形 "vaライバルは形になる(3000,3)。

私はこれらの基本的な質問に対して謝罪します。私がこのことについていくらか明確な考えを得ることができれば、私は感謝します。

EDIT:以下Naseemのアドバイスのおかげで、私は除いてすべての彼のポイントを取り上げたので:train_dataが第2(1000)ファーストクラス(1000)ので、順番にトレーニングデータを返していました

と第3の(1000)。したがってtrain_labelsの順にする必要があります

train_data = np.load(file="bottleneck_features_train_ternary_class.npy") 
    train_labels = np.array([0] * 1000 + [1] * 1000 + [2] * 1000) 
    validation_data = np.load(file="bottleneck_features_validate_ternary_class.npy") 
    validation_labels = np.array([0] * 400 + [1] * 400 + [2] * 400) 

私はそのようにのようなラベルを固定:

train_labels = np_utils.to_categorical(train_labels, 3) 
    validation_labels = np_utils.to_categorical(validation_labels, 3) 

右の形状にラベルを持って、ワンホットは、それらをコードしていました。私は最初のいくつかを調べて、彼らは正しかった。その後、モデルが機能しました。

追加のコメントとして - すべての回答はKerasのドキュメントにありました。私が読んでもう少し時間を費やして、コードをカットアンドペーストする時間が短いなら、私はそれを正しく得ているでしょう。学んだ教訓。

答えて

4

私は、これはyoutは念頭に置いて、すべてをクリアするが、ここで私はあなたのコード内で参照多少の誤差がありますかわからない:

  1. あなたのラベルを作成する方法は私には本当に奇妙です。なぜ、データの半分を0に、残りの半分を1と入れますか:

    train_labels = np.array([0] * (nb_train_samples // 2) + [1] * (nb_train_samples // 2)) 
    

    これは正しくないようです。あなたは何を予測しようとしているのかをもう少し説明する必要があります。通常、あなたのラベルは発電機で生産され、これは、発電機出力入力とターゲットの両方を行いますと、ターゲットは長さの1つのホットエンコードされたベクトル3.

  2. あなたが損失のセリエなります代わりにclass_mode=Noneclass_mode='categorical'を設定する必要があります使用はloss='binary_crossentropy'です。これは、複数のカテゴリに入ることができる画像の分類を行うとき、またはクラスの可能性が2つしかないときに使用されます。これはあなたのケースではありません(私が正しく理解している場合)。あなたは:loss='categorical_crossentropy'を使用する必要があります。これは、各画像が1つのクラスをターゲットとして持つ場合です。

  3. これは、前のポイント、最後のレイヤーのアクティブ化:model.add(Dense(3, activation='sigmoid'))にリンクされています。 Sigmoidはあなたの出力を[1 1 0]または[1 1 1]または[0 0 0]にすることができます。あなたの場合には1つのクラスのみを予測したい場合は無効です。 3つのクラスに属すると分類される。この分類の場合に使用するものは、softmaxです。 softmaxは出力を1に合うように出力を正規化します。出力を確率として解釈することができます:[0.1 0.2 0.7]、画像はファーストクラスに属する確率は10%、ファーストクラスには20%、ファーストクラスには20% %を3番目の文字に置き換えます。だから私はに変更になります。画像ごとに、それが画像というクラスをコードする、あなたは長さ3のワンホットベクトルであることを提供し、ターゲットを想定しているためので、要約しmodel.add(Dense(3, activation='softmax'))

、ネットワークは文句属する。あなたが現在供給しているのは、ただ1つの番号0または1です。

もっと意味がありますか?

+0

Nassim。これは私にとって素晴らしい教訓です。私はあなたが言っていることを理解し、これらのエラー(根本的な誤り)を見ます。あなたが提案した修正を実装し、フィードバックを提供しようとします。多くのありがとう – GhostRider

+0

あなたが大歓迎です:)うまくいかない場合は、あなたの質問に間違っていることを明確にしてください。それがうまくいくならば、来るべき世代の答えを検証することを忘れないでください。 –

関連する問題

 関連する問題