You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何提升基于VGG16迁移学习的情感检测模型验证准确率?

情感分类任务(VGG16迁移学习)验证准确率提升方案

问题背景

我正在进行积极/消极/中性的情感分类任务,采用VGG16迁移学习模型,但自有数据集上验证准确率始终无法突破66%。已尝试的优化手段包括:

  • 扩充训练数据集规模
  • 调整VGG16层的可训练状态(layers.trainable=False/True)
  • 测试不同学习率:0.0001、0.001、0.01
  • 更换激活函数:relu/softmax
  • 设置batch size为64
  • 尝试不同优化器:adam/sgd
  • 更换损失函数:categorical_crossentropy/sparse_categorical_crossentropy
  • 调整动量参数:0.09/0.9

额外尝试:将数据集转为灰度图(准确率略有提升但未达预期)、添加Dropout层(无明显进展)。使用FER2013数据集时,训练准确率0.9997,验证准确率0.7105,但自有数据集表现不佳。

现有代码

import pandas as pd
import numpy as np
import keras
import tensorflow
from keras.models import Model
from keras.layers import Dense
from keras import optimizers
from keras.preprocessing.image import ImageDataGenerator
from keras.preprocessing import image

trdata = ImageDataGenerator()
traindata = trdata.flow_from_directory(directory="path",target_size=(224,224))
tsdata = ImageDataGenerator()
testdata = tsdata.flow_from_directory(directory="path", target_size=(224,224))

from keras.applications.vgg16 import VGG16
vggmodel = VGG16(weights='imagenet', include_top=True)

vggmodel.summary()

for layers in (vggmodel.layers)[:19]:
    print(layers)
    layers.trainable = False

#flatten_out = tensorflow.keras.layers.Flatten()(vggmodel.output)
#fc1 = tensorflow.keras.layers.Dense(units=4096,activation="relu")(flatten_out)
#fc2 = tensorflow.keras.layers.Dense(units=4096,activation="relu")(fc1)
#fc3 = tensorflow.keras.layers.Dense(units=256,activation="relu")(fc2)
#predictions = tensorflow.keras.layers.Dense(units=3, activation="softmax")(fc3)
X= vggmodel.layers[-2].output
predictions = Dense(units=3, activation="softmax")(X)
model_final = Model(vggmodel.input, predictions)

model_final.compile(loss = "categorical_crossentropy", optimizer = optimizers.SGD(lr=0.001, momentum=0.9), metrics=["accuracy"])

model_final.summary()

from keras.callbacks import ModelCheckpoint, LearningRateScheduler, TensorBoard, EarlyStopping

checkpoint = ModelCheckpoint("vgg16_1.h5", monitor='val_acc', verbose=1, save_best_only=True, save_weights_only=False, mode='auto', period=1)
early = EarlyStopping(monitor='val_acc', min_delta=0, patience=40, verbose=1, mode='auto')


model_final.fit_generator(generator= traindata, steps_per_epoch= 95, epochs= 100, validation_data= testdata, validation_steps=7, callbacks=[checkpoint,early])

优化建议

1. 搞对数据预处理和增强

  • 给训练数据加针对性增强:你现在的ImageDataGenerator啥增强都没开,针对情感分类(大概率是人脸),试试加这些:
    trdata = ImageDataGenerator(
        rotation_range=15,  # 小幅度旋转
        width_shift_range=0.1,  # 左右平移
        height_shift_range=0.1,  # 上下平移
        shear_range=0.1,  # 剪切变换
        zoom_range=0.1,  # 缩放
        horizontal_flip=True,  # 水平翻转(人脸左右对称不影响情感)
        brightness_range=[0.8,1.2],  # 亮度调整
        preprocessing_function=keras.applications.vgg16.preprocess_input  # 必须加,和VGG预训练的输入分布对齐
    )
    
  • 灰度图处理要正确:如果灰度图效果好,别直接单通道喂VGG16(它默认要3通道),要么把单通道复制成3通道,要么改VGG16的输入层为单通道(但第一层权重得重新初始化)。

2. 调整迁移学习的打开方式

  • 分层解冻微调:别直接冻前19层或者全解冻,分两步来:
    1. 先把VGG16全冻住,只训练你加的分类头,让模型先适应你数据集的分布。
    2. 解冻最后3-5层卷积层,用极小的学习率(比如1e-5)接着训,让高层特征贴合你的情感任务。
  • 换个预训练模型试试:VGG16太老了,试试MobileNetV2、ResNet50,或者专门针对人脸的VGGFace模型,这些模型提取的特征可能更适合情感分类。

3. 给模型结构补点东西

  • 加中间层和正则化:在VGG输出和分类头之间加个小全连接层+正则化,比如:
    X = vggmodel.layers[-2].output
    X = Dense(256, activation='relu')(X)
    X = keras.layers.Dropout(0.5)(X)  # Dropout比例调调,0.3到0.6都试试
    X = keras.layers.BatchNormalization()(X)  # 加批量归一化稳一稳
    predictions = Dense(3, activation='softmax')(X)
    
  • 处理类别不平衡:如果你的数据集三类样本数量差得多,要么给少数类加权重,要么用class_weight参数:
    # 比如统计后得到权重{0:1.2, 1:0.8, 2:1.0},按实际情况填
    model_final.fit_generator(..., class_weight=class_weights)
    

4. 优化训练策略

  • 别用固定学习率:试试学习率衰减或者自适应调整:
    # 指数衰减,每轮乘0.95
    lr_scheduler = LearningRateScheduler(lambda epoch: 0.001 * 0.95 ** epoch)
    # 或者验证损失不下降就减半学习率
    lr_reducer = keras.callbacks.ReduceLROnPlateau(monitor='val_loss', factor=0.5, patience=5, min_lr=1e-6)
    
  • 检查训练步数:steps_per_epoch和validation_steps得等于「数据集大小/batch_size」,别瞎填,不然训不够或者训多了。
  • 早停别太宽容:当前patience=40太大,改成10-15,模型过拟合了就赶紧停。

5. 先把数据集搞明白

  • 查标注错误:手动翻点样本,看看有没有标错的(比如把开心标成中性),错标样本是准确率杀手。
  • 平衡类别分布:统计三类样本数量,如果某类太少,要么复制少数类样本(过采样),要么删点多数类(欠采样),或者用图像合成工具造点少数类样本。
  • 验证集要靠谱:确保验证集是随机分的,和训练集场景一致,别训练集是摆拍的,验证集是真实抓拍的,那肯定不准。

6. 压一压过拟合

  • 加权重正则化:给全连接层加L2正则,防止权重飘得太厉害:
    Dense(256, activation='relu', kernel_regularizer=keras.regularizers.l2(0.001))
    
  • 严格用最优模型:靠ModelCheckpoint只存验证准确率最高的模型,别用过拟合后的模型评估。

内容的提问来源于stack exchange,提问作者Pratik Pradhan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 16:15:42