构建CNN模型时遇类型转换错误:请求int64但输入为float32
模型训练类型不匹配错误排查
尝试构建模型(注:代码中实际为全连接网络,非CNN)时出现类型转换错误,已尝试手动类型转换但未解决,相关代码及报错如下:
相关代码
自定义评分函数
C1, C2 = tf.constant(70, dtype='float32'), tf.constant(1000, dtype="float32") def score(y_true, y_pred): tf.dtypes.cast(y_true, tf.float32) tf.dtypes.cast(y_pred, tf.float32) sigma = y_pred[:, 2] - y_pred[:, 0] fvc_pred = y_pred[:, 1] # sigma_clip = sigma + C1 sigma_clip = tf.maximum(sigma, C1) delta = tf.abs(y_true[:, 0] - fvc_pred) delta = tf.minimum(delta, C2) sq2 = tf.sqrt(tf.dtypes.cast(2, dtype=tf.float32)) metric = (delta / sigma_clip) * sq2 + tf.math.log(sigma_clip * sq2) return K.mean(metric)
自定义损失函数
def mloss(_lambda): def loss(y_true, y_pred): return _lambda * qloss(y_true, y_pred) + (1 - _lambda) * score(y_true, y_pred) return loss
模型构建代码
def make_model(): z = L.Input((9,), name="Patient") x = L.Dense(100, activation="relu", name="d1")(z) x = L.Dense(100, activation="relu", name="d2")(x) p1 = L.Dense(3, activation="linear", name="p1")(x) p2 = L.Dense(3, activation="relu", name="p2")(x) preds = L.Lambda(lambda x: x[0] + tf.cumsum(x[1], axis=1), name="preds")([p1, p2]) model = M.Model(z, preds, name="CNN") model.compile(loss=mloss(0.8), optimizer="adam", metrics=[score]) return model
训练代码
net = make_model() net.fit(z[tr_idx], y[tr_idx], batch_size=200, epochs=1000, validation_data=(z[val_idx], y[val_idx]), verbose=0)
报错信息
ValueError: Tensor conversion requested dtype int64 for Tensor with dtype float32: <tf.Tensor 'CNN/preds/add:0' shape=(None,3) dtype=float32>
错误原因及解决方案
核心问题
- 评分函数中类型转换未生效:
tf.dtypes.cast是返回新张量的函数,不会原地修改原变量,原代码中仅调用转换但未将结果赋值给y_true/y_pred,导致后续计算时原变量仍保持int64类型,与模型输出的float32张量冲突。 - 输入/标签数据类型不匹配:训练数据
z或标签y可能是int64类型,与模型输出的float32类型不兼容,触发类型转换请求失败。
修复步骤
- 修正评分函数的类型转换:将转换后的张量重新赋值给原变量,确保类型统一:
def score(y_true, y_pred): y_true = tf.dtypes.cast(y_true, tf.float32) # 赋值生效 y_pred = tf.dtypes.cast(y_pred, tf.float32) # 赋值生效 sigma = y_pred[:, 2] - y_pred[:, 0] fvc_pred = y_pred[:, 1] sigma_clip = tf.maximum(sigma, C1) delta = tf.abs(y_true[:, 0] - fvc_pred) delta = tf.minimum(delta, C2) sq2 = tf.sqrt(tf.dtypes.cast(2, dtype=tf.float32)) metric = (delta / sigma_clip) * sq2 + tf.math.log(sigma_clip * sq2) return K.mean(metric)
- 统一训练数据类型:在训练前将输入数据和标签转换为float32:
z = z.astype('float32') y = y.astype('float32')
- 检查qloss函数:如果
qloss涉及y_true和y_pred的运算,同样需要确保类型统一,避免类似冲突。
内容的提问来源于stack exchange,提问作者Quan Do
相关产品推荐
相关产品推荐

