【发布时间】: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