[英]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.