Q:

Simplest ever apply_gradients throws 'op' attribute error

I am learning to use tensorflow library. Every time I try to use simplest (I guess) possible example of gradient-based learning I get the same error, which makes me stuck.
Here is the code:
import tensorflow as tf

x = tf.constant(1, dtype=tf.float32, name='X')
a = tf.Variable(1, dtype=tf.float32, name= 'A')
y = tf.constant(10, dtype=tf.float32, name='Y')

ey = tf.multiply(x, a)
los = (y - ey)**2

optim = tf.train.GradientDescentOptimizer(learning_rate=0.2)

sess = tf.Session()
sess.run(tf.global_variables_initializer())
for counter in range(100):
    grd = sess.run(optim.compute_gradients(loss=los))
    sess.run(optim.apply_gradients(grads_and_vars=grd))

On the last line, I get following error:
AttributeError: 'numpy.float32' object has no attribute 'op'.
Thank you in advance for any tips.

A:

The input of apply_gradients must be a tensor not a numpy array. Because, it is not meant to be called at each step of the learning but just once when building your graph. In fact, it "creates" the "training step" in which variables are updated using the computed gradient
You should use that kind of code instead:
import tensorflow as tf

x = tf.constant(1, dtype=tf.float32, name='X')
a = tf.Variable(1, dtype=tf.float32, name= 'A')
y = tf.constant(10, dtype=tf.float32, name='Y')

ey = tf.multiply(x, a)
los = (y - ey)**2

optim = tf.train.GradientDescentOptimizer(learning_rate=0.2)
grads, vars = zip(*optimizer.compute_gradients(loss))
train_step = optim.apply_gradients(grads_and_vars=grads)

sess = tf.Session()
sess.run(tf.global_variables_initializer())
for counter in range(100):
    grd = sess.run(train_step, feed_dict = {...})

