第三章 数据读取、神经网络
3.1 文件读取流程
学习目标:说明TensorFlow文件读取的流程
有三种获取数据到TensorFlow程序的方法:
- QueueRunner:基于队列的输入管道从TensorFlow图像开头中的文件读取数据
- Feeding:运行每一步时,Python代码提供数据
- 预加载数据:TensorFlow图中的张量包含所有数据(对于小数据集)
3.1.1 文件读取流程
第一阶段:构造文件名队列
第二阶段:读取与解码
第三阶段:批处理
注意:这些操作需要启动运行这些队列操作的线程,以便我们在进行文件读取的过程中能够顺利进行入队出队操作
1 构造文件名队列
将需要读取的文件的文件名放入到文件名队列
tf.train.strng_input_produce(string_tensor, shuffle=True)
- string_tensor:包含文件名+路径的1阶张量
- num_epochs:过几遍数据,默认无限过数据
- return:文件队列
2 读取与解码
从队列当中读取文件内容,并进行解码操作。
1)读取文件内容
阅读器默认每次只读取一个样本
具体来说:
2)内容解码
3 批处理
3.1.2 线程操作
3.1.3 总结
文件读取流程的相关API
3.2 图片读取
学习目标:
- 说明图像数字化的三要素
- 说明图片三要素与张量的表示关系
- 了解张量的存储和计算类型
- 应用tf.image.resize_images实现图像的像素改变
- 应用tf.train.start_queue_runners实现读取线程开启
- 应用tf.train.Corrdinator实现线程协调器开启
- 应用tf.train.batch实现数据的批处理
3.2.1 图像基本知识
- 组成图片最基本单位是像素
1 图片三要素
组成一张图片特征值是所有的像素值,有三个维度:图片长度、图片宽度、图片通道数
图片的通道数是什么?
描述一个像素点,如果是灰度图,那么只需要一个数值来描述它,就是单通道
如果一个像素点,有RGB三种颜色来描述它,及时三通道
- 灰度图:单通道,[长,宽,1]
- 彩色图片:三通道,[长,宽,3]
2 张量形状
3.2.2 图片特征值处理
为什么要缩放图片到统一大小?
在进行图像识别的时候,每个图片样本的特征数量要保持相同。所以需要将所有图片张量大小统一转换
缩小放大图片
tf.image.resize_images(images, size)
- images:4-D形状[batch, height, width, channels]或3-D形状的张量[height, width, channels]的图片数据
- size:1-D int32张量:new_height,new_width,图像的新尺寸
- 返回4-D格式或者3-D格式图片
3.2.3 数据格式
- 存储:unit8(阶跃空间)
- 矩阵计算:float32(提高精度)
3.2.4 案例:狗图片读取
流程:
1)构造文件名队列
2)读取与解码,使样本的形状和类型统一
3)批处理
import tensorflow as tf import os def picture_read(file_list): """ 狗图片读取案例 :return: """ # 1、构造文件名队列 file_queue = tf.train.string_input_producer(file_list) # 2、读取与解码 # 读取阶段 reader = tf.WholeFileReader() # key文件名, value一张图片的原始编码形式 key, value = reader.read(file_queue) print("key:", key) print("value:", value) # 解码阶段 image = tf.image.decode_jpeg(value) print("image;", image) # 图像的形状、类型修改 image_resize = tf.image.resize_images(image, [200,200]) print("image_resize:", image_resize) # 静态形状修改 image_resize.set_shape(shape=[200,200,3]) # 3、批处理 image_batch = tf.train.batch([image_resize], batch_size=100, num_threads=1, capacity=100) print("image_batch:", image_batch) # 开启会话 with tf.Session() as sess: # 创建线程协调员 coord = tf.train.Coordinator() # 开启线程 threads = tf.train.start_queue_runners(sess=sess, coord=coord) key_new, value_new, image_new, image_resize_new, image_batch_new = \ sess.run([key, value, image, image_resize, image_batch]) print("key_new:", key_new) print("value_new:", value_new) print("image_new:", image_new) print("image_resize_new:", image_resize_new) print("image_batch_new:", image_batch_new) # 回收线程 coord.request_stop() coord.join(threads) return None if __name__ == "__main__": # 构造路径 + 文件名的列表 filename = os.listdir("./dog") #print(filename) # 拼接路径 + 文件名 file_list = [os.path.join("dog", file) for file in filename] #print(file_list) picture_read(file_list)
3.3 二进制数据
学习目标:
- 应用tf.FixedLengthRecordReader实现二进制文件读取
- 应用tf.decode_raw实现解码二进制数据
- 说明NHWC与NCHW的区别
- 应用tf.transpose进行维度的位置修改
3.3.1 CIFAR10二进制数据集介绍
https://www.cs.toronto.edu/~kriz/cifar.html
3.3.2 CIFAR10二进制数据读取
流程分析:
1)构造文件名队列
2)读取与解码
3)批处理
先放在这里,先看神经网络,后期补上
3.5 神经网络基础
- 了解感知机结构、作用以及优缺点
- 了解tensorflow playground的使用
- 说明感知机与神经网络的联系
- 说明神经网络的组成
3.5.1 神经网络
神经网络的特点:
- 每个连接都有个权值
- 同一层神经元之间没有连接
- 最后的输出结构对应的层也称之为全连接层
3.6 神经网络原理
学习目标:
- 说明神经网络分类的原理
- 说明softmax回归
- 说明交叉熵损失
3.6.1 softmax回归
softmax回归将神经网络输出转换成概率结果
logits加上softmax映射----多分类问题
3.6.2 交叉熵损失
3.6.4 softmax、交叉熵损失API
计算logits和labels之间的交叉损失熵
tf.nn.softmax_cross_entropy_with_logits(labels=None, logits=None, name=None)
- labels:标签值(真实值)
- logits:样本加权之后的值
- return:返回损失值列表
tf.reduce_mean(input_tensor)
tf.reduce_mean(input_tensor)
计算张量的尺寸的元素平均值
3.7 案例:minst手写数字识别
3.7.1 数据集介绍
1 特征值
2 目标值
3.7.2 minst数据获取API
from tensorflow.examples.tutorials.mnist import input_data mnist = input_data.read_data_sets('mnist_data', one_hot=True) print(mnist.train.next_batch(1)) print(mnist.train.images[0]) # 查看特征值 print(mnist.train.labels[0]) # 目标值
3.7.3 实战:mnist手写体识别
1 网络设计
2 全连接层计算
import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data def full_connection(): """ 用全连接对手写数字进行识别 :return: """ # 1)准备数据 mnist = input_data.read_data_sets("./mnist_data", one_hot=True) # 用占位符定义真实数据 X = tf.placeholder(dtype=tf.float32, shape=[None, 784]) y_true = tf.placeholder(dtype=tf.float32, shape=[None, 10]) # 2)构造模型 - 全连接 # [None, 784] * W[784, 10] + Bias = [None, 10] weights = tf.Variable(initial_value=tf.random_normal(shape=[784, 10], stddev=0.01)) bias = tf.Variable(initial_value=tf.random_normal(shape=[10], stddev=0.1)) y_predict = tf.matmul(X, weights) + bias # 3)构造损失函数 loss_list = tf.nn.softmax_cross_entropy_with_logits(logits=y_predict, labels=y_true) loss = tf.reduce_mean(loss_list) # 4)优化损失 # optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01).minimize(loss) optimizer = tf.train.AdamOptimizer(learning_rate=0.01).minimize(loss) # 5)增加准确率计算 bool_list = tf.equal(tf.argmax(y_true, axis=1), tf.argmax(y_predict, axis=1)) accuracy = tf.reduce_mean(tf.cast(bool_list, tf.float32)) # 初始化变量 init = tf.global_variables_initializer() # 开启会话 with tf.Session() as sess: # 初始化变量 sess.run(init) # 开始训练 for i in range(3000): # 获取真实值 image, label = mnist.train.next_batch(100) _, loss_value, accuracy_value = sess.run([optimizer, loss, accuracy], feed_dict={X: image, y_true: label}) print("第%d次的损失为%f,准确率为%f" % (i+1, loss_value, accuracy_value)) return None if __name__ == "__main__": full_connection()