在复现网络的时候遇到一个问题,在使用tf.nn.conv2d_transpose()实现转置卷积的时候,该函数里面有个参数是output_shape,需要确定输出tensor的shape,由于在建立网络的时候最开始使用的是占位符(placeholder)
images = tf.placeholder(tf.float32, [None, self.cfgs["training"]['image_height'], self.cfgs["training"]['image_width'], self.cfgs["training"]['n_channels']])
这里对于batch_size并没有确定,而是用了None代替。
而在确定转置卷积的output_shape的时候就会导致batch_size也是不定的
所以,如何动态设置反卷积tf.nn.conv2d_transpose()
的output_shape的batch_size
我看到的有两种解决办法:
1、设置一个全局变量,global_batch_size
,在这个全局的变量里面获取batch_size。但是这个方法感觉还是没有很“动态”
2、另一个是获得输入tensor的shape的tensor:
in_shape_tensor=tf.shape(input)
tf.shape()返回的是目标tensor的shape的tensor,在建立网络的时候他是没有定义的,只有在运行的时候才能知道是多少,也就是这个shape是动态的
def de_conv(self,input,out_channal=1,up_scale=1,padding='SAME',name="upsample_bilinear"):
in_shape_tensor=tf.shape(input)
in_shape=input.shape.as_list()
strides=[1,up_scale,up_scale,1]
w_shape=[up_scale*2,up_scale*2,in_shape[-1],1]
out_shape=tf.stack([in_shape_tensor[0],in_shape_tensor[1],in_shape_tensor[2],w_shape[2]])* tf.constant(strides, tf.int32)
weight=self.weight_variable(w_shape)
tf.summary.histogram('weights_{}'.format(name), weight)
tran_conv=tf.nn.conv2d_transpose(input,weight,out_shape,strides)
return tran_conv
附:我在复现的时候遇到另一个问题,用上面方法二创建的反卷积层是动态的,会导致如果在反卷积层后面获得的tensor的shape会是[?,?,?,?]
,如果这时候再根据这个输出tensor的shape来在下一个卷积层里算一些确定的值,会出错,因为这里的shape在建立的时候是不确定的,所以如果使用方法二有这个缺点
如果朋友们有其他好的方法,欢迎交流
参考:https://stackoverflow.com/questions/46885191/tf-nn-conv2d-transpose-output-shape-dynamic-batch-size