在使用tensorflow中经常会出现这个错误,但是原因往往各不相同。
第一种情况:
在tensorflow的计算图中,我们可以利用函数def来封装一些tf操作,但是我们需要使用return语句去规避一些错误,看如下分析:
看如下程序:
import tensorflow as tf
a = tf.Variable(5.0)
def add():
a_change = tf.assign(a, 10.0)
sess = tf.Session()
sess.run(tf.global_variables_initializer())
print(sess.run(add()))
print(sess.run(a))
运行之后,显示如下错误:
Traceback (most recent call last):
File “E:/PythonProject/cnn_cifar10.py”, line 12, in
print(sess.run(add()))
File “E:\Python\lib\site-packages\tensorflow\python\client\session.py”, line 889, in run
run_metadata_ptr)
File “E:\Python\lib\site-packages\tensorflow\python\client\session.py”, line 1105, in _run
self._graph, fetches, feed_dict_tensor, feed_handles=feed_handles)
File “E:\Python\lib\site-packages\tensorflow\python\client\session.py”, line 414, in init
self._fetch_mapper = _FetchMapper.for_fetch(fetches)
File “E:\Python\lib\site-packages\tensorflow\python\client\session.py”, line 231, in for_fetch
(fetch, type(fetch)))
TypeError: Fetch argument None has invalid type <class ‘NoneType’>
此时表明add()没有fetch到参数,因此我们需要对函数里的操作添加return操作:
import tensorflow as tf
a = tf.Variable(5.0)
def add():
a_change = tf.assign(a, 10.0)
return a_change
sess = tf.Session()
sess.run(tf.global_variables_initializer())
print(sess.run(add()))
print(sess.run(a))
输出:
10.0
10.0
如果函数中封装了多个操作,就要分情况了
如下程序:
import tensorflow as tf
a = tf.Variable(5.0)
def add():
a_change = tf.assign(a, 10.0)
a_plus_1 = tf.assign_add(a, 1.0)
return a_change
sess = tf.Session()
sess.run(tf.global_variables_initializer())
print(sess.run(add()))
print(sess.run(a))
输出:
10.0
10.0
此时def中有2个操作,但是只return了a_change,所以会获取到参数,不会出现之前的错误,但是由于没有return a_plus_1操作,所以只运行了a_change操作,所以需要同时return 这2个操作,return的顺序无所谓,修改如下:
import tensorflow as tf
def add():
a_change = tf.assign(a, 10.0)
a_plus_1 = tf.assign_add(a, 1.0)
return a_plus_1, a_change
sess = tf.Session()
sess.run(tf.global_variables_initializer())
print(sess.run(add()))
print(sess.run(a))
输出:
(10.0, 11.0)
11.0
当然,也不一定def封装的操作全部return,如果上一个操作返回的值被现操作使用,则只return现操作即可:
a = tf.Variable(5.0)
import tensorflow as tf
a = tf.Variable(5.0)
def add():
a_change = tf.assign(a, 10.0)
y = a_change + 1
return y
sess = tf.Session()
sess.run(tf.global_variables_initializer())
print(sess.run(add()))
print(sess.run(a))
输出:
11.0
10.0
关于用def函数进行封装的操作是否在tf计算图上的说明:
import tensorflow as tf
a = tf.Variable(5.0)
def add():
a_change = tf.assign(a, 10.0)
return a_change
sess = tf.Session()
sess.run(tf.global_variables_initializer())
print(sess.run(add()))
print(sess.run(a))
上述的tf操作被封装在add()函数中,没有被放在计算图中,若要放在计算图中,则需要调用函数:
import tensorflow as tf
a = tf.Variable(5.0)
def add():
a_change = tf.assign(a, 10.0)
return a_change
add()
sess = tf.Session()
sess.run(tf.global_variables_initializer())
print(sess.run(add()))
print(sess.run(a))
Tensorflow gradients好像不支持 int型的Tensor 的gradients 把w1的设置成float类型的例如tf.float32 gards就能算了,而且tensorflow梯度值一般都是float32类型的。
第二种情况:
第二种情况跟第一种情况是一类情况。。
https://blog.csdn.net/blythe0107/article/details/72818047
Tensorflow报错:
TypeError: Fetch argument None has invalid type <class 'NoneType'>
报错完整内容:
File "D:/Workspace/SpyderWorkspace/Models/RBM_mnist.py", line 211, in main
sess.run(rbm.train_ops(k, step, i),feed_dict={X: X_batch})
File "D:\Program Files\Anaconda3\lib\site-packages\tensorflow\python\client\session.py", line 767, in run
run_metadata_ptr)
File "D:\Program Files\Anaconda3\lib\site-packages\tensorflow\python\client\session.py", line 952, in _run
fetch_handler = _FetchHandler(self._graph, fetches, feed_dict_string)
File "D:\Program Files\Anaconda3\lib\site-packages\tensorflow\python\client\session.py", line 408, in __init__
self._fetch_mapper = _FetchMapper.for_fetch(fetches)
File "D:\Program Files\Anaconda3\lib\site-packages\tensorflow\python\client\session.py", line 227, in for_fetch
(fetch, type(fetch)))
TypeError: Fetch argument None has invalid type <class 'NoneType'>
发现是从sess.run()那行报错。
构建图的代码中,RBM是一个类,train_ops是该类下的函数。rbm是类RBM的一个对象,调用train_ops函数。
train_ops函数定义如下:
def train_ops(self, k, step, batch_count):
...(省略)
with tf.name_scope("update_params"):
tf.assign(self.W, self.W + self.learning_rate * delta_W,name="update_W")
tf.assign(self.bv, self.bv + self.learning_rate*delta_bv,name="update_bv")
tf.assign(self.bh, self.bh + self.learning_rate*delta_bh,name="update_bh")
函数的主要功能是更新参数,于是定义了更新参数操作。而报错的原因在于定义的train_ops函数没有返回值。
正确的代码如下:
def train_ops(self, k, step, batch_count):
...(省略)
with tf.name_scope("update_params"):
new_W = tf.assign(self.W, self.W + self.learning_rate * delta_W,name="update_W")
new_bv = tf.assign(self.bv, self.bv + self.learning_rate*delta_bv,name="update_bv")
new_bh = tf.assign(self.bh, self.bh + self.learning_rate*delta_bh,name="update_bh")
return (new_W, new_bv, new_bh)
至此,报错解决。
第三种情况:
这种情况其实比较傻。。
https://blog.csdn.net/qq_41000891/article/details/84555225
写了一个TensorFlow卷积神经网络的训练程序。
基于mnist数据集进行训练和测试。
但是在程序运行的时候报出了下面的错误。
Traceback (most recent call last):
File "nn_eg.py", line 104, in <module>
train_loss, train_op = sess.run([loss, train_op], {input_x: batch[0], output_y: batch[1]})
File "/home/zhonghangalex/venv/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 929, in run
run_metadata_ptr)
File "/home/zhonghangalex/venv/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 1137, in _run
self._graph, fetches, feed_dict_tensor, feed_handles=feed_handles)
File "/home/zhonghangalex/venv/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 471, in __init__
self._fetch_mapper = _FetchMapper.for_fetch(fetches)
File "/home/zhonghangalex/venv/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 261, in for_fetch
return _ListFetchMapper(fetch)
File "/home/zhonghangalex/venv/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 370, in __init__
self._mappers = [_FetchMapper.for_fetch(fetch) for fetch in fetches]
File "/home/zhonghangalex/venv/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 370, in <listcomp>
self._mappers = [_FetchMapper.for_fetch(fetch) for fetch in fetches]
File "/home/zhonghangalex/venv/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 258, in for_fetch
type(fetch)))
TypeError: Fetch argument None has invalid type <class 'NoneType'>
这里我们看到错误指向的是代码的104行,我将这部分的代码贴出来:
# 训练神经网络
for i in range(20000):
batch = mnist.train.next_batch(50) #从Train(训练)数据集里取下一个50样本
train_loss, train_op = sess.run([loss, train_op], {input_x: batch[0], output_y: batch[1]})
if i % 100 == 0:
test_accuracy = sess.run(accuracy, {input_x: test_x, output_y: test_y})
print("Step=%d, Train loss=%.4f, [Test accuracy=%.2f]" % (i, train_loss, test_accuracy))
这是对神经网络训练的过程,指定训练20000步,有一个奇怪的现象就是,循环的第一步进行得很顺畅,可是从第二步开始就报了这个错误:
这就说明了应该是变量出现了问题。
查阅资料后发现是因为:
train_op变量重新分配给结果的第二个元素sess.run()(恰好是None)。因此,在第二次迭代中,train_op是None,这导致错误。 解决的方法很简单,就是把两个变量的第二个变量改为“_”:
# 训练神经网络
for i in range(20000):
batch = mnist.train.next_batch(50) #从Train(训练)数据集里取下一个50样本
train_loss, _ = sess.run([loss, train_op], {input_x: batch[0], output_y: batch[1]})
if i % 100 == 0:
test_accuracy = sess.run(accuracy, {input_x: test_x, output_y: test_y})
print("Step=%d, Train loss=%.4f, [Test accuracy=%.2f]" % (i, train_loss, test_accuracy))
这样便成功开始了训练:
更多请参考;https://coding.imooc.com/learn/questiondetail/43916.html
说点题外话
注意新手要注意避免梯度检查,以及除零,以及softmax损失值中的nan,inf,以及e的指数次方等问题。
编码问题也很重要,源代码文件第一行添加:#coding:utf-8,这样就可以避免了,
runfile('E:/hnudianshuji/TensorFlow/class4/train_tfrecord.py', wdir='E:/hnudianshuji/TensorFlow/class4')
第四种情况:
我觉得这种情况可能比较重要。
https://blog.csdn.net/u012526003/article/details/61749863
代码网址:
https://github.com/littletomatodonkey/tensorflow_practice/
AlexNet
代码网址
https://github.com/littletomatodonkey/tensorflow_practice/blob/master/alexnet_benchmark.py
跑分结果图
VGGNet
代码网址
https://github.com/littletomatodonkey/tensorflow_practice/blob/master/vggnet_benchmark.py
跑分结果图
GoogleInceptionNet
ResNet
遇到的问题
类型无效或者为NoneType
TypeError: Fetch argument None has invalid type
- gradient中的因变量必须与所有的自变量均有关系,才能进行梯度的求解,否则会报这个错误
- 出现原因:之前搭建网络时,写错了一个变量,导致少了一层cnn,但是变量仍然被考虑进去了,最后的优化结果却与该变量无关,在求gradient(sess.run())时,出现了该问题
- 参考的链接:http://blog.csdn.net/u012436149/article/details/53905797
或者可以看看stackoverflow上面提问:
https://stackoverflow.com/questions/49272228/tensorflow-typeerror-fetch-argument-none-has-invalid-type-class-nonetype-wh
主要意思也是说,无关变量,无法求导。
https://cloud.tencent.com/developer/ask/202312/answer/314611
如果图中它们之间没有显式连接,则返回梯度。 在您的代码中,似乎所有声明的变量都有连接,因此可能是从其他图形加载变量的情况。 您可以使用:
print([v.name for v in tf.all_variables()])
并且仅检查预期变量是此图的一部分。
print([v.name for v in tf.all_variables()])
并且仅检查预期变量是此图的一部分。
第五种情况:
这种情况其实是我真正遇到的问题,其实也算是第四种情况的升级版。。
起因:本来想看看
g = tf.get_default_graph()
with g.gradient_override_map({"Sign": "Identity"}):
对tf.sign函数的影响,发现这个确实有用。
可以看看下面两段代码:
import tensorflow as tf
w1 = tf.constant([2])
w2 = tf.constant([3])
temp = tf.multiply(w1, w2)
g = tf.get_default_graph()
#with g.gradient_override_map({"Sign": "Identity"}):
res = tf.sign(temp*2)
grads = tf.gradients(res,[w1,w2])
with tf.Session() as sess:
tf.global_variables_initializer().run()
re = sess.run(grads)
print(re)
########################分割线,注释下面所有的代码,运行上面的代码,或者注释上面所有的代码,运行下面的代码,比较结果不同#####################################
import tensorflow as tf
w1 = tf.constant([2])
w2 = tf.constant([3])
temp = tf.multiply(w1, w2)
g = tf.get_default_graph()
with g.gradient_override_map({"Sign": "Identity"}):
res = tf.sign(temp*2)
grads = tf.gradients(res,[w1,w2])
with tf.Session() as sess:
tf.global_variables_initializer().run()
re = sess.run(grads)
print(re)
你甚至还可以自己注册标志并定义函数:
import tensorflow as tf
import tensorlayer as tl
import numpy as np
@tf.RegisterGradient("aQuantizeGrad")
def _sign_grad(tytyteyydoop,grad):
return tf.clip_by_value(grad, -1, 10)
def sign(x):
with tf.get_default_graph().gradient_override_map({"Sign": "aQuantizeGrad"}):
return tf.sign(x, name='sign')
w1 = tf.Variable(4)
w2 = tf.Variable(3)
a = tf.multiply(w1,w2)
#g = tf.get_default_graph()
#with g.gradient_override_map({"Sign":"Sign_QuantizeGrad"}):
#clip = tf.sign(a)
#clip = tf.maximum(w1, w2)
clip = sign(a)
m = tf.multiply(clip,3)
m = tf.multiply(clip,-2)
m = tf.multiply(clip,13)
gradients = tf.gradients(m, xs=[w1,w2])
with tf.Session() as sess:
tf.global_variables_initializer().run()
print(sess.run(m))
print(sess.run(gradients))
题外话:
如果自己自定义(然后通过注册的方式),可以实现基本的自定义的梯度回传的,其次还可以同另外一个函数tf.pyfunc来实现自定义梯度回传。但这只是最基本,想自定义更加高级的操作,则需要去改底层代码,注册更多函数,甚至重新编译安装。
回到话题,于是我想看看这样的效果:
import tensorflow as tf
#w1 = tf.constant([-2.0,-1.0])
g = tf.get_default_graph()
#res = tf.sign(w1)
#res=tf.where(tf.greater(w1,0.0),w1, tf.zeros_like(w1, tf.float32))
def _compute_threshold(x):
"""
ref: https://github.com/XJTUWYD/TWN
Computing the threshold.
"""
x_sum = tf.reduce_sum(tf.abs(x), reduction_indices=None, keep_dims=False, name=None)
threshold = tf.div(x_sum, tf.cast(tf.size(x), tf.float32), name=None)
threshold = tf.multiply(0.7, threshold, name=None)
return threshold
W = tf.constant([2.0,-1.0])
threshold = _compute_threshold(W)
g = tf.get_default_graph()
with g.gradient_override_map({"Greater": "Identity"}):
with g.gradient_override_map({"Where": "Identity"}):
alpha1_temp1 = tf.where(tf.greater(W, 1.0), W, tf.zeros_like(W, tf.float32))
alpha1_temp2 = tf.where(tf.less(W, -0.5), W, tf.zeros_like(W, tf.float32))
alpha_array = tf.add(alpha1_temp1, alpha1_temp2, name=None)
alpha_array_abs = tf.abs(alpha_array)
alpha_array_abs1 = tf.where(tf.greater(alpha_array_abs, 0), tf.ones_like(alpha_array_abs, tf.float32), tf.zeros_like(alpha_array_abs, tf.float32))
alpha_sum = tf.reduce_sum(alpha_array_abs)
n = tf.reduce_sum(alpha_array_abs1)
alpha = tf.div(3.0, n)
#W = tf.get_variable(name='W', shape=(10, 10), dtype=tf.float32)
# W = tl.act.sign(W) # dont update ...
grads = tf.gradients(alpha1_temp1 ,W)
with tf.Session() as sess:
tf.global_variables_initializer().run()
re = sess.run(grads)
print(re)
print(sess.run(threshold))
print(sess.run(alpha_array_abs))
print(sess.run(alpha))
结果发现,这种情况,其实吧,你要是了解tf.where以及tf.greater就更好了。。这两个函数更像是关系运算,而关系运算对于这种静态图框架,可以说是一大软肋。。而这种关系运算如果想建立梯度关系的话,一般要么是设置none(不可导),要么直接设置梯度0,或者identity,也就是梯度1。
而我发现,后来想想,其实也应该这样,上面的g.gradient_override_map好像加了与不加,没什么关系。。其实也可能是这几个函数自身就设置了identity吧。
更重要的是,上面的函数,如果原变量与输出变量不建立运算关系的话,是无法计算梯度的,若强行直接计算会报上面一直提的错误信息。但是如果这个关系运算(或者称为与原变量无关的运算),参与了后面其他与原变量的运算(操作),那么之前那个也自然不会报错,直接跳过无关运算的求导(自动处理)。
比如你可以试试:
alpha1_temp1 = tf.where(tf.greater(W, 1.0), W, tf.zeros_like(W, tf.float32))
alpha1_temp1 = tf.where(tf.greater(W, 3.0), W, tf.zeros_like(W, tf.float32))
alpha1_temp1 = tf.where(tf.greater(W, 1.0), W, W)
alpha1_temp1 = tf.where(tf.greater(W, 3.0), W, W)
分别求tf.gradients(alpha1_temp1,W)
,看看效果。
而
alpha = tf.div(3.0, n)
,如果直接tf.gradients(alpha,W)
,或者tf.gradients(n,W)
,都是会直接报错的。
而alpha = tf.div(W*W, n)
或者alpha = tf.div(alpha_sum, n)
,就不会报错,可以顺利求导,而且我也认为这样是合理的。
切记切记,tensorflow是图,计算图,一种图模型,你始终是在构建一个计算模型(姑且可以认为它是静态计算图)。
要想参与计算,包括梯度计算,必须要有对应算子参与构建数据流图,最终形成一张计算图,这样才能启动tensorflow引擎。。
除此之外,再介绍一种特别相似的报错,如下:
TypeError: ‘NoneType’ object is not callable
这种报错暂时还不算严重的错误,通过重新运行代码可以避免。。
暂时还不知道原因,但是往往与上面的使用一样,也就是这些与特殊函数使用有关,所以这里也建议,最好不要随便使用这些函数作为梯度反传要经过的操作,否则可能得不到想要的结果,毕竟它们归根到底是条件表达式,tensorflow这些框架可能不是太支持,也不够稳定。要真正使用自定义的函数以及梯度反传,还是需要自己设计并注册函数的,当然这是另外一个话题了。。
print("100000000000000000000000000000000000000000")
import tensorflow as tf
def _compute_threshold(x):
"""
ref: https://github.com/XJTUWYD/TWN
Computing the threshold.
"""
x_sum = tf.reduce_sum(tf.abs(x), reduction_indices=None, keep_dims=False, name=None)
threshold = tf.div(x_sum, tf.cast(tf.size(x), tf.float32), name=None)
threshold = tf.multiply(0.7, threshold, name=None)
return threshold
def _compute_alpha(x):
"""
Computing the scale parameter.
"""
threshold = _compute_threshold(x)
alpha1_temp1 = tf.where(tf.greater(x, threshold), x, tf.zeros_like(x, tf.float32))
alpha1_temp2 = tf.where(tf.less(x, -threshold), x, tf.zeros_like(x, tf.float32))
alpha_array = tf.add(alpha1_temp1, alpha1_temp2, name=None)
alpha_array_abs = tf.abs(alpha_array)
alpha_array_abs1 = tf.where(tf.greater(alpha_array_abs, 0), tf.ones_like(alpha_array_abs, tf.float32), tf.zeros_like(alpha_array_abs, tf.float32))
alpha_sum = tf.reduce_sum(alpha_array_abs)
n = tf.reduce_sum(alpha_array_abs1)
alpha = tf.div(alpha_sum, n)
return alpha
def _ternary_operation(x):
"""
Ternary operation use threshold computed with weights.
"""
g = tf.get_default_graph()
with g.gradient_override_map({"Sign": "Identity"}):
threshold = _compute_threshold(x)
x = tf.sign(tf.add(tf.sign(tf.add(x, threshold)), tf.sign(tf.add(x, -threshold))))
return x
W = tf.get_variable(name='W', shape=(10, 10), dtype=tf.float32)
# W = tl.act.sign(W) # dont update ...
alpha = _compute_alpha(W)
W1 = _ternary_operation(W)
W2 = tf.multiply(alpha, W1)
grads1 = tf.gradients(W2 ,W)
grads2 = tf.gradients(alpha ,W)
grads3 = tf.gradients(W1 ,W)
grads4 = tf.gradients(W2 ,W1)
grads5 = tf.gradients(W2 ,alpha)
res=tf.multiply(alpha,grads3) + tf.multiply(tf.reduce_sum(W1),grads2)
with tf.Session() as sess:
tf.global_variables_initializer().run()
re = sess.run(grads1)
print(re)
print(sess.run(grads2))
print(sess.run(grads3))
print(sess.run(alpha))
print(sess.run(W1))
print(sess.run(grads4))
print(sess.run(grads5))
print(sess.run(res))
print(sess.run(res)==sess.run(grads1))
如果报错,可能显示如下,这是你需要重新运行。。
如果不报错,输出如下:
你还可以看看这个,便于对上面理解:
import tensorflow as tf
a=tf.constant([1,2,3])
b=a
c=tf.reduce_sum(a)
d=tf.multiply(b,c)
sess.run(tf.gradients(d,a))
sess.run(tf.gradients(d,b))
sess.run(tf.gradients(d,c))
a=tf.constant([1,2,3])
b=tf.multiply(1,a)
c=tf.reduce_sum(a)
d=tf.multiply(b,c)
sess.run(tf.gradients(d,a))
sess.run(tf.gradients(d,b))
sess.run(tf.gradients(d,c))
a=tf.constant([1,2,3])
b=tf.multiply(2,a)
c=tf.reduce_sum(a)
d=tf.multiply(b,c)
sess.run(tf.gradients(d,a))
sess.run(tf.gradients(d,b))
sess.run(tf.gradients(d,c))
a=tf.constant([1,2,3])
b=tf.multiply(a,a)
d=tf.multiply(b,a)
sess.run(tf.gradients(b,a))
sess.run(tf.gradients(d,a))
sess.run(tf.gradients(d,b))
a=tf.constant([1,2,3])
b=tf.reduce_sum(a)
c=tf.multiply(a,b)
sess.run(tf.gradients(c,a))
讲真要全部弄懂上面的输出,还是需要功夫的,需要了解的几点就是,链式法则,全导数与偏导数,计算精度(四舍五入),矩阵,向量以及变量之间相互求导。
更多可以参考:
https://www.cnblogs.com/weiyinfu/p/10071955.html
今天的文章Tensorflow报错:TypeError: Fetch argument None has invalid type class ‘NoneType’分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/31966.html