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

DenseNet模型训练出现Mul操作类型不匹配TypeError错误求助

计算机视觉模型训练类型不匹配错误解决

问题复现

我在训练基于DenseNet121的计算机视觉模型,模型构建代码:

# 创建预训练基础模型
base_model = DenseNet121(weights='/Users/awabe/Desktop/Project/PapilaDB/ClinicalData/DenseNet-BC-121-32-no-top.h5', include_top=False)

x = base_model.output

# 添加全局空间平均池化层
x = GlobalAveragePooling2D()(x)

# 添加逻辑回归层
predictions = Dense(len(labels), activation="sigmoid")(x)

model = Model(inputs=base_model.input, outputs=predictions)
model.compile(optimizer='adam', loss=get_weighted_loss(pos_weights, neg_weights))

训练及绘图代码:

history = model.fit_generator(train_generator, 
                              validation_data=test_generator,
                              steps_per_epoch=100, 
                              validation_steps=25, 
                              epochs = 3)

plt.plot(history.history['loss'])
plt.ylabel("loss")
plt.xlabel("epoch")
plt.title("Training Loss Curve")
plt.show()

运行后触发类型不匹配错误:

TypeError: 用户代码中出现错误:
File "/opt/anaconda3/envs/tensorflow/lib/python3.10/site-packages/keras/engine/training.py", line 1160, in train_function  *
    return step_function(self, iterator)
File "/var/folders/p4/gy9qtf594h3d5q85bzzgflz00000gn/T/ipykernel_1809/4264699890.py", line 27, in weighted_loss  *
    loss += -(K.mean((pos_weights[i] * y_true[:,i] * K.log(y_pred[:,i] + epsilon) + neg_weights[i]*(1-y_true[:,i]) * K.log(1-y_pred[:,i]+epsilon))))

TypeError: 'Mul'操作的输入'y'为float32类型,与参数'x'的int64类型不匹配。

问题原因

自定义加权损失函数中,pos_weights和neg_weights是int64整数类型,而模型输出的y_pred和标签y_true是float32浮点类型,张量乘法操作要求输入类型必须一致,因此触发类型不匹配错误。

解决方法

方法1:提前转换权重数据类型

在传入损失函数前,把权重数组转换为float32类型:

# 假设pos_weights和neg_weights是numpy数组
pos_weights = pos_weights.astype('float32')
neg_weights = neg_weights.astype('float32')

# 再编译模型
model.compile(optimizer='adam', loss=get_weighted_loss(pos_weights, neg_weights))

方法2:在损失函数内部转换类型

在损失函数计算时,用Keras的K.cast函数将权重转换为float32:

def get_weighted_loss(pos_weights, neg_weights):
    def weighted_loss(y_true, y_pred):
        epsilon = K.epsilon()
        loss = 0.0
        for i in range(len(pos_weights)):
            # 转换权重类型为float32
            pos_w = K.cast(pos_weights[i], dtype='float32')
            neg_w = K.cast(neg_weights[i], dtype='float32')
            loss += -(K.mean((pos_w * y_true[:,i] * K.log(y_pred[:,i] + epsilon) + neg_w*(1-y_true[:,i]) * K.log(1-y_pred[:,i]+epsilon))))
        return loss
    return weighted_loss

方法3:统一标签数据类型

检查train_generator和test_generator输出的标签类型,确保标签是float32格式。如果生成器输出的是整数标签,可以在生成器内部转换:

# 示例:在生成器中转换标签类型
def my_generator(...):
    # 原有逻辑获取x, y
    y = y.astype('float32')
    yield x, y

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 16:00:59