今天使用 TensorFlow 来实现图片分类问题,首先我们需要那一些图片资源来训练神经网络。今天是周末,经过一周紧张工作和学习感觉有些疲劳,今天就简单给大家介绍一下,如果内容不够详细随后还会进行补充。
import os
import tarfile
# print(os.path.exists("./cifar-10-python.tar.gz"))
tarfile.open("./cifar-10-python.tar.gz", 'r:gz').extractall(".")
CIFAR_DIR = "./cifar-10-batches-py"
print(os.listdir(CIFAR_DIR))
对下载下来的 .tar.gz 压缩文件夹进行解压获取资源文件,os.listdir(CIFAR_DIR) 查看一下资源文件夹中所包含的内容。
['batches.meta', 'data_batch_1', 'data_batch_2', 'data_batch_3', 'data_batch_4', 'data_batch_5', 'readme.html', 'test_batch']
其中 'data_batch_1', 'data_batch_2', 'data_batch_3', 'data_batch_4', 'data_batch_5'为数据文件,我们打印 data 数据获取
with open(os.path.join(CIFAR_DIR,"data_batch_1"),"rb") as f:
data = pickle.load(f,encoding='latin1')
print(type(data))
with 语句我们就不用指定 f 将打开文件作为 f 使用,接下来使用 pickle 文件加载数据,在 python2 中使用 cPickle 来代替 pickle。通过打印 data 类型发现为字典类型
<class 'dict'>
我们可以尝试输出一下 data 的字典结构中键值
with open(os.path.join(CIFAR_DIR,"data_batch_1"),"rb") as f:
data = pickle.load(f,encoding='latin1')
print(type(data))
print(data.keys())
dict_keys(['batch_label', 'labels', 'data', 'filenames'])
输出 data 中 data 键对应数据的形状,发现为 numpy 为矩阵。我们图片数据都保存在 data['data'] 中
继续输出矩阵形状,也就是他是一个几维矩阵
print(data['data'].shape)
这里提供 10000 条图片的数据,32 * 32 * 3 = 3072 表示 32 x 32 图片的 RBG 数据数量
(10000, 3072)
我们知道
with open(os.path.join(CIFAR_DIR,"data_batch_2"),'rb') as f:
data = pickle.load(f,encoding='latin1')
image_arr = data['data'][100]
image_arr = image_arr.reshape(3,32,32)
image_arr = image_arr.transpose(1,2,0)
plt.imshow(image_arr)
plt.show()
接下来工作是将数据显示为图片,准备查看第 100 张图片,所有获得数组索引为 100 的数据。
根据数据格式我们知道图片是一个三通道,所以需要将要数据拆成一个 2 维数组,每个点又是一个数组保存 3 (RGB) 颜色信息。通过 reshape 来改变数组结构,(3,32,32)表示 3 通道 32 表示图片大小为 32 x 32。不过要想显示图片需要这个 32 32 3 这样结构数据,所以需要 transpose 来对数组结构进行调整。
构建神经网络
我们已经准备好了数据,现在可以搭建神经网络,开始 TensorFlow 模型。首先引入我们 TensorFlow 和 numpy 库。
定义占位符
定义占位符接受变量,x 表示输入也就是将图片像素,类型为 float32,有关 placeholder 用法和好处是我们在 Tensorflow 中需要神经网络搭建起来可以预留一些位置稍后输入数据,这就是 placeholder 的具体用法。
x = tf.placeholder(tf.float32,[None,3072])
# [None]
y = tf.placeholder(tf.int64,[None])
y 为 labels 的 placeholder 以为 y 为离散变量所有类型为 int64
None 表示输入样本数量是不确定
x = tf.placeholder(tf.float32,[None,3072])
# [None]
y = tf.placeholder(tf.int64,[None])
#[]
w = tf.get_variable('w',[x.get_shape()[-1],1],initializer=tf.random_normal)
b = tf.get_variable('b',[1],initializer=tf.constant_initializer(0.0))
y_ = tf.matmul(x,w) + b
p_y_l = tf.nn.sigmoid(y_)
y_reshaped = tf.reshape(y,(-1,1))
对于每一个 x 输入我们都需要一个权重和 x 做内积,所有维度应该和单个样本维度 3072 相同,这里使用 [x.get_shape()[-1],1] 输出为 1 initializer 这里是做初始化,这里使用正态分布。然后定义 b 为偏执。这里大家如果就得解释不够,随后当代码 coding 完,详细给大家进行解释说明。
网友评论