9

First the broad questions:

  • Is it possible to build a conditional graph with tensorflow?
  • If yes, do the automated gradient-calcuation and the implemented optimizers work with it?
  • Can I access the shape of a tensor and turn it into an integer for using it with an "if" condition and a "for i in range()" loop?

My actual use case is that I want to do a 1D convolution with variable tensor length. For this I first need an if statement that only executes the convolution if the length is greater then one. Then I have a for loop that goes through the tensor for the convolution. The problem is that this code:

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

doesn't work because the range operator needs an integer. Can I turn this somehow into an integer?

In the end I want to train this model with adagrad, either with the automatic differentiation or the already implemented optimiser


Edit:

this is the 1D convolution which will later be the first of two Layers in my Model. The type errors are behind each version of the for loop that triggers one

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})
Hooked
  • 84,485
  • 43
  • 192
  • 261
user3688217
  • 538
  • 2
  • 5
  • 15

1 Answers1

3

I recommend you to write each question differently. Otherwise it will be closed as too broad.

I can answer only your 3-rd question. How to programmatically get a shape of the tensor. You are correctly using shape to get the shape of the tensor, but you still can not get the results before you run the graph (look at my 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]

The ugly way that I have found to get the shape from constants, without running the graph is to do something like (do not really know why would you need it):

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

To get the shape from a variable, you can do this:

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

Another way to access a shape of a Tensor before the evaluation is: tf.Tensor.get_shape()

Community
  • 1
  • 1
Salvador Dali
  • 214,103
  • 147
  • 703
  • 753
  • 1
    the if is part of the graph itself, I can't run the graph to build it. The second approach also gives me a type error: **TypeError: unsupported operand type(s) for -: 'NoneType' and 'int'** – user3688217 Nov 11 '15 at 01:42
  • @user3688217 without knowing how you build your graph, it is impossible to tell why do you have this TypeError. Try run my examples and you will see the numbers. – Salvador Dali Nov 11 '15 at 04:21
  • I added the Code of the convolution that if executed throws the errors for the for loop – user3688217 Nov 11 '15 at 17:17
  • @user3688217 one more time: do not write 3 questions in one. Edit your current question, leave only one and open two new questions. – Salvador Dali Nov 11 '15 at 19:48