tf.gradients(model.output, model.input) computes a different value each time I run it

Viewed 713

I'm trying to compute the gradient of the output layer with respect to the input layer. My neural network is relatively small (input layer composed of 9 activation units and the output layer of 1) and the training went fine as the test provided a very good accuracy. I made the NN model using Keras.

In order to solve my problem, I need to compute the gradient of the output with respect to the input. This is, I need to obtain the Jacobian which as dimension [1x9]. The gradients function in tensorflow should provide me with everything I need, but when I run the code below I obtain a different solution every time.

output_v = model.output
input_v = model.input
gradients = tf.gradients(output_v, input_v)

sess = tf.Session()
sess.run(tf.initialize_all_variables())

print(sess.run(model.input,feed_dict={model.input:x_test_N[0:1,:]}))
evaluated_gradients = sess.run(gradients,feed_dict{model.input:x_test_N[0:1,:]})
print(evaluated_gradients)

sess.close()

The first print command shows this value every time I run it (just to make sure that the input values are not modified):

[[-1.4306372 -0.1272892  0.7145787  1.338818  -1.2957293 -0.5402862-0.7771702 -0.5787912 -0.9157122]]

But the second print shows different ones:

[[ 0.00175761, -0.0490326 , -0.05413761,  0.09952173,  0.06112418, -0.04772799,  0.06557006, -0.02473242,  0.05542536]]

[[-0.00416433,  0.08235116, -0.00930298,  0.04440641,  0.03752216, 0.06378302,  0.03508484, -0.01903783, -0.0538374 ]]

Using finite differences, evaluated_gradients[0,0] = 0.03565103, which isn't close to any of the first values previously printed.

Thanks for your time!

Alberto


Solved by creating a specific session just before training my model:

sess = tf.Session()
sess.run(tf.global_variables_initializer())
K.set_session(sess)

history = model.fit(x_train_N, y_train_N, epochs=n_epochs,
                    validation_split=split, verbose=1, batch_size=n_batch_size,
                    shuffle='true', callbacks=[early_stop, tensorboard])

And evaluating the gradient after training, while tf.session is still open:

evaluated_gradients = sess.run(K.gradients(model.output, model.input), feed_dict={model.input: x_test_N})
1 Answers

Presumably your network is set up to initialize weights to random values. When you run sess.run(tf.initialize_all_variables()), you are initializing your variables to new random values. Therefore you get different values for output_v in every run, and hence different gradients. If you want to use a model you trained before, you should replace the initialization with initialize_all_variables() with a restore command. I am not familiar with how this is done in Keras since I usually work directly with tensorflow, but I would try this.

Also note that initialize_all_variables is deprecated and you should use global_variables_initializer instead.

Related