ValueError: No gradients provided for any variable(TensorFlow2!绝对详细!)

今天的代码一直遇见下列错误, 烦不胜烦。其实就是因为在进行优化求损失函数最小值的时候,找不到需要梯度下降的变量,提示的是要检查损失函数。

  ([str(v) for _, v in grads_and_vars], loss))
ValueError: No gradients provided for any variable, check your graph for ops that do not support gradients, between variables [] and loss <function loss at 0x000001ABF60B2488>.

我的出错代码如下。

train_logits = inference(train_batch, BATCH_SIZE, N_CLASSES)
 def loss():
           return tf.nn.sparse_softmax_cross_entropy_with_logits(labels=train_label_batch,logits=train_logits ) )#infere
optimizer.minimize(loss=loss)

按我的理解,优化过程的第一步其实就是求梯度。这个过程就是根据输入的损失函数,提取其中的变量,进行梯度下降,使整个损失函数达到最小值。首先想的是怎么提取损失函数中的变量呢?
查看官网,我们可以看到optimizer.minimize函数的变量列表,其实就是variables类型的元组或者列表。那理想中的梯度下降过程,其实就是利用标签和预测值求损失函数,再对从预测模型引入的variables变量进行梯度下降,以减小损失函数。
在这里插入图片描述
那其实,损失函数作为预测模型和优化模型的桥梁,肯定要做到传递变量的作用。我们使用下面这个关于初次使用tensorflow遇到的坑的代码,直观看一下错误处在了哪里,再对症下药。源代码肯定是可以运行成功的,但我们稍微做一些修改。其实就是把return tf.keras.losses.MSE(y_data, Weights*x_data+biases)修改成w=Weights*x_data+biases def loss(): return tf.keras.losses.MSE(y_data, w)
不再直接传预测模型,而是传入一个变量,虽然这个变量就是原来的预测模型,我们想看根据一个变量,是否梯度下降的时候可以找到对应的变量。

# -*- coding: utf-8 -*-
import tensorflow as tf
import numpy as np

#  tf.disable_v2_behavior()

# create data
x_data = np.random.rand(100).astype(np.float32)     # 一百个随机数列  定义数据类型
y_data = x_data*0.1+0.3          # W为0.3
print(y_data)
# create tensorflow structure start #
# AttributeError: module 'tensorflow' has no attribute 'random_uniform'
# V2版本里面random_uniform改为random.uniform
Weights = tf.Variable(tf.random.uniform((1,), -1.0, 1.0))  # 随机数列生产的参数 [1] W结构为一维 -1.0, 1.0 随机生产数列的范围
# TypeError: 'function' object is not subscriptable
# 一般是少了括号
print(Weights)
biases = tf.Variable(tf.zeros((1,)))     # 定义初始值 0
print(biases)
# y = Weights*x_data+biases
# 定义预测值y
w=Weights*x_data+biases
def loss():
    print(tf.keras.losses.MSE(y_data, w))
    return tf.keras.losses.MSE(y_data, w)  # alias 计算loss  预测值与真实值的差别
# AttributeError: module 'tensorflow_core._api.v2.train' has no attribute 'GradientDescentOptimizer'
# "tf.train.GradientDescentOptimizer" change "tf.compat.v1.train.GradientDescentOptimizer"
# `loss` passed to Optimizer.compute_gradients should be a function when eager execution is enabled.
# 神经网络知道误差以后 优化器(optimizer)减少误差 提升参数的准确度
# 其中的minimize可以拆为以下两个步骤:
# ① 梯度计算
# ② 将计算出来的梯度应用到变量的更新中
# 拆开的好处是,可以对计算的梯度进行限制,防止梯度消失和爆炸
# optimizer = tf.compat.v1.train.GradientDescentOptimizer(0.5)
# train = optimizer.minimize(loss)
optimizer = tf.keras.optimizers.SGD(learning_rate=0.5)  # alias: tf.optimizers.SGD learning_rate=0.5
#init = tf.initializer_all_variables()
#  create tensorflow structure end #

# create session
# sess = tf.Session()
# sess.run(init)          # Very important

for step in range(201):
    optimizer.minimize(loss,var_list=[Weights,biases])
    if step % 20 == 0:
        print("{} step, Weights = {}, biases = {}"
              .format(step, Weights.read_value(), biases.read_value()))  # read_value函数可用numpy替换

运行结果如下:

    ([v.name for _, v in grads_and_vars],))
ValueError: No gradients provided for any variable: ['Variable:0', 'Variable:0'].

发现发现了需要梯度下降的两个变量[‘Variable:0’, ‘Variable:0’],并不是我们希望的权重和偏置。那这两个值是在哪里产生的呢?
我们打印初始化的权重和偏置

Weights = tf.Variable(tf.random.uniform((1,), -1.0, 1.0))  
# 一般是少了括号
print(Weights)
biases = tf.Variable(tf.zeros((1,)))     # 定义初始值 0
print(biases)

结果如下,发现正是我们的初始权重和偏置啊。所以还是直接传模型吧,而不是传递一个已经计算好的数值

<tf.Variable 'Variable:0' shape=(1,) dtype=float32, numpy=array([-0.16910172], dtype=float32)>
<tf.Variable 'Variable:0' shape=(1,) dtype=float32, numpy=array([0.], dtype=float32)>

除了直接输入模型,还可以使用下述方法

def loss():
    # print(tf.keras.losses.MSE(y_data, w))
    w = Weights * x_data + biases
    return tf.keras.losses.MSE(y_data, w)  # alias 计算loss  预测值与真实值的差别

结果:
哎,就是一直试,慢慢找套路

20 step, Weights = [-0.06692801], biases = [0.39274]
40 step, Weights = [0.05562253], biases = [0.32465476]
60 step, Weights = [0.08820234], biases = [0.30655444]
80 step, Weights = [0.09686362], biases = [0.3017425]
100 step, Weights = [0.09916621], biases = [0.30046323]
120 step, Weights = [0.09977833], biases = [0.30012316]
140 step, Weights = [0.09994107], biases = [0.30003276]
160 step, Weights = [0.09998435], biases = [0.3000087]
180 step, Weights = [0.09999582], biases = [0.30000234]
200 step, Weights = [0.09999889], biases = [0.30000064]

我原来的代码也应该修改成return tf.nn.sparse_softmax_cross_entropy_with_logits(labels=train_label_batch,logits=inference(train_batch, BATCH_SIZE, N_CLASSES) )#inference(train_batch, BATCH_SIZE, N_CLASSES)

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值