我正在编写一个自定义的递归神经网络。网络状态在while循环体中定义,并且当某个条件发生时递归停止。我想使用迭代次数作为循环内部某些函数的参数。例如,当我使用萎缩卷曲时,我希望扩张速度取决于当前的迭代。
def body(self,..., iteration):
dilation_rate = 2**iteration
state = tf.nn.atrous_conv2d(..., rate = dilation_rate)
iteration += 1
def RNN_loop(...)
iter = tf.constant(np.array(0), dtype = tf.int32)
... = tf.while_loop(self.condition, self.body, [...,iter])
因为迭代被定义为张量,所以我不知道如何将它传递给期望数字的atrous_conv2d。如果我尝试使用iteration.eval来评估循环内张量的值,我得到:
ValueError: Operation u'layer/while/Identity_4' has been marked as not fetchable.
如果我将张量传递给我得到的函数:
ValueError: setting an array element with a sequence.
答案 0 :(得分:0)
TL; DR :使用tf.nn.convolution()
代替tf.nn.atrous_conv2d()
并短路tf.nn._nn_ops._get_strides_and_dilation_rate()
。 (请参阅答案底部的代码示例。)
<强> TS; WM 强>:
tf.nn.atrous_conv2d()
的实施基本上只需调用tf.nn.convolution()
,dilation_rate
设置为[rate, rate]
。 This是源代码中的当前位置,但我在此处复制它(没有130行注释),因为它可能会更改,因此链接可能会过时:
def atrous_conv2d(value, filters, rate, padding, name=None):
return convolution(
input=value,
filter=filters,
padding=padding,
dilation_rate=np.broadcast_to(rate, (2,)),
name=name)
在此明确np.broadcast_to()
使dilation_rate
无法使用张量。tf.nn.convolution()
。也许在_get_strides_and_dilation_rate()
那么?
嗯,理论上,是的,直到调用dilation_rate = np.array(dilation_rate, dtype=np.int32)
,其中最无益的是
Convolution
之后,_WithSpaceToBatch.__init__()
课程并不在乎,dilation_rate = ops.convert_to_tensor(
dilation_rate, dtypes.int32, name="dilation_rate")
会立即明确地将其转换为张量:
tf.nn._get_strides_and_dilation_rate()
因此,如果您非常确信您的参数是正确的,那么您可以将tf.nn.convolution()
短路,然后使用双暗扩张率直接调用import tensorflow as tf
square_size = 5
dr = tf.placeholder( shape = ( 2, ), dtype = tf.int32 )
inp = tf.reshape( tf.constant( range( square_size * square_size ), dtype = tf.float32 ), ( 1, square_size, square_size, 1 ) )
fltr = tf.reshape( tf.ones( ( 3, 3 ) ), ( 3, 3, 1, 1 ))
_original = tf.nn._nn_ops._get_strides_and_dilation_rate
tf.nn._nn_ops._get_strides_and_dilation_rate = lambda a, b, c : ( b, c )
state = tf.nn.convolution( inp, fltr, "SAME", strides = [ 1, 1 ], dilation_rate = dr )
tf.nn._nn_ops._get_strides_and_dilation_rate = _original
with tf.Session() as sess:
print( sess.run( tf.squeeze( inp ) ) )
print
print( sess.run( tf.squeeze( state ), feed_dict = { dr : [ 2, 2 ] } ) )
print
print( sess.run( tf.squeeze( state ), feed_dict = { dr : [ 3, 3 ] } ) )
,就像这段代码一样(测试):
tf.squeeze
将以动态更改的扩张率输出结果(const subarrays = array.map(pair => pair.split());
仅用于易读性):
[[0. 1. 2. 3. 4.]
[5. 6. 7. 8. 9.]
[10。 11. 12. 13. 14.]
[15。 16. 17. 18. 19.]
[20。 21. 22. 23. 24.]][[24. 28. 42. 28. 32.]
[44. 48. 72. 48. 52.]
[66. 72. 108. 72. 78.]
[44. 48. 72. 48. 52.]
[64. 68. 102. 68. 72.]][[36。 40. 19. 36. 40.]
[56。 60. 29. 56. 60.]
[23。 25. 12. 23. 25.]
[36。 40. 19. 36. 40.]
[56。 60. 29. 56. 60.]]