python - opt.apply_gradients() 返回“尝试更新张量”错误
问题描述
我的问题如下:给定一个深度学习模型和一个损失函数,我想评估损失函数相对于模型输入的梯度,然后相应地更新输入。
我尝试解决这个问题的方法与本教程的“从头开始编写训练循环”非常相似;我必须更改评估梯度然后.apply_gradients()
应用的变量。
这是我的代码:
target = 0.5 * np.ones(data1.shape)
optimizer = tf.keras.optimizers.SGD(learning_rate=1e-3)
epochs = 180
for epoch in range(epochs):
with tf.GradientTape() as tape:
data1 = tf.convert_to_tensor(data1)
tape.watch(data1)
logits = pred_block(data1, training=False)
loss_value = tf.keras.losses.MSE(target, logits)
grads = tape.gradient(loss_value, data1)
optimizer.apply_gradients(zip(grads, data1))
GradientTape()
范围内被data1
转换为张量,然后被磁带监视,否则我无法获取关于 的梯度data1
。
但是,我收到以下错误:
/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/optimizer_v2/optimizer_v2.py in apply_grad_to_update_var(var, grad)
592 """Apply gradient to variable."""
593 if isinstance(var, ops.Tensor):
--> 594 raise NotImplementedError("Trying to update a Tensor ", var)
595
596 apply_kwargs = {}
NotImplementedError: ('Trying to update a Tensor ', <tf.Tensor: shape=(5,), dtype=float64, numpy=array([0.30344828, 0.30344828, 0.30344828, 0. , 0. ])>)
它所引用的张量是data1
,因此我尝试将其转换为 a numpy.array
。最后一行代码修改为:
optimizer.apply_gradients(zip(grads, np.array(data1)))
但我收到以下错误:
/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/optimizer_v2/optimizer_v2.py in _prepare(self, var_list)
782 var_devices = var._devices # pylint: disable=protected-access
783 else:
--> 784 var_devices = [var.device]
785 var_dtype = var.dtype.base_dtype
786 for var_device in var_devices:
AttributeError: 'numpy.ndarray' object has no attribute 'device'
如果我也转换,也会发生同样的情况grads
。
我想可能和形状有关data1
,也就是(5756,5)
因为给出的错误NotImplementedError: ('Trying to .... shape = (5,))
,所以我试着给它加个维度data1
。在打开for
循环之前:
data1 = data1[:, np.newaxis, :]
for epoch in range(epochs):
...
但是同样的错误信息会出现:
/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/optimizer_v2/optimizer_v2.py in apply_grad_to_update_var(var, grad)
592 """Apply gradient to variable."""
593 if isinstance(var, ops.Tensor):
--> 594 raise NotImplementedError("Trying to update a Tensor ", var)
595
596 apply_kwargs = {}
NotImplementedError: ('Trying to update a Tensor ', <tf.Tensor: shape=(1, 5), dtype=float64, numpy=array([[0.30344828, 0.30344828, 0.30344828, 0. , 0. ]])>)
即使将training
标志从False
更改为 也会True
产生相同的错误。
我还尝试将代码的最后两行更改如下:
grads = tape.gradient(loss_value, data1)
grads = tf.distribute.get_replica_context().all_reduce('sum', grads)
optimizer.apply_gradients(zip(grads, data1),
experimental_aggregate_gradients=False)
同样,同样的错误消息出现:
/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/optimizer_v2/optimizer_v2.py in apply_grad_to_update_var(var, grad)
592 """Apply gradient to variable."""
593 if isinstance(var, ops.Tensor):
--> 594 raise NotImplementedError("Trying to update a Tensor ", var)
595
596 apply_kwargs = {}
NotImplementedError: ('Trying to update a Tensor ', <tf.Tensor: shape=(5,), dtype=float64, numpy=array([0.30344828, 0.30344828, 0.30344828, 0. , 0. ])>)
我做错了什么吗?
谢谢!
解决方案
如果你想更新你的输入,它应该是一个tf.Variable
,而不是一个张量。优化器的文档apply_gradients
说明:
将渐变应用于变量。
tf.Variable
您可以在指南中阅读更多信息:变量简介
用变量替换你的 data1 张量应该可以完成这项工作:
target = 0.5 * np.ones(data1.shape)
optimizer = tf.keras.optimizers.SGD(learning_rate=1e-3)
epochs = 180
# the Variable must be created out out of the training loop
data_variable = tf.Variable(data1)
for epoch in range(epochs):
with tf.GradientTape() as tape:
tape.watch(data_variable)
logits = pred_block(data_variable, training=False)
loss_value = tf.keras.losses.MSE(target, logits)
grads = tape.gradient(loss_value, data_variable)
optimizer.apply_gradients(zip([grads], [data_variable]))
推荐阅读
- powershell - 在powershell中将网络打印机设置为默认打印机
- http - Set-Cookie 标头不能跨域工作
- python-3.x - 通过 abc 创建每个可能的字符串组合
- php - 需要帮助在 hmvc codeigniter 中集成 CKEditor 和 CKFinder
- python - 将数据框中的 json 转换为单独的列
- python - 将数据库引擎更改为 MySQL。现在 Django 不创建表
- azure - 使用 Terraform 通过 Azure AKS 管理的 Kuberntes 集群和 Active Directory 部署命名空间
- react-native - 反应本机导航 v5 选项卡按下不起作用
- java - 删除元素后从头开始检查arraylist
- java - 修复损坏的 BufferedReader 字符串