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

CNN训练自定义图像时SparseCategoricalCrossentropy类型错误

问题

用CNN训练自定义图像,已将class_mode设为sparse,选用SparseCategoricalCrossentropy损失函数,但训练时出现「无法将元素转换为张量」的TypeError,更换其他损失函数问题仍存在,怀疑数据格式有误,附上相关代码及报错栈。

数据生成器与网络代码

train_datagen = ImageDataGenerator(
rescale=1./255,
width_shift_range=.05,
height_shift_range=.05,
zoom_range=0.05,
validation_split=0.3,
horizontal_flip=True,
vertical_flip=True,
fill_mode="constant",
cval=0)

test_datagen = ImageDataGenerator(
rescale=1./255)
    
#data augmentation
train_ds = train_datagen.flow_from_directory(
train_data_dir,
shuffle=True,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode='sparse',
subset='training');

cnn = Sequential()
cnn.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=(img_width,img_height,3)))
cnn.add(BatchNormalization())

cnn.add(Conv2D(32, kernel_size=(3, 3), activation='relu'))
cnn.add(BatchNormalization())
cnn.add(MaxPooling2D(pool_size=(2, 2)))
cnn.add(Dropout(0.2))

cnn.add(Conv2D(64, kernel_size=(3, 3), activation='relu'))
cnn.add(BatchNormalization())

cnn.add(Flatten())

cnn.add(Dense(64, activation='relu'))
cnn.add(Dense(22, activation='softmax'))

cnn.compile(loss=keras.losses.SparseCategoricalCrossentropy,
              optimizer="Adam",
              metrics=['accuracy'])

完整报错栈

--------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In [24], line 111
    106 cnn.compile(loss=keras.losses.SparseCategoricalCrossentropy,
    107               optimizer="Adam",
    108               metrics=['accuracy'])
    110 epochs=20
--> 111 history = cnn.fit(
    112   train_ds,
    113   validation_data=valid_ds,
    114   steps_per_epoch=math.ceil(len(train_ds) / batch_size),
    115   epochs=epochs)
    117 plt.plot(history.history['loss'], label='train')
    118 plt.plot(history.history['val_loss'], label='validation')

File ~\AppData\Local\Programs\Python\Python310\lib\site-packages\keras\utils\traceback_utils.py:70, in filter_traceback.<locals>.error_handler(*args, **kwargs)
     67     filtered_tb = _process_traceback_frames(e.__traceback__)
     68     # To get the full stack trace, call:
     69     # `tf.debugging.disable_traceback_filtering()`
---&gt; 70     raise e.with_traceback(filtered_tb) from None
     71 finally:
     72     del filtered_tb

File ~\AppData\Local\Temp\__autograph_generated_fileswqeb6ya.py:15, in outer_factory.<locals>.inner_factory.<locals>.tf__train_function(iterator)
     13 try:
     14     do_return = True
---&gt; 15     retval_ = ag__.converted_call(ag__.ld(step_function), (ag__.ld(self), ag__.ld(iterator)), None, fscope)
     16 except:
     17     do_return = False

TypeError: in user code:

    File "C:\Users\maiaz\AppData\Local\Programs\Python\Python310\lib\site-packages\keras\engine\training.py", line 1160, in train_function  *
        return step_function(self, iterator)
    File "C:\Users\maiaz\AppData\Local\Programs\Python\Python310\lib\site-packages\keras\engine\training.py", line 1146, in step_function  **
        outputs = model.distribute_strategy.run(run_step, args=(data,))
    File "C:\Users\maiaz\AppData\Local\Programs\Python\Python310\lib\site-packages\keras\engine\training.py", line 1135, in run_step  **
        outputs = model.train_step(data)
    File "C:\Users\maiaz\AppData\Local\Programs\Python\Python310\lib\site-packages\keras\engine\training.py", line 994, in train_step
        loss = self.compute_loss(x, y, y_pred, sample_weight)
    File "C:\Users\maiaz\AppData\Local\Programs\Python\Python310\lib\site-packages\keras\engine\training.py", line 1052, in compute_loss
        return self.compiled_loss(
    File "C:\Users\maiaz\AppData\Local\Programs\Python\Python310\lib\site-packages\keras\engine\compile_utils.py", line 265, in __call__
        loss_value = loss_obj(y_t, y_p, sample_weight=sw)
    File "C:\Users\maiaz\AppData\Local\Programs\Python\Python310\lib\site-packages\keras\losses.py", line 158, in __call__
        return losses_utils.compute_weighted_loss(
    File "C:\Users\maiaz\AppData\Local\Programs\Python\Python310\lib\site-packages\keras\utils\losses_utils.py", line 328, in compute_weighted_loss
        losses = tf.convert_to_tensor(losses)

    TypeError: Failed to convert elements of <keras.losses.SparseCategoricalCrossentropy object at 0x0000017523557AC0> to Tensor. Consider casting elements to a supported type. See https://www.tensorflow.org/api_docs/python/tf/dtypes for supported TF dtypes.

解决方案

核心错误原因

你在compile方法中传入损失函数时,直接使用了keras.losses.SparseCategoricalCrossentropy(类本身),而非实例化后的对象。Keras要求接收损失函数的实例,而非类引用,这才是导致张量转换失败的根本原因,和数据格式无关。

修正代码

将损失函数改为实例化形式:

cnn.compile(loss=keras.losses.SparseCategoricalCrossentropy(),  # 添加括号完成实例化
              optimizer="Adam",
              metrics=['accuracy'])

或者使用更简洁的字符串形式(Keras会自动对应到损失函数实例):

cnn.compile(loss='sparse_categorical_crossentropy',
              optimizer="Adam",
              metrics=['accuracy'])

额外检查点

  • 确认valid_ds的创建参数和train_ds保持一致,同样设置class_mode='sparse',避免验证集标签格式不匹配
  • steps_per_epoch计算有误:len(train_ds)本身就是训练集的批次数量,无需再除以batch_size,直接使用steps_per_epoch=len(train_ds)即可,否则会导致每个epoch重复训练多轮

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 01:10:54