如何解决Inception Score代码中的AttributeError错误?
问题:Inception Score计算代码报错AttributeError: 'NoneType' object has no attribute 'value'
运行用于评估生成图片的Inception Score代码时持续报错,相关函数代码如下:
# Code adapted from # https://github.com/openai/improved-gan/blob/master/inception_score/model.py # which was in turn derived from # tensorflow/tensorflow/models/image/imagenet/classify_image.py # ... def _init_inception(): global softmax if not os.path.exists(MODEL_DIR): os.makedirs(MODEL_DIR) filename = DATA_URL.split('/')[-1] filepath = os.path.join(MODEL_DIR, filename) if not os.path.exists(filepath): def _progress(count, block_size, total_size): sys.stdout.write('\r>> Downloading %s %.1f%%' % ( filename, float(count * block_size) / float(total_size) * 100.0)) sys.stdout.flush() filepath, _ = urllib.request.urlretrieve(DATA_URL, filepath, _progress) print() statinfo = os.stat(filepath) print('Succesfully downloaded', filename, statinfo.st_size, 'bytes.') tarfile.open(filepath, 'r:gz').extractall(MODEL_DIR) #with tf.gfile.FastGFile(os.path.join( with tf.io.gfile.GFile(os.path.join( MODEL_DIR, 'classify_image_graph_def.pb'), 'rb') as f: graph_def = tf.compat.v1.GraphDef() graph_def.ParseFromString(f.read()) _ = tf.import_graph_def(graph_def, name='') # Works with an arbitrary minibatch size. with tf.compat.v1.Session() as sess: pool3 = sess.graph.get_tensor_by_name('pool_3:0') ops = pool3.graph.get_operations() for op_idx, op in enumerate(ops): for o in op.outputs: shape = o.get_shape() shape = [s.value for s in shape] new_shape = [] for j, s in enumerate(shape): if s == 1 and j == 0: new_shape.append(None) else: new_shape.append(s) o.set_shape(tf.TensorShape(new_shape)) w = sess.graph.get_operation_by_name("softmax/logits/MatMul").inputs[1] logits = tf.matmul(tf.squeeze(pool3, [1, 2]), w) softmax = tf.nn.softmax(logits)
错误出现在标注# Works with an arbitrary minibatch size.的代码段,错误信息如下:
Traceback (most recent call last): File "C:\Users\k\anaconda3\envs\tf\lib\contextlib.py", line 130, in __exit__ self.gen.throw(type, value, traceback) File "C:\Users\k\anaconda3\envs\tf\lib\site-packages\tensorflow_core\python\framework\ops.py", line 5385, in get_controller yield g File "D:/Git/Graduation/mytext2image-main/IS.py", line 182, in _init_inception shape = [s.value for s in shape] File "D:/Git/Graduation/mytext2image-main/IS.py", line 182, in <listcomp> shape = [s.value for s in shape] AttributeError: 'NoneType' object has no attribute 'value'
疑问:该问题是否与TensorFlow版本有关?已将所有tf替换为tf.compat.v1,求解决帮助。
解决方案
这个错误确实和TensorFlow版本兼容有关:旧代码基于TF1.x原生API编写,即使替换为tf.compat.v1,部分API的行为仍有变化。当TensorShape的维度为未知(动态维度,值为None)时,直接访问s.value会返回None,触发AttributeError。
具体修改步骤
将报错的维度遍历代码替换为更安全的标准写法:
原代码中:
shape = o.get_shape() shape = [s.value for s in shape]
替换为:
shape = o.get_shape().as_list()
as_list()是TensorFlow中获取TensorShape维度列表的标准方法,会直接返回包含None的维度列表,无需手动遍历访问.value,同时兼容TF1.x和tf.compat.v1模式。
修改后的完整代码片段
# Works with an arbitrary minibatch size. with tf.compat.v1.Session() as sess: pool3 = sess.graph.get_tensor_by_name('pool_3:0') ops = pool3.graph.get_operations() for op_idx, op in enumerate(ops): for o in op.outputs: shape = o.get_shape().as_list() # 核心修改处 new_shape = [] for j, s in enumerate(shape): if s == 1 and j == 0: new_shape.append(None) else: new_shape.append(s) o.set_shape(tf.TensorShape(new_shape)) w = sess.graph.get_operation_by_name("softmax/logits/MatMul").inputs[1] logits = tf.matmul(tf.squeeze(pool3, [1, 2]), w) softmax = tf.nn.softmax(logits)
补充说明
你已替换的tf.io.gfile.GFile、tf.compat.v1.Session等API都是正确的兼容写法,无需调整。修改后即可解决动态维度导致的NoneType属性访问错误。
内容的提问来源于stack exchange,提问作者zli2001
相关产品推荐
相关产品推荐

