I want to change the weights of one layer of a neural net to a new set of known values. The current set of values is:
>>> import tensorflow as tf
...
>>> curr_layer.weights
<tf.Variable 'conv2d/kernel:0' shape=(4, 4, 1, 64) dtype=float32, numpy=
array([[[[ 0.02059445, -0.01320859, -0.00185177, ..., 0.02550568,
-0.02180868, 0.00089696]],
...
[[-0.03411875, -0.00027762, -0.00894349, ..., 0.04085622,
0.02792494, -0.02052956]]]], dtype=float32)>
For the sake of this example, I created a zero array with the same shape:
>>> silly = np.zeros([4,4,1,64])
However, when I use assign
to transfer the values, the name of the graph node associated with the Tensor also changes:
>>> curr_layer.weights[0].assign(silly)
curr_layer.weights[0].assign(silly)
<tf.Variable 'UnreadVariable' shape=(4, 4, 1, 64) dtype=float32, numpy=
array([[[[0., 0., 0., ..., 0., 0., 0.]],
....
[[0., 0., 0., ..., 0., 0., 0.]]]], dtype=float32)>
Where now 'conv2d/kernel:0'
has become'Unread Variable
'. How do I prevent this from happening? How do I change only the values associated with the tensor?
CodePudding user response:
The name doesn't actually change:
a = tf.Variable(np.zeros((3, 4)), name='test')
a.name
prints test:0
. And then
a.assign(np.zeros((3, 4)))
a.name
still prints test:0
.
CodePudding user response:
For a tf.Variable instance, the .assign method has a read_value
argument that's True
by default. If x
is an arbitrary tf.Variable, then for a numpy array silly
(of the same dimensions as x
), you can do:
x.assign(silly, read_value=False)
This won't return anything, but it will change the tf.Variable instance, x
in place.
For a toy example I adapted from the original post, doing the following:
silly = np.zeros([2,2])
x = tf.Variable([[1,0],[0,1]], dtype=tf.float32, name='test')
x.assign(silly, read_value=False)
x
resulted in:
<tf.Variable 'test:0' shape=(2, 2) dtype=float32, numpy=
array([[0., 0.],
[0., 0.]], dtype=float32)>
Obviously not the same exact tensors involved in the original post, but the expected behavior is as desired.