【问题标题】:ValueError: Input 0 of layer block1_conv1 is incompatible with the layerValueError:层block1_conv1的输入0与层不兼容
【发布时间】:2021-09-13 13:10:41
【问题描述】:

我是 DL 新手,我正在尝试使用 FER2013 日期集通过 VGG16 预训练网络执行情感识别任务,但是当我尝试预测结果时出现此错误:

"ValueError: 层 block1_conv1 的输入 0 与层不兼容:输入形状的预期轴 -1 具有值 3,但接收到形状为 (None, 48, 48, 1) 的输入"

代码如下:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sn
import skimage.io
import keras.backend as K
import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.applications import VGG16
from tensorflow.keras.layers import Dense, Flatten, Dropout,BatchNormalization ,Activation
from tensorflow.keras.models import Model, Sequential
from keras.applications.nasnet import NASNetLarge
from tensorflow.keras.callbacks import ReduceLROnPlateau, ModelCheckpoint, EarlyStopping
from tensorflow.keras.optimizers import Adam

from google.colab import drive
drive.mount("/content/drive")

from zipfile import ZipFile
!unzip -q "/content/drive/MyDrive/archive.zip"

train_datagen = ImageDataGenerator(rescale = 1./255,
                                   validation_split = 0.2,
                                  
        rotation_range=5,
        width_shift_range=0.2,
        height_shift_range=0.2,
        shear_range=0.2,
        #zoom_range=0.2,
        horizontal_flip=True,
        vertical_flip=True,
        fill_mode='nearest')

valid_datagen = ImageDataGenerator(rescale = 1./255,
                                  validation_split = 0.2)

test_datagen  = ImageDataGenerator(rescale = 1./255
                                  )

train_dir='train'
train_dataset  = train_datagen.flow_from_directory(train_dir,
                                                   target_size = (48,48),
                                                   class_mode = 'categorical',
                                                   subset = 'training',
                                                   batch_size = 64)

valid_dataset = valid_datagen.flow_from_directory(train_dir,
                                                  target_size = (48,48),
                                                  class_mode = 'categorical',
                                                  subset = 'validation',
                                                  batch_size = 64)

test_dir='test'
test_dataset = test_datagen.flow_from_directory(test_dir,
                                                  target_size = (48,48),
                                                  class_mode = 'categorical',
                                                  batch_size = 64)

base_model = tf.keras.applications.VGG16(input_shape=(48,48,3),include_top=False,weights="imagenet")

# Freezing Layers

for layer in base_model.layers[:-4]:
    layer.trainable=False
# Building Model

model=Sequential()
model.add(base_model)
model.add(Dropout(0.5))
model.add(Flatten())
model.add(BatchNormalization())
model.add(Dense(32,kernel_initializer='he_uniform'))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(32,kernel_initializer='he_uniform'))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(32,kernel_initializer='he_uniform'))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(Dense(7,activation='softmax'))
# Model Summary

model.summary()

from tensorflow.keras.utils import plot_model
from IPython.display import Image
plot_model(model, to_file='convnet.png', show_shapes=True,show_layer_names=True)
Image(filename='convnet.png') 

def f1_score(y_true, y_pred): #taken from old keras source code
    true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))
    possible_positives = K.sum(K.round(K.clip(y_true, 0, 1)))
    predicted_positives = K.sum(K.round(K.clip(y_pred, 0, 1)))
    precision = true_positives / (predicted_positives + K.epsilon())
    recall = true_positives / (possible_positives + K.epsilon())
    f1_val = 2*(precision*recall)/(precision+recall+K.epsilon())
    return f1_val
METRICS = [
      tf.keras.metrics.BinaryAccuracy(name='accuracy'),
      tf.keras.metrics.Precision(name='precision'),
      tf.keras.metrics.Recall(name='recall'),  
      tf.keras.metrics.AUC(name='auc'),
        f1_score,
]
lrd = ReduceLROnPlateau(monitor = 'val_loss',patience = 20,verbose = 1,factor = 0.50, min_lr = 1e-10)

mcp = ModelCheckpoint('model.h5')

es = EarlyStopping(verbose=1, patience=20)

model.compile(optimizer='Adam', loss='categorical_crossentropy',metrics=METRICS)
history=model.fit(train_dataset,validation_data=valid_dataset,epochs = 5,verbose = 1,callbacks=[lrd,mcp,es])

model.save('vgg-16.h5')

import keras

model = keras.models.load_model('vgg-16.h5', compile = False)

METRICS = [
      tf.keras.metrics.BinaryAccuracy(name='accuracy'),
      tf.keras.metrics.Precision(name='precision'),
      tf.keras.metrics.Recall(name='recall'),  
      tf.keras.metrics.AUC(name='auc'),
        f1_score,
]

model.compile(optimizer='Adam', loss='categorical_crossentropy',metrics=METRICS)

from keras.preprocessing import image

img = image.load_img("test/happy/PrivateTest_1140198.jpg",target_size = (48,48),color_mode = "grayscale")
img = np.array(img)
plt.imshow(img)
print(img.shape) #prints (48,48) that is the shape of our image

label_dict = {0:'Angry',1:'Disgust',2:'Fear',3:'Happy',4:'Neutral',5:'Sad',6:'Surprise'}
img = np.expand_dims(img,axis = 0) #makes image shape (1,48,48)
img = img.reshape(1,48,48,1)
result = model.predict(img)

【问题讨论】:

  • 您的 VGG16 模型有 3 个通道,但您的 img 只有 1 个。

标签: tensorflow keras deep-learning neural-network


【解决方案1】:

这个预训练的 VGG16 网络设置为接收形状为 (48, 48, 3) 的输入图像,这 3 个通道对应于图像的 RGB 颜色。

在这一行:

img = image.load_img("test/happy/PrivateTest_1140198.jpg",target_size = (48,48),color_mode = "grayscale")

您使用color_mode="grayscale" 加载图像,这将返回一个 1 通道图像。

要适应模型的预期输入形状,您需要设置color_mode="rgb",这会产生 3 通道 RGB 图像。

然后,在通过模型之前将您的图像重塑为img = img.reshape(1,48,48,3)

【讨论】:

    猜你喜欢
    • 2021-07-04
    • 2020-11-28
    • 2021-05-31
    • 1970-01-01
    • 2022-07-22
    • 2021-08-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多