TensorFlow实现Wasserstein DCGAN时ndarray转Tensor/Operation错误求助
sess.run(image_batch)的类型转换错误 嘿,我来帮你捋捋这个问题——你遇到的“Can not convert a ndarray into a Tensor or Operation”错误其实指向一个很明确的问题:你传给sess.run()的image_batch是个NumPy数组,但TensorFlow 1.x的会话只认TensorFlow自己的Tensor对象或者可执行的Operation,不认原生的NumPy数组。结合你用Keras加载MNIST的方式,咱们一步步拆解:
1. 先搞清楚image_batch的类型问题
你用keras.datasets.mnist.load_data()拿到的X_train是纯NumPy数组,如果你的代码里直接把这个数组赋值给image_batch,然后就塞给sess.run(),那肯定会报错。TensorFlow 1.x的会话运行逻辑是基于计算图的,必须把数据包装成计算图里的Tensor才行。
给你两个常用的正确姿势:
- 占位符+feed_dict方式(适合小数据集或者快速调试):
# 先定义一个占位符,对应MNIST图片的形状 image_placeholder = tf.placeholder(tf.float32, shape=[None, 28, 28, 1]) # 后续构建判别器/生成器模型时,都用这个占位符作为输入 # 训练的时候再通过feed_dict把NumPy数组的批次数据传进去 _, disc_loss_val = sess.run([train_disc_op, disc_loss], feed_dict={image_placeholder: X_train_batch})
- tf.data数据集管道(更高效,推荐用于WGAN这类需要稳定数据输入的场景):
# 先预处理MNIST数据:加通道维度,归一化到WGAN常用的[-1,1]区间 X_train = X_train.reshape(-1, 28, 28, 1).astype('float32') X_train = (X_train - 127.5) / 127.5 # 用tf.data把数组转换成TensorFlow的数据集 dataset = tf.data.Dataset.from_tensor_slices(X_train) dataset = dataset.shuffle(60000).batch(your_batch_size) # 创建迭代器 iterator = dataset.make_initializable_iterator() image_batch = iterator.get_next() # 训练前别忘了初始化迭代器! sess.run(iterator.initializer) # 现在再run image_batch就没问题了 current_batch = sess.run(image_batch)
2. 关于异常处理触发二次异常的问题
这个大概率是你在异常处理的代码块里又做了调用sess.run()或者操作未正确初始化的Tensor/数组的操作。建议先把异常处理代码注释掉,先解决核心的类型转换错误,等主流程跑通了,再回头调试异常处理的逻辑,这样更容易定位问题。
3. 针对你用的W-DCGAN代码的具体调整
你用的代码里应该是直接把Keras加载的NumPy数组当成TensorFlow的Tensor来用了,所以得做这几个关键调整:
- 必须对MNIST数据做预处理:补全通道维度,归一化到[-1,1](WGAN对数据归一化的要求比普通DCGAN更严格)
- 把原始NumPy数组用上面说的两种方式之一包装成TensorFlow的Tensor,再作为
image_batch传入会话运行
4. 版本兼容性的小提醒
你用的是TensorFlow 1.4.1,这个版本的tf.data已经很稳定了,但要注意别混用Keras和TensorFlow的会话——Keras在TF1.x里会默认创建自己的会话,如果你手动创建了sess,可能会出现会话冲突的问题,建议统一用你自己创建的TensorFlow会话来管理所有操作。
最后给你个快速验证小技巧:在调用sess.run(image_batch)之前,先打印type(image_batch),如果输出是<class 'numpy.ndarray'>,那百分百就是这个类型问题,赶紧把它转成TensorFlow的Tensor再试!
内容的提问来源于stack exchange,提问作者Tanmay Bhatnagar

