Basically, I have a function that expects a tensor x and two placeholders z and c.
def error_robust(x,z,c):
zz = tf.reshape(z, [-1, 28, 28, 1])
var = tf.reduce_mean(x-zz)
out = tf.cond( tf.abs(var) <= c, lambda: (c*c/6.0)*(1 - tf.pow(1-tf.pow(var/c,2),3)), lambda: tf.Variable(c*c/6.0) )
return out
I define the placeholders and tensors that I am gonna use:
# TENSORFLOW PLACEHOLDERS
sess = tf.Session(config=tf.ConfigProto(allow_soft_placement=True))
flat_mnist_data = tf.placeholder(tf.float32, [None, 28*28])
dropout_keep_prob = tf.placeholder(tf.float32)
param_robust = tf.placeholder(tf.float32, shape=())
Calling the defined function does not generate any errors:
error_r = error_robust(layer1_b.reconstruction, flat_mnist_data, param_robust)
This generates an error:
sess.run(tf.global_variables_initializer())
InvalidArgumentError (see above for traceback): You must feed a value for placeholder tensor 'Placeholder' with dtype float
[[Node: Placeholder = Placeholderdtype=DT_FLOAT, shape=[], _device="/job:localhost/replica:0/task:0/gpu:0"]]
I don't really understand why it happens. Any ideas on how to solve this one?
Ok, I got it. I was first expecting c to be a simple scalar. So I was using tf.Variable as the second argument of the tf.cond.
Updating the error_robust function solves it:
def error_robust(x,z,c):
zz = tf.reshape(z, [-1, 28, 28, 1])
var = tf.reduce_mean(x-zz)
out = tf.cond( tf.abs(var) <= c, lambda: (c*c/6.0)*(1 - tf.pow(1-tf.pow(var/c,2),3)), lambda: c*c/6.0 )
return out
Related
I have a list of placeholders as follows:
input_vars = []
input_vars.append(tf.placeholder(shape=[None, 5], dtype=tf.float32, name="place0"))
input_vars.append(tf.placeholder(shape=[None, 5], dtype=tf.float32, name="place1"))
input_vars.append(tf.placeholder(shape=[None, 5], dtype=tf.float32, name="place2"))
I want to access different placeholders based on a int placeholder as follows:
which_input = tf.placeholder(tf.int32)
When calling the following in session:
input_vars[which_input]
I am getting the following error:
TypeError: list indices must be integers, not Tensor
I tried using tf.gather which worked, however when I want to feed the selected placeholder in the dense layer as follows:
helpme = tf.gather(input_vars, which_input)
l_in = tf.layers.dense(inputs=helpme, units=64, activation=tf.nn.relu, trainable=True)
I am getting the following error:
ValueError: Input 0 of layer dense_4 is incompatible with the layer: its rank is undefined, but the layer requires a defined rank.
Here is the session running info:
x = [[1,2,3,4,5]]
x.append([6,7,8,9,10])
y = [[5,4,3,2,1]]
y.append([5,3,2,1,1])
with tf.Session() as sess:
init = tf.global_variables_initializer()
sess.run(init)
dictd = dict()
dictd[input_vars[0]] = x
dictd[input_vars[1]] = y
dictd[input_vars[2]] = x
dictd[which_input] = 2
print sess.run(l_in, feed_dict=dictd)
Am I missing something? How can this be done?
You just need to reshape your output from tf.gather as explained in this answer:
l_in = tf.layers.dense(inputs=tf.reshape(helpme, shape=[-1,5]), units=64, activation=tf.nn.relu, trainable=True)
tf.trainable_variables() returns a list of all trainable variable objects. When an object from the list is passed to an op, such as tf.nn.l2_loss, TensorFlow is able to cast the object as a Tensor and perform the necessary calculations. However, passing the same object to a user defined function throws an error.
Consider the following two layer network to work with:
# Generate random data
x_train = np.random.rand(64, 16, 16, 8)
y_train = np.random.randint(0, 5, 64)
one_hot = np.zeros((len(y_train), 5))
one_hot[list(np.indices((len(y_train),))) + [y_train]] = 1
y_train = one_hot
# Model definition
class FeedForward(object):
def __init__(self, l2_lambda=0.01):
self.x = tf.placeholder(tf.float32, shape=[None, 16, 16, 4], name="input_x")
self.y = tf.placeholder(tf.float32, [None, 5], name="input_y")
l2_loss = tf.constant(0.0)
with tf.name_scope("conv1"):
kernel_shape=[1, 1, 4, 4]
w = tf.Variable(tf.truncated_normal(kernel_shape, stddev=0.1), name="weight")
conv1 = tf.nn.conv2d(self.x, w, strides=[1, 1, 1, 1], padding="SAME", name="conv")
with tf.name_scope("conv2"):
kernel_shape=[1, 1, 4, 2]
w = tf.Variable(tf.truncated_normal(kernel_shape, stddev=0.1), name="weight")
conv2 = tf.nn.conv2d(conv1, w, strides=[1, 1, 1, 1], padding="SAME", name="conv")
out = tf.contrib.layers.flatten(conv2)
with tf.name_scope("output"):
kernel_shape=[out.get_shape()[1].value, 5]
w = tf.Variable(tf.truncated_normal(kernel_shape, stddev=0.1), name="weight")
self.scores = tf.matmul(out, w, name="scores")
predictions = tf.argmax(self.scores, axis=1, name="predictions")
# L2 Regularizer
if l2_reg_lambda > 0.:
l2_loss = tf.add_n([self.some_norm(var) for var in tf.trainable_variables() if ("weight" in var.name)])
losses = tf.nn.softmax_cross_entropy_with_logits(logits=self.scores, labels=self.y)
self.loss = tf.reduce_mean(losses) + (l2_lambda * l2_loss)
correct_predictions = tf.equal(predictions, tf.argmax(self.y, axis=1))
self.accuracy = tf.reduce_mean(tf.cast(correct_predictions, "float"), name="accuracy")
def some_norm(w):
# operate on w and return scalar
# (only) for example
return (1 / tf.nn.l2_loss(w))
with tf.Graph().as_default():
sess = tf.Session()
with sess.as_default():
ffn = FeedForward()
global_step = tf.Variable(0, name="global_step", trainable=False)
optimizer = tf.train.GradientDescentOptimizer(learning_rate=1e-2)
grads_and_vars = optimizer.compute_gradients(ffn.loss)
sess.run(tf.global_variables_initializer())
def train_step(x_batch, y_batch):
feed_dict = {
ffn.x: x_batch,
ffn.y: y_batch,
}
_, step, loss, accuracy = sess.run([train_op, global_step, ffn.loss, ffn.accuracy], feed_dict)
print("step {}, loss {:g}, acc {:g}".format(step, loss, accuracy))
batch_size = 32
n_epochs = 4
s_idx = - batch_size
for batch_index in range(n_epochs):
s_idx += batch_size
e_idx = s_idx + batch_size
x_batch = x_train[s_idx:e_idx]
y_batch = y_train[s_idx:e_idx]
train_step(x_batch, y_batch)
current_step = tf.train.global_step(sess, global_step)
The problem here is that on passing the trainable variable to some_norm(), it is passed as an object and can not be operated on. The related error message encountered at the first line inside some_norm() is:
Failed to convert object of type <class '__main__.FeedForward'> to Tensor.
Contents: <__main__.FeedForward object at 0x7fefde7e97b8>.
Consider casting elements to a supported type.
Is there a way to cast the object returned by tf.trainable_variables() as a tensor or is there a possible workaround such as passing a reference?
How is using the above different from using l2_loss = tf.add_n([tf.nn.l2_loss(var) for var in tf.trainable_variables()...]) which works just fine?
You forgot the self argument in your some_norm implementation def some_norm(w):, so it tries to convert your instance of the class (self) to a tensor.
I have seen pieces of code using either [], [None], None or () as the shape for a placeholder, that is
x = tf.placeholder(..., shape=[], ...)
y = tf.placeholder(..., shape=[None], ...)
z = tf.placeholder(..., shape=None, ...)
w = tf.placeholder(..., shape=(), ...)
What's the difference between these?
TensorFlow uses arrays rather than tuples. It converts tuples to arrays. Therefore [] and () are equivalent.
Now, consider this code example:
x = tf.placeholder(dtype=tf.int32, shape=[], name="foo1")
y = tf.placeholder(dtype=tf.int32, shape=[None], name="foo2")
z = tf.placeholder(dtype=tf.int32, shape=None, name="foo3")
val1 = np.array((1, 2, 3))
val2 = 45
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
#print(sess.run(x, feed_dict = {x: val1})) # Fails
print(sess.run(y, feed_dict = {y: val1}))
print(sess.run(z, feed_dict = {z: val1}))
print(sess.run(x, feed_dict = {x: val2}))
#print(sess.run(y, feed_dict = {y: val2})) # Fails
print(sess.run(z, feed_dict = {z: val2}))
As can be seen, placeholder with [] shape takes a single scalar value directly. Placeholder with [None] shape takes a 1-dimensional array and placeholder with None shape can take in any value while computation takes place.
I have lately been vexed by the following error message:
ValueError: Cannot feed value of shape (2455040,) for Tensor 'Placeholder:0', which has shape '(2455040, ?)'
Which is being produced from running the following code:
NUMCLASSES=16
NUMPIXELS=959*640*4
# set up to feed an array of images [images, size_of_image]
x = tf.placeholder(tf.float32, [NUMPIXELS,None])
....deletia....
# Define loss and optimizer..why is this 2d?
y_ = tf.placeholder(tf.float32, [None,NUMCLASSES])
sess = tf.InteractiveSession()
tf.global_variables_initializer().run(session=sess)
tl = get_tensor_list()
for f, n in tl:
str = '/users/me/downloads/train/' + f
mm = Image.open(str)
mm = mm.convert('F')
mma=np.array(mm)
i = mma.flatten() #now this is an array of floats of size NUMPIXELS
sess.run(train_step, feed_dict={x: i, y_: n}) # <<DEATH
Somehow, that array is getting a shape that tf does not like [(x,) when it wants (x,?)]. How to satisfy the tensorgods in this case? The tensor must be what it must be for other mathematical reasons not discussed.
reshaping the array might help.
i = mma.flatten().reshape((NUMPIXELS,1))
The error happens because the two tensors have different ranks: tensor with shape (2455040,) has rank 1, while tensor with shape (2455040,?) has rank 2.
You can do this:
x = tf.placeholder(tf.float32, [None])
x = tf.reshape(x, [NUMPIXELS,-1])
I am wondering if the same holds for tf.split_v() as tf.split().
According to the documentation split_v also accepts a Tensor as second argument.
However, when I try this code
batch_size_ph = tf.placeholder(dtype = tf.int32, name='BatchSize')
seq_length_ph = tf.placeholder(dtype = tf.int32, name='SeqLength')
input_data = tf.placeholder(dtype=tf.float32, shape=[50, 25, 10])
inputs = tf.split_v(input_data,seq_length_ph, 1) #tf.ones(seq_length_ph, tf.int32)
#inputs = [tf.squeeze(input_, [1]) for input_ in inputs]
with tf.Session() as sess:
[out] = sess.run([inputs],feed_dict = {batch_size_ph: 50,
seq_length_ph: 25,
input_data: np.random.rand(50,25,10)})
print out
print len(out)
print out[0].shape
The error is
NameError: global name 'value_shape' is not defined
Is this possible or not?