对占位符x进行反卷积操作。因为占位符中batch_size设置为None,而tf.nn.conv2d_transpose函数需要指定output_shape, 于是使用tf.shape()函数构建output_shape,让output_shape的batch_size保持与x动态一致。代码如下。
import tensorflow as tf
def unconv(x):
x= tf.reshape(x, [-1, 32, 1, 64])
output_shape = [tf.shape(x)[0], tf.shape(x)[1]*2, tf.shape(x)[2], tf.shape(x)[3]]
batch, h, w, channels = x.get_shape().as_list()
# 使用tf.shape()得到的是tensor,用于初始化权值变量时,这个维度变量也需要初始化,这时就会
# 面临占位符没有no feed的问题。
initial_state = tf.random.uniform([3, 1, tf.shape(x)[3], tf.shape(x)[3]], minval = -1, maxval = 1)
filter_w = tf.Variable(initial_state)
return tf.nn.conv2d_transpose(input = x, filters = filter_w, output_shape = output_shape, padding = "SAME", strides = [1,2,1,1])
if __name__ == "__main__":
tf.compat.v1.disable_eager_execution()
x = tf.compat.v1.placeholder(dtype = tf.float32, shape = [None, 2048])
y = unconv(x)
num = 32
input_list = [[1. for i in range(2048)] for i in range(num)]
with tf.compat.v1.Session() as sess:
tf.compat.v1.global_variables_initializer().run()
y = y.eval(feed_dict = {x: input_list})
print(tf.shape(y))
运行上述代码,tensorflow会在变量初始化时报错,说You must feed a value for placeholder tensor 'Placeholder' with dtype float and shape. 哟,这可难为人了。因为变量初始化的时候不需要给占位符赋值的。那这里为什么会报这个错误呢。
这就是因为当我们使用tf.shape()获取x的维度时,返回的是tensor变量。然后我们在创建权值变量时,即下面代码中,把权值变量的维度设定成了一个tensor。变量初始化到这个initial_state的时候便会报错。
initial_state = tf.random.uniform([3, 1, tf.shape(x)[3], tf.shape(x)[3]], minval = -1, maxval = 1)
这时,我们可以把这段代码进行修改。把它变成下面的样子就能避免错误了:
batch, h, w, channels = x.get_shape().as_list()
initial_state = tf.random.uniform([3, 1, channels , channels], minval = -1, maxval = 1)
此时修改的完整代码如下。再次运行就不会报错了。
import tensorflow as tf
def unconv(x):
x= tf.reshape(x, [-1, 32, 1, 64])
output_shape = [tf.shape(x)[0], tf.shape(x)[1]*2, tf.shape(x)[2], tf.shape(x)[3]]
batch, h, w, channels = x.get_shape().as_list()
# 使用tf.shape()得到的是tensor,用于初始化权值变量时,这个维度变量也需要初始化,这时就会
# 面临占位符没有no feed的问题。
batch, h, w, channels = x.get_shape().as_list()
initial_state = tf.random.uniform([3, 1, channels, channels], minval = -1, maxval = 1)
filter_w = tf.Variable(initial_state)
return tf.nn.conv2d_transpose(input = x, filters = filter_w, output_shape = output_shape, padding = "SAME", strides = [1,2,1,1])
if __name__ == "__main__":
tf.compat.v1.disable_eager_execution()
x = tf.compat.v1.placeholder(dtype = tf.float32, shape = [None, 2048])
y = unconv(x)
num = 32
input_list = [[1. for i in range(2048)] for i in range(num)]
with tf.compat.v1.Session() as sess:
tf.compat.v1.global_variables_initializer().run()
y = y.eval(feed_dict = {x: input_list})
print(tf.shape(y))
tf.shape()与get_shape()的功能都是获得tensor的维度,但是它们可以使用的场景是完全不同的,所以用起来还是要小心一点儿。