TensorFlow调用tf.nn.conv2d卷积时触发AttributeError报错
问题现象
在MNIST数据集上测试模型卷积运算效果、编写卷积核可视化代码时,运行代码抛出AttributeError属性错误。
原可视化代码如下:
keep_prob=1.0 ActivatedUnits = convolve1(sampleimage) filters = ActivatedUnits.shape[3] plt.figure(1, figsize=(20,20)) n_columns = 6 n_rows = np.math.ceil(filters / n_columns) + 1 for i in range(filters): plt.subplot(n_rows, n_columns, i+1) plt.title('Filter ' + str(i)) plt.imshow(ActivatedUnits[0,:,:,i], interpolation="nearest", cmap="gray")
核心报错信息截取:
AttributeError: 'list' object has no attribute 'shape'
报错位置指向tf.nn.conv2d执行时读取输入shape属性的逻辑。
错误原因
- 传入卷积函数的
sampleimage是Python原生list类型,不具备shape属性,不符合tf.nn.conv2d对输入数据格式的要求:卷积接口要求输入必须是NumPy数组、Tensor张量这类带维度信息的类数组结构,输入维度需要匹配4维格式[batch_size, height, width, channels]。 - 代码逻辑不符合TensorFlow 1.x静态图的调用规则:原项目基于TF1.x静态图机制编写,卷积节点
convolve1只是计算图上的操作定义,直接传参调用不会执行实际计算,就算输入格式正确也无法得到卷积输出的实际数值。
修复方案
调整代码逻辑,先将输入图像转换为符合维度要求的NumPy数组,再通过会话运行卷积节点拿到激活结果,修复后代码如下:
import numpy as np import tensorflow as tf import matplotlib.pyplot as plt keep_prob = 1.0 # 将输入样本转为4维NumPy数组,MNIST为单通道28*28图,单样本batch值为1 # 假设原始sampleimage是28*28的像素列表/数组 sampleimage_arr = np.array(sampleimage, dtype=np.float32).reshape(1, 28, 28, 1) # TF1.x静态图模式下通过sess.run执行卷积节点,喂入对应数据 ActivatedUnits = sess.run( convolve1(x), feed_dict={ x: sampleimage_arr, keep_prob: 1.0 } ) filters = ActivatedUnits.shape[3] plt.figure(1, figsize=(20,20)) n_columns = 6 n_rows = np.math.ceil(filters / n_columns) + 1 for i in range(filters): plt.subplot(n_rows, n_columns, i+1) plt.title('Filter ' + str(i)) plt.imshow(ActivatedUnits[0,:,:,i], interpolation="nearest", cmap="gray") plt.show()
注意:如果是TensorFlow 2.x环境运行该代码,需要先禁用2.x默认的eager模式、适配1.x接口,或者将卷积逻辑改写为TF2.x的动态图调用形式,不需要通过sess.run即可直接拿到计算结果。
内容的提问来源于stack exchange,提问作者gsv
相关产品推荐
相关产品推荐

