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

基于MobileNetV2的Keras模型预测恒定及多样性低问题咨询

问题背景与模型情况

我正在构建一个基于MobileNetV2的Keras模型,用于对6项人类能力进行帧级预测。每个输出头对应一项能力,采用100分类(分数0-99)的softmax输出。模型输入为归一化到[-1,1]的224×224 RGB帧(与MobileNetV2预处理兼容),数据集规模较小(138段5分钟视频逐帧处理)。

模型简化代码如下:

def create_model(input_shape):
    inputs = tf.keras.Input(shape=input_shape)

    base_model = MobileNetV2(
        input_tensor=inputs,
        weights='imagenet',
        include_top=False,
        pooling='avg'
    )

    for layer in base_model.layers:
        layer.trainable = False

    for layer in base_model.layers[-20:]:
        layer.trainable = True
        
    x = base_model.output
    x = layers.BatchNormalization()(x)
    x = layers.Dense(256, use_bias=False)(x)
    x = layers.BatchNormalization()(x)
    x = layers.Activation('relu')(x)
    x = layers.Dropout(0.3)(x)
    x = layers.BatchNormalization()(x)

    outputs = [
        layers.Dense(
            100, 
            activation='softmax',
            kernel_initializer='he_uniform',
            dtype='float32',
            name=comp
        )(x) 
        for comp in LABELS
    ]

    model = tf.keras.Model(inputs=inputs, outputs=outputs)

    lr_schedule = tf.keras.optimizers.schedules.CosineDecay(
        initial_learning_rate=1e-4,
        decay_steps=steps_per_epoch*EPOCHS,
        warmup_target=5e-3,
        warmup_steps=steps_per_epoch
    )

    opt = tf.keras.optimizers.Adam(lr_schedule, clipnorm=1.0)
    opt = tf.keras.mixed_precision.LossScaleOptimizer(opt)

    model.compile(
        optimizer=opt,
        loss={comp: tf.keras.losses.SparseCategoricalCrossentropy() 
              for comp in LABELS},
        metrics=['accuracy']
    )
    return model

模型出现异常表现:训练集上准确率极高(疑似过拟合),但训练后对不同输入(甚至随机输入)均输出相同的向量;预训练阶段的预测多样性也极低,测试代码如下:

test_input = np.random.rand(1, 224, 224, 3).astype(np.float32)
predictions = model.predict(test_input)
print("Pre-train prediction diversity:", [np.std(p) for p in predictions])
技术问题
  1. 为何训练后的模型对不同输入(包括随机输入)均输出相同的向量?
  2. 为何预训练阶段的输出多样性如此之低?

问题解答

1. 训练后模型输出固定向量的原因及解决思路

  • 过拟合到极端样本/标签分布:小数据集下模型极易记住训练数据的统计特征,若训练集中某类标签占比过高,或存在大量重复帧,模型会直接输出该类概率分布,完全忽略输入特征。
  • BatchNormalization层冗余导致特征坍缩:代码中在base_model输出后连续叠加多个BatchNormalization层,训练时BN使用当前批次的均值方差,而推理阶段依赖训练累积的统计量。小数据集下训练批次小,累积的均值方差易失真,导致BN层输出近乎固定的数值,后续全连接层也随之输出固定结果。
  • 学习率与梯度裁剪设置不合理:CosineDecay的初始学习率1e-4到warmup_target5e-3跨度太大,加上clipnorm=1.0可能过度限制梯度,或warmup阶段学习率突增让模型参数更新到极端值,后续无法调整。
  • 解决建议:
    • 加入数据增强:对视频帧做随机裁剪、翻转、颜色扰动,扩充数据集多样性,缓解过拟合。
    • 精简BatchNormalization层:base_model本身已包含BN层,后续仅保留必要的BN(比如Dense(256)后加一次即可),避免多次BN引发的特征坍缩。
    • 调整学习率策略:降低warmup_target(比如设为1e-4),放宽clipnorm阈值或暂时移除,观察参数更新情况。
    • 添加正则化:在Dense层加入kernel_regularizer=tf.keras.regularizers.l2(1e-4),限制参数范围,防止过拟合到极端值。

2. 预训练阶段输出多样性低的原因及解决思路

  • 测试输入预处理不匹配:测试用随机输入是np.random.rand生成的[0,1]范围数据,但模型要求输入归一化到[-1,1],输入分布与训练数据完全不符,MobileNetV2的预训练特征无法被有效激活,导致输出方差极低。
  • 初始化与未训练层的限制:虽然解冻了base_model最后20层,但其余层冻结,预训练阶段(未训练或仅少量轮次),base_model的大部分特征仍保留ImageNet通用特征,未学习到适配当前任务的特征;加上顶部Dense层初始化后未经过足够训练,输出分布自然集中。
  • 解决建议:
    • 对齐测试输入预处理:将随机输入归一化到[-1,1],即test_input = (np.random.rand(1,224,224,3)*2 -1).astype(np.float32),再测试输出多样性。
    • 分阶段训练:先冻结整个base_model,单独训练顶部Dense层和输出头,让模型先适配当前任务的标签分布,再解冻部分base_model层微调。
    • 调整初始化方式:尝试用glorot_uniform初始化输出层,或初始化后对输出层参数做小幅度扰动,增加初始输出的多样性。

内容的提问来源于stack exchange,提问作者asfa afs

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 23:39:56