2017-07-15 45 views
2

我有一個非常簡單的與傳輸學習和VGG16 NN有關的問題。在Keras中傳輸學習:ValueError:檢查目標時出錯:期望dense_26具有形狀(無,3)但獲得了形狀(3000,1)

這裏是我的代碼: 「發現3000個圖像屬於3類」

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() 
  • 「找到600張屬於3類的圖像。」

    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 

我在這裏的困難凸顯我的一個根本性的誤解我懷疑,但我需要一些非常直接的解釋。我在這個訓練中有三節課。 'hrct_data_small/train'包含3個文件夾,'hrct_data_small/validation'包含3個文件夾。

第一:我是在想,頂級車型的最後一層糾正:

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

應該是「3」,因爲我有3個班。

二:

我抓住了數據的形狀進行調查

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

然後

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 shape (3000, 4, 4, 512) 
    Train_labels shape (3000,) 
    Validation_data shape (600,) 
    Validation_labels (600,) 

所以,應該把「列車數據形狀「va可以呈現形狀(3000,3)。

我對這些基本問題表示歉意 - 如果我能對此有一個清晰的思考,我會很感激。

編輯:所以拜納西姆的建議之下,我解決了所有問題,除了:

的train_data是爲了恢復訓練數據,所以第一類(1000),那麼第二(1000)第三(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)) 
    

    這看起來不對。你需要多解釋一下你試圖預測的內容。通常情況下你的標籤應與發生器產生,並設置class_mode='categorical'代替class_mode=None這會使發電機輸出輸入和目標,目標將是長度的一個熱點編碼向量3.

  2. 你損失的意甲使用的是loss='binary_crossentropy'。當您對可以分爲多個類別的圖像進行分類時,或者只有兩種類別的可能性時,會使用這種方法。這不是你的情況(如果我理解正確的話)。您應該使用:loss='categorical_crossentropy'。這是每個圖像有一個,但不超過一個類作爲目標。

  3. 這與前一點鏈接,最後一層的激活:model.add(Dense(3, activation='sigmoid'))。 sigmoid將允許你的輸出爲[1 1 0]或[1 1 1]或[0 0 0],這些都是無效的,因爲在你的情況下你只想預測一個類,你不想讓你的圖像被歸類爲屬於三類。我們用於這種分類案例的是softmax。 softmax將對輸出進行歸一化,使它們總和爲1.現在可以將輸出解釋爲概率:[0.1 0.2 0.7],該圖像具有屬於第一類的概率爲10%,屬於第二類的概率爲10%,並且70 %到第三。因此,我想改變爲:model.add(Dense(3, activation='softmax'))

所以總結一下,網絡抱怨,因爲每個圖像時,會要求您提供的是長度爲3的一個熱載體的目標,編碼類,圖像屬於。你目前正在餵它只是一個數字0或1.

它更有意義嗎?

+0

Nassim。這對我來說是極好的教學。我明白你在說什麼,並看到這些錯誤(基本錯誤)。我會盡力實施您提出的修改並提供反饋。非常感謝 – GhostRider

+0

您好,先生們,歡迎:)如果它不起作用,請澄清你的問題出了什麼問題。如果有效,不要忘記驗證後代的答案。 –

相關問題