You need to enable JavaScript to run this app. 使用Keras Lambda实现视频序列标注CTC对齐时触发Squeeze维度报错
优惠活动
大模型
产品
解决方案
定价
更多

使用Keras Lambda实现视频序列标注CTC对齐时触发Squeeze维度报错

报错根因定位

这个报错和视频/语音的模态适配没有任何关系,本质是传入K.ctc_batch_cost的张量维度完全不满足API要求。
内部的Squeeze操作逻辑是:K.ctc_batch_cost会对input_length、label_length张量执行squeeze,默认要求这两个张量的形状为[batch_size, 1],自动挤掉最后大小为1的维度。现在传入的对应张量形状是[?, 3],最后一维大小为3,没有可squeeze的维度,直接触发报错。

代码中的具体维度错位问题:

  • 错误将静态numpy数组y_train、X_train_length直接传入Lambda层的入参列表。Lambda层的入参必须是接入计算图的Keras张量(即Input层输出、或之前网络层的输出),静态numpy数组无固定计算图维度属性,会直接造成形状错位。
  • Input层的shape定义不符合要求:定义input_length、label_length时,直接把numpy数组的shape当参数传入,最终得到的张量是一维形状,没有保证最后一维大小为1,不满足CTC API的入参规范。
  • labels的类型和填充规则错误:用float32类型的全1数组填充标签,CTC要求labels为int32类型的整数索引,浮点值既不满足类型校验,填充逻辑也不符合空白标签的设置规则。
  • 给Lambda层硬编码output_shape=(208,30)完全多余:CTC损失的输出形状是[batch_size](每个样本对应一个损失值),硬写的形状和实际输出完全不匹配,会进一步引发维度冲突。
适配视频序列标注的CTC实现修正方案

CTC的损失逻辑对输入模态无任何偏好,不管是语音帧序列、视频抽帧序列、文本token序列,只要满足“时序步长 > 标签序列长度”的对齐前提,完全可以复用语音场景的Lambda逻辑,不需要针对视频做特殊改造,只需要把维度对齐到API要求即可:

  • 严格按维度要求定义CTC相关的输入层:
# 主输入为视频抽帧后的时序特征:形状[batch, 视频抽帧数, 单帧特征维度]
# labels:形状[batch, 最大标签序列长度],整数类型存储标签索引
labels = Input(name='the_labels', shape=[None], dtype='int32')
# input_length:必须为[batch, 1]的二维形状,记录每个样本的有效视频时序长度
input_length = Input(name='input_length', shape=[1], dtype='int64')
# label_length:必须为[batch, 1]的二维形状,记录每个样本的有效标签序列长度
label_length = Input(name='label_length', shape=[1], dtype='int64')
  • 修正Lambda层的CTC计算逻辑,去掉无意义的硬编码截断:
def ctc_lambda_func(args):
    y_pred, labels, input_length, label_length = args
    # 原语音代码里的前2步截断是适配RNN初始输出垃圾值的逻辑
    # 视频场景如果没有固定的前2步无效输出,直接删掉这行即可,不需要硬套语音的截断规则
    # y_pred = y_pred[:, 2:, :]
    return K.ctc_batch_cost(labels, y_pred, input_length, label_length)
  • 正确连接计算图,移除硬编码的输出形状:
loss_out = Lambda(
    function=ctc_lambda_func,
    name='ctc'
)([y_pred, labels, input_length, label_length])
  • 视频场景的特殊适配注意点:
  • 构建训练模型时,损失设为lambda y_true, y_pred: y_pred,因为CTC损失已经在Lambda层完成计算,不需要额外传入损失值;训练时的标签输入可以用零值占位,计算过程不会用到这个占位值。
  • 必须满足CTC对齐的前提:单样本的有效视频抽帧数量,要大于对应标注的标签序列长度,否则CTC对齐会直接失效。比如一段5秒视频抽了50帧,对应动作标注有20个,是符合要求的;如果只抽了10帧,会因为时序步长不足触发对齐错误。
  • 最后的softmax输出层要预留1个空白占位类(CTC要求的blank类):比如要标注5类动作,最后全连接层的神经元数量要设为6,留1个类作为blank占位,这部分逻辑和语音任务完全一致,不需要额外修改。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.08 11:27:04