Tensorflow GradientTape()只返回Nones

Tensorflow GradientTape()只返回Nones,tensorflow,Tensorflow,我尝试在渴望模式下用Tensorflow计算梯度,但是 tf.GradientTape()只返回None值。我不明白为什么。 梯度在update_policy()函数中计算 该行的输出: grads=tape.gradient(损耗、自模型、可训练变量) 是 {list}:[无,无,…,无] 这是代码 将tensorflow导入为tf 从keras.backend.tensorflow_后端导入集_会话 将numpy作为np导入 tf.enable_eager_execution() 打印(

我尝试在渴望模式下用Tensorflow计算梯度,但是 tf.GradientTape()只返回None值。我不明白为什么。 梯度在update_policy()函数中计算

该行的输出:

grads=tape.gradient(损耗、自模型、可训练变量)

{list}:[无,无,…,无]
这是代码

将tensorflow导入为tf
从keras.backend.tensorflow_后端导入集_会话
将numpy作为np导入
tf.enable_eager_execution()
打印(tf.executing_急切地()
config=tf.ConfigProto()
config.gpu\u options.allow\u growth=True
sess=tf.Session(config=config)
设置会话(sess)
类数据网络:
定义初始(自我、状态空间、动作空间、lr、伽马):
self.state\u space=状态空间
self.action\u space=action\u space
self.gamma=gamma
self.model=tf.keras.Sequential()
#康
self.model.add(
Conv2D(filters=32,kernel_size=[8,8],strips=[4,4],activation='relu',
输入_形状=(84,84,4,),
name='conv1'))
self.model.add(
Conv2D(filters=64,kernel_size=[4,4],strips=[2,2],activation='relu',name='conv2'))
self.model.add(
Conv2D(filters=128,kernel_size=[4,4],strips=[2,2],activation='relu',name='conv3'))
self.model.add(tf.keras.layers.flatte(name='flatte'))
#完全连接
self.model.add(tf.keras.layers.density(units=512,activation='relu',name='fc1'))
self.model.add(tf.keras.layers.drout(rate=0.4,name='dr1'))
self.model.add(tf.keras.layers.density(units=256,activation='relu',name='fc2'))
self.model.add(tf.keras.layers.drout(rate=0.3,name='dr2'))
self.model.add(tf.keras.layers.density(units=128,activation='relu',name='fc3'))
self.model.add(tf.keras.layers.drout(rate=0.1,name='dr3'))
#罗吉斯酒店
self.model.add(tf.keras.layers.Dense(units=self.action\u space,activation=None,name='logits'))
self.model.summary()
#优化器
self.optimizer=tf.train.AdamOptimizer(学习率=lr)
def get_问题(自身):
s=s[np.newaxis,:]
logits=self.model.predict
probs=tf.nn.softmax(logits.numpy())
返回问题
def更新策略(自我、s、r、a):
使用tf.GradientTape()作为磁带:
logits=self.model.predict
策略损失=tf.nn.softmax\u交叉熵\u与逻辑向量v2(标签=a,逻辑向量=逻辑向量)
保单损失=保单损失*tf.停止梯度(r)
损失=tf.减少平均值(保单损失)
梯度=磁带梯度(损耗、自模型、可训练的变量)
self.optimizer.apply_梯度(zip(梯度、self.model.trainiable_变量))

您的模型中没有向前传球。
Model.predict()
方法返回
numpy()
数组,而不录制前向传递。看看这个例子:

给定以下数据和模型:

将tensorflow导入为tf
将numpy作为np导入
x_train=tf.convert_to_tensor(np.one((1,2),np.float32),dtype=tf.float32)
y_train=tf。将_转换为_张量([[0,1]])
model=tf.keras.models.Sequential([tf.keras.layers.Dense(2,输入_形状=(2,)]))
首先,我们使用
predict()

使用tf.GradientTape()作为磁带:
logits=模型预测(x_列车)
打印('`logits'具有类型{0}'。格式(类型(logits)))
#'logits'具有类型
xentropy=tf.nn.softmax\u cross\u entropy\u与\u logits(标签=y\u列车,logits=logits)
缩减=tf.缩减平均值(X熵)
梯度=磁带。梯度(减少,模型。可训练的变量)
打印('grads为:{0}'。格式(grads))
#毕业生:【无,无】
现在我们使用模型的输入:

使用tf.GradientTape()作为磁带:
logits=模型(x_列车)
打印('`logits'具有类型{0}'。格式(类型(logits)))
#'logits'具有类型
xentropy=tf.nn.softmax\u cross\u entropy\u与\u logits(标签=y\u列车,logits=logits)
缩减=tf.缩减平均值(X熵)
梯度=磁带。梯度(减少,模型。可训练的变量)
打印('grads为:{0}'。格式(grads))
#毕业生:[,]

因此,使用模型的
\u调用
(即
model(x)
)进行向前传球,而不是
predict()

predict()
返回
numpy
类型。它应该是张量。这是第一个问题。在
predict()
中删除
.numpy()
update\u policy()
函数不调用
predict()
函数。这与计算梯度无关。
update\u policy()
函数调用
self.model.predict()
。为了避免误解,我更改了函数。教授,我不会说德语。对不起,我的翻译很好。您确定正在监视这些变量吗?在调用
self.model.predict()
之前,请尝试添加
tape.watch(self.model.trainable\u变量)
,然后在
update\u policy()
中调用
self.model.predict()
,我们在不到30秒内完成了相同的操作。这应该是可行的,尽管我认为这仅仅是因为
.predict
返回numpy数组,它不能用TF来区分<代码>调用返回tensor@Sharky,对不起;-)+你说得对,numpy不能被区分,但它也不会记录向前传递,否则对
predict()
的调用最终会使缓冲区溢出。@沙基,谢谢,我现在也欠你一次。@Sharky你说得对,投票是理所当然的。对我来说,这是不可能的,我需要至少15个声望才能投票。现在你需要了。这个问题也是值得的。