TensorFlow卷积层报错:输入为float tensor要求为double tensor如何解决?
问题根源
- 你混淆了TensorFlow和PyTorch的API:当前代码使用的是TensorFlow框架,张量类型为
EagerTensor,而你写的.type()、torch.from_numpy、DoubleTensor均为PyTorch语法,完全不兼容TensorFlow,因此会报属性不存在的错误 conv.double()写法无效:你定义的conv是lambda函数,本身没有double方法,这行代码无法起到转换张量类型的作用- 代码存在逻辑错误:函数参数传入的是x,但你内部调用了全局变量
X_train_tf,后续复用该层会出现异常
正确解决方法
提供两种可行方案,按需选择即可:
方案1:转换所有输入和参数为double类型(匹配conv要求的double输入)
修改后的卷积层代码如下:
import tensorflow as tf def convLayer(x, kHeight, kWidth, strideX, strideY, featureNum, name, padding = "SAME", groups = 1): """convolution""" # 用函数参数x,不要硬编码全局的X_train_tf channel = int(x.get_shape()[-1]) # 卷积计算时统一将输入转为double类型,TensorFlow中double对应tf.float64 def conv(a, b): a_double = tf.cast(a, dtype=tf.float64) b_double = tf.cast(b, dtype=tf.float64) return tf.nn.conv2d(a_double, b_double, strides = [1, strideY, strideX, 1], padding = padding) with tf.compat.v1.variable_scope(name) as scope: # 权重参数直接定义为float64类型,避免后续转换损耗 w = tf.compat.v1.get_variable("w", shape = [kHeight, kWidth, int(channel/groups), featureNum], dtype=tf.float64) b = tf.compat.v1.get_variable("b", shape = [featureNum], dtype=tf.float64) xNew = tf.split(value = x, num_or_size_splits = groups, axis = 3) wNew = tf.split(value = w, num_or_size_splits = groups, axis = 3) featureMap = [conv(t1, t2) for t1, t2 in zip(xNew, wNew)] mergeFeatureMap = tf.concat(axis = 3, values = featureMap) print(mergeFeatureMap.shape) out = tf.nn.bias_add(mergeFeatureMap, b) return tf.nn.relu(tf.reshape(out, mergeFeatureMap.get_shape().as_list()), name = scope.name)
方案2:调整卷积要求为float类型(更推荐,训练速度更快、显存占用更低)
如果没有强制的double精度要求,直接将所有参数和输入统一为float32即可,无需转double:
import tensorflow as tf def convLayer(x, kHeight, kWidth, strideX, strideY, featureNum, name, padding = "SAME", groups = 1): """convolution""" channel = int(x.get_shape()[-1]) conv = lambda a, b: tf.nn.conv2d(a, b, strides = [1, strideY, strideX, 1], padding = padding) with tf.compat.v1.variable_scope(name) as scope: # 显式指定权重为float32,和TensorFlow默认输入类型匹配 w = tf.compat.v1.get_variable("w", shape = [kHeight, kWidth, int(channel/groups), featureNum], dtype=tf.float32) b = tf.compat.v1.get_variable("b", shape = [featureNum], dtype=tf.float32) xNew = tf.split(value = x, num_or_size_splits = groups, axis = 3) wNew = tf.split(value = w, num_or_size_splits = groups, axis = 3) featureMap = [conv(t1, t2) for t1, t2 in zip(xNew, wNew)] mergeFeatureMap = tf.concat(axis = 3, values = featureMap) print(mergeFeatureMap.shape) out = tf.nn.bias_add(mergeFeatureMap, b) return tf.nn.relu(tf.reshape(out, mergeFeatureMap.get_shape().as_list()), name = scope.name)
注意事项
- TensorFlow中张量类型转换统一使用
tf.cast(张量, dtype=目标类型),float32对应单精度float,float64对应双精度double - 不要跨框架混用API,使用TensorFlow时所有张量操作都调用tf开头的方法,不要调用PyTorch相关方法
- 自定义层尽量使用传入的参数,不要硬编码全局变量,避免后续调用出现异常
内容的提问来源于stack exchange,提问作者Francisco Nieto
相关产品推荐
相关产品推荐

