theano-scan:如何 outputs_info 将占位符提要作为输入
theano-scan: how outputs_info with placeholder feed as input
我对 theano 中的 outputs_info 扫描感到困惑。下面是计算 A**k 的扫描示例:
k = T.iscalar("k")
A = T.vector("A")
def inner_fct(prior_result, B):
return prior_result * B
# Symbolic description of the result
result, updates = theano.scan(fn=inner_fct,
outputs_info=T.ones_like(A),
non_sequences=A, n_steps=k)
# Scan has provided us with A ** 1 through A ** k. Keep only the last
# value. Scan notices this and does not waste memory saving them.
final_result = result[-1]
power = theano.function(inputs=[A, k], outputs=final_result,
updates=updates)
print(power(range(10), 2))
我做了如下小改动:
k = T.iscalar("k")
A = T.vector("A")
def inner_fct(prior_result, B):
return B, B, prior_result * B #!! change return of inner_fct
#!! change scan as below
[B1, B2, result], updates = theano.scan(fn=inner_fct,
outputs_info=[None, None, T.ones_like(A)],
non_sequences=A, n_steps=k)
final_result = result[-1]
power = theano.function(inputs=[A, k], outputs=final_result,
updates=updates)
print(power(range(10), 2))
它仍然得到与原始结果相同的结果。当我更改 outpus_info=[None, T.ones_like(A), None] 或 ouputs_info=[T.ones_like(A), None, None], 还是一样的结果。
T.ones_like(A) 将作为 inner_fct 中 prior_result 的首字母,所以我可以假设 theano 会找到一个不是 None 的首字母作为 prior_result 的首字母]?
theano 究竟是如何选择 outputs_info 中的首字母作为输入的?
k = T.iscalar("k")
A = T.vector("A")
def inner_fct(prior_result, B):
return B, prior_result*B, prior_result * B #!! change return of inner_fct
#!! change scan as below
[B1, B2, result], updates = theano.scan(fn=inner_fct,
outputs_info=[None, None, T.ones_like(A)],
non_sequences=A, n_steps=k)
power = theano.function(inputs=[A, k], outputs=[B2,result],
updates=updates)
print(power(range(10), 2))
outputs_info中的第二个参数是None,这意味着inner_fct的第二个输出不是循环的,但是print(power(range(10), 2))
表明B2
是循环的与 result
.
相同
outputs_info
就像 the documentation 说的那样有效。
特别是,
outputs_info is the list of Theano variables or dictionaries
describing the initial state of the outputs computed recurrently.
并且
If you provide a None instead of a variable or a empty dictionary scan
assumes that you will not use any taps for this output (like for
example in case of a map)
outputs_info
列表中的元素数量应与 scan
步进函数返回的值数量相匹配。在您的第一个示例中,阶跃函数 returns 是单个值,因此 outputs_info
应该(并且确实)包含单个元素。在你的第二个例子中,阶跃函数 returns 三个值所以 outputs_info
应该(并且确实)包含三个元素。
对于 outputs_info
中的每个值,如果它是 None
则表示该值不是循环的(此位置的输出不可用于以后的迭代)。一个非None
outputs_info
的值表示那个位置的步进输出是循环的,提供的值是传递给步进函数的初始值在第一步;后续步骤接收上一步的输出。
所以 scan
并没有做一些聪明的魔术来自动找出哪个元素包含初始值。在第二个示例中,您只是简单地告诉 Theano 做一些特定的事情,阶跃函数 returns 两个非循环值(因此有两个 None
s)后跟一个循环值(因此初始值在第三个位置)。
在第三个示例中(在问题编辑中添加),步进函数(第三个)仍然只有一个循环输出。 outputs_info
值决定了哪些输出是循环的,在第三个例子中,只有一个非 None
outputs_info
值。 B2
函数输出和result
函数输出相同,因为它们有相同的计算表达式:prior_result*B
。这两个值中的哪一个被迭代并不重要,它们始终保持相同。
我对 theano 中的 outputs_info 扫描感到困惑。下面是计算 A**k 的扫描示例:
k = T.iscalar("k")
A = T.vector("A")
def inner_fct(prior_result, B):
return prior_result * B
# Symbolic description of the result
result, updates = theano.scan(fn=inner_fct,
outputs_info=T.ones_like(A),
non_sequences=A, n_steps=k)
# Scan has provided us with A ** 1 through A ** k. Keep only the last
# value. Scan notices this and does not waste memory saving them.
final_result = result[-1]
power = theano.function(inputs=[A, k], outputs=final_result,
updates=updates)
print(power(range(10), 2))
我做了如下小改动:
k = T.iscalar("k")
A = T.vector("A")
def inner_fct(prior_result, B):
return B, B, prior_result * B #!! change return of inner_fct
#!! change scan as below
[B1, B2, result], updates = theano.scan(fn=inner_fct,
outputs_info=[None, None, T.ones_like(A)],
non_sequences=A, n_steps=k)
final_result = result[-1]
power = theano.function(inputs=[A, k], outputs=final_result,
updates=updates)
print(power(range(10), 2))
它仍然得到与原始结果相同的结果。当我更改 outpus_info=[None, T.ones_like(A), None] 或 ouputs_info=[T.ones_like(A), None, None], 还是一样的结果。 T.ones_like(A) 将作为 inner_fct 中 prior_result 的首字母,所以我可以假设 theano 会找到一个不是 None 的首字母作为 prior_result 的首字母]?
theano 究竟是如何选择 outputs_info 中的首字母作为输入的?
k = T.iscalar("k")
A = T.vector("A")
def inner_fct(prior_result, B):
return B, prior_result*B, prior_result * B #!! change return of inner_fct
#!! change scan as below
[B1, B2, result], updates = theano.scan(fn=inner_fct,
outputs_info=[None, None, T.ones_like(A)],
non_sequences=A, n_steps=k)
power = theano.function(inputs=[A, k], outputs=[B2,result],
updates=updates)
print(power(range(10), 2))
outputs_info中的第二个参数是None,这意味着inner_fct的第二个输出不是循环的,但是print(power(range(10), 2))
表明B2
是循环的与 result
.
outputs_info
就像 the documentation 说的那样有效。
特别是,
outputs_info is the list of Theano variables or dictionaries describing the initial state of the outputs computed recurrently.
并且
If you provide a None instead of a variable or a empty dictionary scan assumes that you will not use any taps for this output (like for example in case of a map)
outputs_info
列表中的元素数量应与 scan
步进函数返回的值数量相匹配。在您的第一个示例中,阶跃函数 returns 是单个值,因此 outputs_info
应该(并且确实)包含单个元素。在你的第二个例子中,阶跃函数 returns 三个值所以 outputs_info
应该(并且确实)包含三个元素。
对于 outputs_info
中的每个值,如果它是 None
则表示该值不是循环的(此位置的输出不可用于以后的迭代)。一个非None
outputs_info
的值表示那个位置的步进输出是循环的,提供的值是传递给步进函数的初始值在第一步;后续步骤接收上一步的输出。
所以 scan
并没有做一些聪明的魔术来自动找出哪个元素包含初始值。在第二个示例中,您只是简单地告诉 Theano 做一些特定的事情,阶跃函数 returns 两个非循环值(因此有两个 None
s)后跟一个循环值(因此初始值在第三个位置)。
在第三个示例中(在问题编辑中添加),步进函数(第三个)仍然只有一个循环输出。 outputs_info
值决定了哪些输出是循环的,在第三个例子中,只有一个非 None
outputs_info
值。 B2
函数输出和result
函数输出相同,因为它们有相同的计算表达式:prior_result*B
。这两个值中的哪一个被迭代并不重要,它们始终保持相同。