张量流中的条件图和访问张量大小的for循环

Posted

技术标签:

【中文标题】张量流中的条件图和访问张量大小的for循环【英文标题】:conditional graph in tensorflow and for loop that accesses tensor size 【发布时间】:2016-02-12 00:50:10 【问题描述】:

首先是广泛的问题:

是否可以使用 tensorflow 构建条件图? 如果是,自动梯度计算和实施的优化器是否可以使用它? 我能否访问张量的形状并将其转换为整数,以便在“if”条件和“for i in range()”循环中使用它?

我的实际用例是我想做一个可变张量长度的一维卷积。为此,我首先需要一个 if 语句,该语句仅在长度大于 1 时才执行卷积。然后我有一个通过张量进行卷积的 for 循环。问题是这段代码:

for i in range(tf.shape(tensor)[0]): 

不起作用,因为范围运算符需要一个整数。我可以把它变成一个整数吗?

最后我想用 adagrad 训练这个模型,无论是自动微分还是已经实现的优化器


编辑:

这是一维卷积,稍后将成为我模型中两层中的第一层。每个版本的 for 循环都会触发类型错误

import tensorflow as tf 
import numpy as np 

def convolve(s, Tl, Tr, b):

    if (tf.shape(s)[0] == 1):
        return s

    sum = 0

    # for i in range(tf.shape(s)[0] - 1): # error: TypeError: range() integer end argument expected, got Tensor
    # for i in range(s._shape._dims[0]._value - 1): # error: TypeError: unsupported operand type(s) for -: 'NoneType' and 'int'
    for i in range(s.get_shape().as_list()[0] - 1): # error: TypeError: unsupported operand type(s) for -: 'NoneType' and 'int'

        sum += tf.tanh(tf.matmul(Tl,s[i]) + tf.matmul(Tr, s[i+1]) + b)

    return sum

ModelSize = 3

# tensor to be convolved
s = tf.placeholder("float", shape = [None, ModelSize])

# initialise weights
Tl = tf.Variable(tf.random_normal(shape=[ModelSize,ModelSize], stddev = 0.1 ))
Tr = tf.Variable(tf.random_normal(shape=[ModelSize,ModelSize], stddev = 0.1 ))
b = tf.Variable(tf.random_normal(shape=[ModelSize], stddev = 0.1 ))

#convolution
s_convolved = convolve(s, Tl, Tr, b)

# initialise variables.
init = tf.initialize_all_variables()

# run graph
sess = tf.Session()
sess.run(init)

# test data
s_dataLong = np.random.random((2,5,ModelSize))
s_dataShort = np.random.random((2,1,ModelSize))

for s_dataPart in s_dataLong:
    print sess.run(s_convolved, feed_dict = s : s_dataPart)

for s_dataPart in s_dataShort:
    print sess.run(s_convolved, feed_dict = s : s_dataPart)

【问题讨论】:

【参考方案1】:

我建议您以不同的方式编写每个问题。否则会因为过于宽泛而被关闭。

我只能回答你的第三个问题。如何以编程方式获得张量的形状。您正确使用了shape to get the shape of the tensor,但在运行图表之前您仍然无法获得结果(看看我的explanation here)。

a = tf.truncated_normal([2, 3], mean=0.0, stddev=0.02, dtype=tf.float32, seed=1)
b = tf.shape(a)
sess = tf.Session()
print sess.run(b) # will give you [2 3]

我发现在不运行图形的情况下从常量获取形状的丑陋方法是执行类似的操作(不知道为什么需要它):

print a._shape._dims[0]._value
print a._shape._dims[1]._value

要从变量中获取形状,您可以这样做:

weights = tf.Variable(tf.random_normal([784, 200], stddev=0.35))
print weights.get_shape().as_list()

在评估之前访问张量形状的另一种方法是:tf.Tensor.get_shape()

【讨论】:

if 是图本身的一部分,我无法运行图来构建它。第二种方法也给了我一个类型错误:TypeError: unsupported operand type(s) for -: 'NoneType' and 'int' @user3688217 在不知道如何构建图形的情况下,无法判断为什么会出现此 TypeError。尝试运行我的示例,您将看到数字。 我添加了卷积代码,如果执行该代码会引发 for 循环的错误 @user3688217 再来一次:不要把三个问题合二为一。编辑您当前的问题,只留下一个并打开两个新问题。

以上是关于张量流中的条件图和访问张量大小的for循环的主要内容,如果未能解决你的问题,请参考以下文章

张量流中的动态批量大小

如果循环中涉及的所有张量都在 GPU 上,我的 for 循环是不是并行运行?

由张量流中的索引张量指定的切片二维张量

在张量流中,如何迭代存储在张量中的输入序列?

如何在张量流中对张量进行子集化?

当切片本身是张量流中的张量时如何进行切片分配