Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 我可以把张量的一部分设置为不可训练的吗?_Python_Tensorflow_Keras_Gradient_Tensor - Fatal编程技术网

Python 我可以把张量的一部分设置为不可训练的吗?

Python 我可以把张量的一部分设置为不可训练的吗?,python,tensorflow,keras,gradient,tensor,Python,Tensorflow,Keras,Gradient,Tensor,很容易将张量设置为不可训练,trainable=False。但是我可以只设置张量的一部分不可训练吗 假设我有一个2*2张量,我只想要一个元素不可训练,另外三个元素可训练 这样(我希望1,1元素始终为零,其他三个元素由优化器更新) 谢谢。简短的回答:你不能 更长的答案:您可以通过在计算梯度后将部分梯度设置为零来模拟这种效果,这样部分变量就永远不会更新 以下是一个例子: import tensorflow as tf tf.random.set_seed(0) model = tf.keras.Se

很容易将张量设置为不可训练,
trainable=False
。但是我可以只设置张量的一部分不可训练吗

假设我有一个2*2张量,我只想要一个元素不可训练,另外三个元素可训练

这样(我希望1,1元素始终为零,其他三个元素由优化器更新)


谢谢。

简短的回答:你不能

更长的答案:您可以通过在计算梯度后将部分梯度设置为零来模拟这种效果,这样部分变量就永远不会更新

以下是一个例子:

import tensorflow as tf
tf.random.set_seed(0)
model = tf.keras.Sequential([tf.keras.layers.Dense(2, activation="sigmoid", input_shape=(2,), name="first"), tf.keras.layers.Dense(1,activation="sigmoid")])
X = tf.random.normal((1000,2))
y = tf.reduce_sum(X, axis=1)
ds = tf.data.Dataset.from_tensor_slices((X,y))
在该示例中,第一层具有以下权重
W

>>> model.get_layer("first").trainable_weights[0]
<tf.Variable 'first/kernel:0' shape=(2, 2) dtype=float32, numpy=
array([[ 0.13573623, -0.68269   ],
       [ 0.8938798 ,  0.6792033 ]], dtype=float32)>
然后,在运行该循环后,我们可以再次检查wieghts:

model.get_layer("first").trainable_weights[0]
<tf.Variable 'first/kernel:0' shape=(2, 2) dtype=float32, numpy=
array([[-0.08515069, -0.51738167],
       [ 0.8938798 ,  0.6792033 ]], dtype=float32)>
model.get_层(“第一”)。可训练的_权重[0]

只有第一行更改。

在调用
优化器之前,我会尝试保存所需的权重。在调用
优化器之后,应用\u梯度
并将其更改回以前的状态。应用\u梯度
。这不会阻止反向传播,谢谢!这是一个优雅的解决方案:)
loss = tf.losses.MSE
opt = tf.optimizers.SDG(1.) # high learning rate to see the change
for xx,yy in ds.take(1):
    with tf.GradientTape() as tape:
        l = loss(model(xx),yy)
    g = tape.gradient(l,model.get_layer("first").trainable_weights[0])
    gradient_slice = g[:1] # first row
    new_grad = tf.concat([gradient_slice, tf.zeros((1,2), dtype=tf.float32),], axis=0) # replacing the rest with zeros
    opt.apply_gradients(zip([new_grad], [model.get_layer("first").trainable_weights[0]]))
model.get_layer("first").trainable_weights[0]
<tf.Variable 'first/kernel:0' shape=(2, 2) dtype=float32, numpy=
array([[-0.08515069, -0.51738167],
       [ 0.8938798 ,  0.6792033 ]], dtype=float32)>