此文章是我在阅读该书第一章(MNIST 机器学习入门…)时,我遇到的问题的总结.
1. 关于mnist数据集
from tensorflow.examples.tutorials.mnist import input_data
# 从MNIST_data/中读取MNIST数据。这条语句在数据不存在时,会自动执行下载
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
注意:one_hot=True是把labels转成one_hot,默认是False.
使用one_hot的原因是现在多分类CNN网络的输出通常是softmax层,输出是一个概率分布,从而要求输入的标签也以概率分布的形式出现,进而算交叉熵。
通过上面程序得到mnist数据集,具体属性如下表:
注意:如果想知道导入数据的具体代码,可以参考这个博客
附上导入数据完整程序:
from tensorflow.examples.tutorials.mnist import input_data
# 从MNIST_data/中读取MNIST数据。这条语句在数据不存在时,会自动执行下载
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
# 查看训练数据的大小
print(mnist.train.images.shape) # (55000, 784)
print(mnist.train.labels.shape) # (55000, 10)
# 查看验证数据的大小
print(mnist.validation.images.shape) # (5000, 784)
print(mnist.validation.labels.shape) # (5000, 10)
# 查看测试数据的大小
print(mnist.test.images.shape) # (10000, 784)
print(mnist.test.labels.shape) # (10000, 10)
# 打印出第0幅图片的向量表示
print(mnist.train.images[0, :])
# 打印出第0幅图片的标签
print(mnist.train.labels[0, :])
2. 关于把numpy转成图片
from scipy import misc
import os
mnist = input_data.read_data_sets('MNIST_data/',one_hot=True)
save_dir = 'MNIST_data/raw/'
def my_makedir(path):
if not os.path.isdir(path):
os.makedirs(path)
my_makedir(save_dir)
for i in range(20):
img_name = 'mnist_train_%d.jpg' %i
img_data = mnist.train.images[i,:]
img_data = img_data.reshape(28,28)
filename = os.path.join(save_dir,img_name)
misc.toimage(img_data,cmin=0,cmax=1).save(filename)
这里保存图像用的是scipy.misc,虽然有警告说版本不合适,但是还是能运行成功。我随即试了一下PIL.Image,发现一直会报错。
im = Image.fromarray(img_data)
im.save(filename)
报错信息OSError: cannot write mode F as JPEG
我尝试添加mode=‘L’,im = Image.fromarray(img_data,mode='L')
,意思是让他以灰度图像的方式读取,结果虽然不报错,但是得到的图片却全是黑色的。
这个问题待解决。。。
3. 关于batch
mnist数据集里面应该写了next_batch这个函数,所以可以直接调用:
x_batch,y_batch = mnist.train.next_batch(100)
但是如果想用tf.train.shuffle_batch
该怎么搞呢?
x_batch,y_batch = tf.train.shuffle_batch([mnist.train.images,mnist.train.labels],
batch_size=100,capacity=60000,
num_threads=4,min_after_dequeue=10000
)
注意,上面这几个参数是必需的,不然会报错,详情参见这个博客
但是上面这个语句会报错,大致报错信息是这个
the tensor object was Tensor("shuffle_batch:0", shape=(100, 55000, 784), dtype=float32) which was passed to the feed with key Tensor("Placeholder:0", shape=(?, 784), dtype=float32).
可以看出,这个函数不能适用于图像数据展开成一维的tensor,在喂数据之前先要把784 reshape成(28,28)才行。但是这个前面已经定义好了x的维度,所以这里不适合用tf.train.shuffle_batch
这个函数。
4. 关于Tensor.eval()函数
train_accuracy = accuracy.eval(feed_dict={x:batch[0],y:batch[1],keep_prob:1.0})
print("training accuracy %g" % train_accuracy)
刚开始有点懵逼,为什么这条语句不用run也能输出结果,后来查了一下发现:
with tf.Session() as sess:
print(accuracy.eval({x:mnist.test.images,y_: mnist.test.labels}))
效果和下面语句的效果是一样的:
with tf.Session() as sess:
print(sess.run(accuracy, {x:mnist.test.images,y_: mnist.test.labels}))
这其中最主要的区别就在于你可以使用sess.run()在同一步获取多个tensor中的值,
例如:
t = tf.constant(42.0)
u = tf.constant(37.0)
tu = tf.mul(t, u)
ut = tf.mul(u, t)
with sess.as_default():
tu.eval() # runs one step
ut.eval() # runs one step
sess.run([tu, ut]) # evaluates both tensors in a single step