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
相关产品推荐
相关产品推荐

