簡體   English   中英

嘗試利用 Keras 的 VGG16 預訓練時出現無效形狀錯誤 model

[英]Invalid Shape Error when trying to leverage Keras's VGG16 pretrained model

我正在嘗試在我自己的圖像分類問題中利用 kera 的VGG16 model 我的代碼主要基於 Francois Chollet 的示例(Python 中深度學習的第 8 章 - 代碼)。

我要預測三個班級。 目錄結構:

data/
  training/
    class_1
    class_2
    class_3

注意:這是我第一次使用 Keras,所以我可能只是做錯了什么。

我對model.fit()的調用失敗並顯示: ValueError: Shapes (32, 1) and (32, 3) are incompatible 有關完整的錯誤消息,請參閱此問題的底部。 如果我從 .summary .summary()調用中查看 output,我看不到一層維度 (32, 1)。

import pathlib
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras.utils import image_dataset_from_directory

DATA_DIR = pathlib.Path('./data/')
batch_size = 32
img_width = image_height = 256

train_dataset = image_dataset_from_directory(
    DATA_DIR / "training",
    image_size=img_width_height,
    batch_size=batch_size)

validation_dataset = image_dataset_from_directory(
    DATA_DIR / "validation",
    image_size=img_width_height,
    batch_size=batch_size)

# Found 128400 files belonging to 3 classes.
# Found 15600 files belonging to 3 classes.

vgg16_convolution_base = keras.applications.vgg16.VGG16(
    weights="imagenet",
    include_top=False,
    input_shape=(img_width, image_height, 3))

vgg16_convolution_base.summary()
# block3_conv3 (Conv2D)       (None, 64, 64, 256)       590080    
# block3_pool (MaxPooling2D)  (None, 32, 32, 256)       0         
# block4_conv1 (Conv2D)       (None, 32, 32, 512)       1180160   
# block4_conv2 (Conv2D)       (None, 32, 32, 512)       2359808   
# block4_conv3 (Conv2D)       (None, 32, 32, 512)       2359808   
# block4_pool (MaxPooling2D)  (None, 16, 16, 512)       0         
# block5_conv1 (Conv2D)       (None, 16, 16, 512)       2359808   
# block5_conv2 (Conv2D)       (None, 16, 16, 512)       2359808   
# block5_conv3 (Conv2D)       (None, 16, 16, 512)       2359808   
# block5_pool (MaxPooling2D)  (None, 8, 8, 512)         0

def get_features_and_labels(dataset):
    all_features = []
    all_labels = []
    for images, labels in dataset:
        preprocessed_images = keras.applications.vgg16.preprocess_input(images)
        features = vgg16_convolution_base.predict(preprocessed_images)
        all_features.append(features)
        all_labels.append(labels)
    return np.concatenate(all_features), np.concatenate(all_labels)

train_features, train_labels = get_features_and_labels(train_dataset)
val_features, val_labels = get_features_and_labels(validation_dataset)

print(train_features.shape)
print(train_labels.shape)
# (128400, 8, 8, 512)
# (128400,)

print(val_features.shape)
print(val_labels.shape)
# (15600, 8, 8, 512)
# (15600,)

inputs = keras.Input(shape=(8, 8, 512))

x = layers.Flatten()(inputs)
x = layers.Dense(256)(x)
x = layers.Dropout(0.5)(x)

outputs = layers.Dense(3, activation="softmax")(x)

model = keras.Model(inputs, outputs)

model.compile(loss="categorical_crossentropy",
              optimizer="rmsprop",
              metrics=["accuracy"])

model.summary()
# input_4 (InputLayer)        [(None, 8, 8, 512)]       0         
# flatten_1 (Flatten)         (None, 32768)             0         
# dense_2 (Dense)             (None, 256)               8388864   
# dropout_1 (Dropout)         (None, 256)               0         
# dense_3 (Dense)             (None, 3)                 771       
# ================================================================
# Total params: 8,389,635
# Trainable params: 8,389,635

history = model.fit(
    train_features, train_labels,
    epochs=20,
    validation_data=(val_features, val_labels)

我對model.fit()的調用失敗並顯示: ValueError: Shapes (32, 1) and (32, 3) are incompatible

...
File "C:\Users\x\anaconda3\lib\site-packages\keras\losses.py", line 1990, in categorical_crossentropy
        return backend.categorical_crossentropy(
    File "C:\Users\x\anaconda3\lib\site-packages\keras\backend.py", line 5529, in categorical_crossentropy
        target.shape.assert_is_compatible_with(output.shape)

完整追溯

3 個類的categorical_crossentropy損失和 32 的批大小決定了標簽的形狀(對於每個 bach)為 (32, 3)。

這些標簽目前是有序的: 0 2 1 可以對序號標簽使用SparseCategoricalCrossentropy損失:

loss= tf.keras.losses.SparseCategoricalCrossentropy()

或者,仍然可以使用categorical_crossentropy損失,但結合 one-hot 編碼標簽(1, 0, 0) for 0(0, 1, 0) for 1(0, 0, 1) for 2 . 下面的代碼片段可以完成這樣的編碼:

#one-hot encoding
num_class = len(set(train_labels))
train_labels=tf.one_hot(indices=train_labels, depth=num_class)
val_labels=tf.one_hot(indices=val_labels, depth=num_class)

數據的性質(有序或無序)有助於確定單熱編碼是首選還是有序編碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM