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

如何解决Python训练孟加拉手语识别模型时出现的负维度尺寸错误

孟加拉手语识别模型训练报错排查

问题描述

我正在尝试构建用于孟加拉手语识别的模型,但在拟合模型时触发报错,相关代码如下:

import numpy as np
import matplotlib.pyplot as plt
import os
import cv2
from tqdm import tqdm
import tensorflow as tf

DATADIR = '/content/drive/MyDrive/Dataset/BSL Alphabet'

CATEGORIES =['1','2','3','4','5','6','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','Z1','Z2','Z3',]

for category in CATEGORIES:
    path = os.path.join(DATADIR, category)
    for img in os.listdir(path):
        img_array = cv2.imread(os.path.join(path, img), cv2.IMREAD_GRAYSCALE)
        plt.imshow(img_array, cmap='gray')
        plt.show()
        break
    break

batch_size = 32
img_height = 100
img_width = 100
train_ds = tf.keras.preprocessing.image_dataset_from_directory(
    DATADIR,validation_split=0.2,subset='training',seed=123,
    image_size=(img_height, img_width),
    batch_size=batch_size,
)
val_ds = tf.keras.preprocessing.image_dataset_from_directory(
    DATADIR,validation_split=0.2,subset='validation',seed=123,
    image_size=(img_height, img_width),
    batch_size=batch_size,
)
AUTOTUNE = tf.data.AUTOTUNE

train_ds = train_ds.cache().prefetch(buffer_size=AUTOTUNE)
val_ds = val_ds.cache().prefetch(buffer_size=AUTOTUNE)
num_classes = 36

model = tf.keras.Sequential([
    tf.keras.layers.experimental.preprocessing.Rescaling(1.0 / 255),
    tf.keras.layers.Conv2D(16, 3, activation='relu', input_shape=(100,100, 3)),
    tf.keras.layers.BatchNormalization(),
    tf.keras.layers.MaxPooling2D(pool_size=(2, 2)),
    tf.keras.layers.Conv2D(32, 3, activation='relu'),
    tf.keras.layers.BatchNormalization(),
    tf.keras.layers.MaxPooling2D(pool_size=(2, 2)),
    tf.keras.layers.Conv2D(64, 3, activation='relu'),
    tf.keras.layers.BatchNormalization(),
    tf.keras.layers.MaxPooling2D(pool_size=(2, 2)),
    tf.keras.layers.Conv2D(128, 3, activation='relu'),
    tf.keras.layers.BatchNormalization(),
    tf.keras.layers.MaxPooling2D(pool_size=(2, 2)),
    tf.keras.layers.Conv2D(256, 3, activation='relu'),
    tf.keras.layers.BatchNormalization(),
    tf.keras.layers.MaxPooling2D(pool_size=(2, 2)),
    tf.keras.layers.Conv2D(512, 3, activation='relu'),
    tf.keras.layers.BatchNormalization(),
    tf.keras.layers.MaxPooling2D(pool_size=(2, 2)),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(84, activation='relu'),
    tf.keras.layers.Dropout(0.5),
    tf.keras.layers.Dense(num_classes, activation='softmax'),
    ])

model.compile(optimizer='adam', 
loss=tf.losses.SparseCategoricalCrossentropy(from_logits=True),
      metrics=['accuracy'])
model.fit(train_ds, validation_data=val_ds, epochs=3)

运行代码后报错信息如下:

Epoch 1/3
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
 in ()
2   train_ds,
3   validation_data=val_ds,
----> 4   epochs=3
5 )

9 frames
/usr/local/lib/python3.7/dist-packages/tensorflow/python/framework/func_graph.py in wrapper(*args, **kwargs)
    992           except Exception as e:  # pylint:disable=broad-except
    993             if hasattr(e, "ag_error_metadata"):
--> 994               raise e.ag_error_metadata.to_exception(e)
    995             else:
    996               raise

ValueError: in user code:

    /usr/local/lib/python3.7/dist-packages/keras/engine/training.py:853 train_function  *
        return step_function(self, iterator)
    /usr/local/lib/python3.7/dist-packages/keras/engine/training.py:842 step_function  **
        outputs = model.distribute_strategy.run(run_step, args=(data,))
    /usr/local/lib/python3.7/dist-packages/tensorflow/python/distribute/distribute_lib.py:1286 run
        return self._extended.call_for_each_replica(fn, args=args, kwargs=kwargs)
    /usr/local/lib/python3.7/dist-packages/tensorflow/python/distribute/distribute_lib.py:2849 call_for_each_replica
        return self._call_for_each_replica(fn, args, kwargs)
    /usr/local/lib/python3.7/dist-packages/tensorflow/python/distribute/distribute_lib.py:3632 _call_for_each_replica
        return fn(*args, **kwargs)
    /usr/local/lib/python3.7/dist-packages/keras/engine/training.py:835 run_step  **
        outputs = model.train_step(data)
    /usr/local/lib/python3.7/dist-packages/keras/engine/training.py:787 train_step
        y_pred = self(x, training=True)
    /usr/local/lib/python3.7/dist-packages/keras/engine/base_layer.py:1037 __call__
        outputs = call_fn(inputs, *args, **kwargs)
    /usr/local/lib/python3.7/dist-packages/keras/engine/sequential.py:383 call
        outputs = layer(inputs, **kwargs)
    /usr/local/lib/python3.7/dist-packages/keras/engine/base_layer.py:1037 __call__
        outputs = call_fn(inputs, *args, **kwargs)
    /usr/local/lib/python3.7/dist-packages/keras/layers/pooling.py:360 call
        data_format=conv_utils.convert_data_format(self.data_format, 4))
    /usr/local/lib/python3.7/dist-packages/tensorflow/python/util/dispatch.py:206 wrapper
        return target(*args, **kwargs)
    /usr/local/lib/python3.7/dist-packages/tensorflow/python/ops/nn_ops.py:4783 max_pool
        name=name)
    /usr/local/lib/python3.7/dist-packages/tensorflow/python/ops/gen_nn_ops.py:5344 max_pool
        data_format=data_format, name=name)
    /usr/local/lib/python3.7/dist-packages/tensorflow/python/framework/op_def_library.py:750 _apply_op_helper
        attrs=attr_protos, op_def=op_def)
    /usr/local/lib/python3.7/dist-packages/tensorflow/python/framework/func_graph.py:601 _create_op_internal
        compute_device)
    /usr/local/lib/python3.7/dist-packages/tensorflow/python/framework/ops.py:3569 _create_op_internal
        op_def=op_def)
    /usr/local/lib/python3.7/dist-packages/tensorflow/python/framework/ops.py:2042 __init__
        control_input_ops, op_def)
    /usr/local/lib/python3.7/dist-packages/tensorflow/python/framework/ops.py:1883 _create_c_op
        raise ValueError(str(e))

    ValueError: Negative dimension size caused by subtracting 2 from 1 for '{{node sequential_3/max_pooling2d_22/MaxPool}} = MaxPool[T=DT_FLOAT, data_format="NHWC", explicit_paddings=[], ksize=[1, 2, 2, 1], padding="VALID", strides=[1, 2, 2, 1]](sequential_3/batch_normalization_22/FusedBatchNormV3)' with input shapes: [?,1,1,256].

报错原因

核心问题是堆叠的卷积+池化层数过多,输入的100x100尺寸图像经过多次卷积和2倍下采样后,特征图尺寸被压缩到1x1,此时再执行2x2的最大池化操作,就会出现维度为负的错误。

附带存在参数冲突问题:损失函数设置了from_logits=True,但输出层使用了softmax激活,二者逻辑冲突,会导致模型收敛异常。

解决方案

可任选以下一种方案解决维度报错问题:

  • 减少网络层数:删除最后一组Conv2D(512, 3)、BatchNormalization、MaxPooling2D三层结构,保留前5组卷积池化即可。
  • 调整卷积填充方式:给所有Conv2D层增加padding='same'参数,保证卷积操作不会缩小特征图尺寸,仅池化时进行下采样。
  • 增大输入尺寸:将img_height和img_width从100调整为224,足够支撑6次下采样的尺寸需求。

同时修正损失函数参数冲突,可二选一调整:

  • 将损失函数的from_logits=True改为from_logits=False
  • 删除输出层Dense的activation='softmax'参数

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 21:18:03