面部表情检测CNN模型训练遇UnimplementedError,如何修复?
问题
在面部表情检测项目中训练自定义CNN模型时,执行以下训练代码:
history = model3.fit(x= train_set, validation_data = validation_set, batch_size = 32, epochs = 20)
触发UnimplementedError异常,核心错误信息为:
Fused conv implementation does not support grouped convolutions for now.
相关模型定义、回调配置及编译代码如下:
模型定义
no_of_classes = 4 model3 = Sequential() # Add 1st CNN Block model3.add(Conv2D(64, (2,2), padding = 'same', activation = 'relu', input_shape = (48, 48, 1))) model3.add(BatchNormalization()) model3.add(LeakyReLU(alpha = 0.2)) model3.add(MaxPooling2D(2,2)) model3.add(Dropout(rate = 0.2)) # Add 2nd CNN Block model3.add(Conv2D(128, (2,2), padding = 'same', activation = 'relu')) model3.add(BatchNormalization()) model3.add(LeakyReLU(alpha = 0.2)) model3.add(MaxPooling2D(2,2)) model3.add(Dropout(rate = 0.2)) # Add 3rd CNN Block model3.add(Conv2D(512, (2,2), padding = 'same', activation = 'relu')) model3.add(BatchNormalization()) model3.add(LeakyReLU(alpha = 0.2)) model3.add(MaxPooling2D(2,2)) model3.add(Dropout(rate = 0.2)) # Add 4th CNN Block model3.add(Conv2D(512, (2,2), padding = 'same', activation = 'relu')) model3.add(BatchNormalization()) model3.add(LeakyReLU(alpha = 0.2)) model3.add(MaxPooling2D(2,2)) model3.add(Dropout(rate = 0.2)) # Add 5th CNN Block model3.add(Conv2D(256, (2,2), padding = 'same', activation = 'relu')) model3.add(BatchNormalization()) model3.add(LeakyReLU(alpha = 0.2)) model3.add(MaxPooling2D(2,2)) model3.add(Dropout(rate = 0.2)) model3.add(Conv2D(512, (2,2), padding = 'same', activation = 'relu')) model3.add(BatchNormalization()) model3.add(LeakyReLU(alpha = 0.2)) model3.add(MaxPooling2D(1,1)) model3.add(Dropout(rate = 0.2)) model3.add(Flatten()) # First fully connected layer model3.add(Dense(256)) model3.add(LeakyReLU(alpha = 0.2)) model3.add(BatchNormalization()) model3.add(Dropout(rate = 0.2)) # Second fully connected layer model3.add(Dense(512)) model3.add(LeakyReLU(alpha = 0.2)) model3.add(BatchNormalization()) model3.add(Dropout(rate = 0.2)) # Third fully connected layer model3.add(Dense(64)) model3.add(LeakyReLU(alpha = 0.2)) model3.add(BatchNormalization()) model3.add(Dropout(rate = 0.2)) model3.add(Dense(no_of_classes, activation = 'softmax')) model3.summary()
回调配置
from keras.callbacks import ModelCheckpoint, ReduceLROnPlateau, CSVLogger epochs = 35 steps_per_epoch = train_set.n//train_set.batch_size validation_steps = validation_set.n//validation_set.batch_size checkpoint = ModelCheckpoint("model3.h5", monitor = 'val_accuracy', save_weights_only = True, mode = 'max', verbose = 1) reduce_lr = ReduceLROnPlateau(monitor = 'val_loss', factor = 0.1, patience = 2, min_lr = 0.0001 , mode = 'auto') callbacks = [checkpoint, reduce_lr]
编译代码
model3.compile(optimizer = Adam(learning_rate = 0.001), loss = 'categorical_crossentropy', metrics ='accuracy')
解决方案
核心原因
TensorFlow的融合卷积实现目前不支持分组卷积,即便模型未显式设置groups参数,在小尺寸特征图卷积、输入通道与滤波器数量比例触发自动分组等场景下,TensorFlow会尝试用分组卷积优化,从而触发该错误。
修复方法
方法1:禁用卷积层的融合实现
在所有Conv2D层中添加fused=False参数,强制TensorFlow不使用融合卷积:
# 示例:修改第一个Conv2D层 model3.add(Conv2D(64, (2,2), padding = 'same', activation = 'relu', input_shape = (48, 48, 1), fused=False))
将模型中所有Conv2D层都加上该参数,即可绕过融合实现的限制。
方法2:移除冗余激活函数(优化)
模型中每个Conv2D都设置了activation='relu',随后又添加LeakyReLU层,属于重复激活,既浪费计算资源也可能干扰模型表现。建议移除Conv2D中的activation参数,仅保留LeakyReLU:
# 修改后示例 model3.add(Conv2D(64, (2,2), padding = 'same', input_shape = (48, 48, 1), fused=False)) model3.add(BatchNormalization()) model3.add(LeakyReLU(alpha = 0.2))
方法3:调整卷积核尺寸(可选)
错误出现在第五个Block后的Conv2D层,此时输入特征图已缩小到1x1,使用2x2卷积核会触发特殊处理。可将该层卷积核改为1x1:
model3.add(Conv2D(512, (1,1), padding = 'same', activation = 'relu', fused=False))
额外修正
回调配置中存在参数拼写错误:原代码中的model应为mode,已在上述回调代码中修正,不修正会导致回调功能异常。
内容的提问来源于stack exchange,提问作者Domla Pass
相关产品推荐
相关产品推荐

