title: Manual parameter updates using tf.assign in TensorFlow
body: <p>Given the following example code (to work with):</p>
  
  <pre><code># 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):
          self.x = tf.placeholder(tf.float32, shape=[None, 16, 16, 8], name="input_x")
          self.y = tf.placeholder(tf.float32, [None, 5], name="input_y")
  
          with tf.name_scope("conv1"):
              kernel_shape=[3, 3, 8, 8]
              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=[3, 3, 8, 4]
              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)
              predictions = tf.argmax(self.scores, axis=1, name="predictions")
  
          self.loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=self.scores, labels=self.y))
  
          correct_predictions = tf.equal(predictions, tf.argmax(self.y, axis=1))
          self.accuracy = tf.reduce_mean(tf.cast(correct_predictions, "float"), name="accuracy")
  </code></pre>
  
  <p>I wish to perform a custom weight update step, ie., aside from the weight update on each iteration, I would like to subtract some fixed value from my weight parameter as below:</p>
  
  <pre><code>with tf.Graph().as_default():
      session_conf = tf.ConfigProto(allow_soft_placement=True, log_device_placement=False)
      sess = tf.Session(config=session_conf)      
  
      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)
  
          updated_gv = []
          for g, w in grads_and_vars:
              # perform update on weights aside from ouput weights
              if ("weight" in w.name) and ("output" not in w.name):
                  # some weight update
                  w_update = tf.Variable.assign(w, w - tf.constant(1.0, shape=w.get_shape()))
              updated_gv.append([g, w])
          # next two lines are not required here                
          update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)
          with tf.control_dependencies(update_ops):
              train_op = optimizer.apply_gradients(updated_gv, global_step=global_step)
  
          sess.run(tf.global_variables_initializer())
  
          def train_step(x_batch, y_batch):
              feed_dict = {
  
              }
              _, step, _update, loss, accuracy = sess.run([train_op, global_step, w_update, ffn.loss, ffn.accuracy], 
                                                          feed_dict={ffn.x: x_batch, ffn.y: y_batch})
              print("step {}, loss {:g}, acc {:g}".format(step, loss, accuracy))
  
          batch_size = 32
          s_idx = - batch_size
  
          for batch_index in range(2):
              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)
  </code></pre>
  
  <p>However, the above code (and other similar variations of it) do not affect the actual weights. I assume that any assignments using <code>tf.Variable.assign...</code> or <code>tf.assign...</code> are made into some copy of the original variable.</p>
  
  <p>What is the most meaningful way to perform the intended update?</p>