TensorFlow入门
3.1文件读取流程
3.1.1文件读取流程
●第一阶段构造文件名队列
●第二阶段读取与解码
●第三阶段批处理.
注:这些操作需要启动运行这些队列操作的线程,以便我们在进行文件读取的过程中能够顺利进行入队出队操作
1.构造文件名队列
将需要读取的文件的文件名放入文件名队列tf.train.string_input_producer(string_tensor,shuffle=True)
string_tensor:含有文件名+路径的1阶张量
num_epochs:过几遍数据,默认无限过数据
return文件队列
2读取与解码
从队列当中读取文件内容,并进行解码操作。
- 1)读取文件内容
阅读器默认每次只读取一个样本
具体说来:
文本文件默认一次读取一行
图片文件默认一次读取一张图片
二进制文件一次读取指定字节数(最好是一个样本的字节数)
TFRecords默认一次读取一个example
tf.TextLineReader
:阅读文本文件逗号分隔值(CSV)格式,默认按行读取。return: 读取器实例
tf.WholeFileReader
: 用于读取图片文件。return: 读取器实例
tf.FixedLengthRecordReader(record_bytes)
: 二进制文件。要读取每个记录是固定数量字节的二进制文件。record_ bytes: 整型,指定每次读取(一个样本)的字节数。return: 读取器实例
tf.TFRecordReader
: 读取TFRecords文件。return: 读取器实例
注:
1.它们有共同的读取方法: read(file_queue)
, 并且都会返回一个Tensors元组(key文件名字,value默认的内容(一个样本))
2.由于默认只会读取一个样本,所以如果想要进行批处理,需要使用
tf.train.batch
或tf.train.shuffle_batch
进行批处理操作,便于之后指定每批次多个样本的训练。
- 2)内容解码
读取不同类型的文件,也应该对读取到的不同类型的内容进行相对应的解码操作,解码成统一的Tensor格式
●tf.decode_csv
:解码文本文件内容
●tf.image.decode_jpeg(contents)
。将JPEG编码的图像解码为uint8张量
。return:uint8张量, 3-D形状[height, width, channels]
●tf.image.decode_png(contents)
。将PNG编码的图像解码为uint8张量
。return:张量 类型,3-D形状[height, width, channels]
●tf.decode_raw
:解码二进制文件内容
。与tf.FixedLengthRecordReader搭配使用,二进制读取为uint8类型
解码阶段,默认所有的内容都解码成tf.uint8类型,如果之后需要转换成指定类型则可使用tf.cast()进行相应转换。
- 3)批处理
解码之后,可以直接获取默认的一个样本内容了,但如果想要获取多个样本,需要加入到新的队列进行批处理。
●tf.train.batch(tensors, batch_size, num_threads = 1, capacity = 32,name=None)
。读取指定大小(个数)的张量
。tensors: 可以是包含张量的列表,批处理的内容放到列表当中
。batch_size:从队列中读取的批处理大小
。num_threads: 进入队列的线程数
。capacity: 整数,队列中元素的最大数量
。return:tensors
●tf.train.shuffle_batch
3.1.2线程操作
以上用到的队列都是tf.train.QueueRunner
对象。
每个QueueRunner都负责一个阶段,tf.train.start_queue_runners
函数会要求图中的每个QueueRunner启动它的运行队列操作的线程。(这些操作需要在会话中开启)
●tf.train.start queue_runners(sess=None, coord=None)
。收集图中所有的队列线程,默认同时启动线程
。sess: 所在的会话
。coord: 线程协调器
。return: 返回所有线程
●tf.train.Coordinator()
。线程协调员,对线程进行管理和协调
。request_ sto(): 请求停止
。should_ stop(): 询问是否结束
。join(threads=None, stop_ grace_ period_ secs=120)
: 回收线程。return: 线程协调员实例
读取图片文件实例:
import tensorflow as tf
import os
def picture_read(file_list):
#图片读取案例
#1.构造文件名队列
file_queue=tf.train.string_input_producer(file_list)
#2.读取与解码
#读取阶段
reader=tf.WholeFileReader()
#key文件名 value一张图片的原始编码形式
key,value=reader.read(file_queue)
#print("key:\n",key)
#print("value:\n",value)
#解码解读那
image=tf.image.decode_jpeg(value)
print(image)
#图像形状、类型修改
image_resized=tf.image.resize_images(image,[200,200])
print("image_resized:\n",image_resized)
#静态形状修改
image_resized.set_shape([200,200,3])
print("image_resized.set_shape:\n", image_resized)
#3.批处理
image_batch=tf.train.batch([image_resized],batch_size=100,num_threads=1,capacity=100)
print("image_batch:\n",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_resized_new,image_batch_new=sess.run([key,value,image, image_resized,image_batch])
print("key_new:\n",key_new)
print("value_new\n",value_new)
print("image_new\n",image_new)
print("image_resized_new\n", image_resized_new)
print("image_batch_new\n", image_batch_new)
#回收线程
coord.request_stop()
coord.join(threads)
return None
if __name__ == '__main__':
#构造路径+文件名的列表
filename = os.listdir("D:\\NewForWwy\\workspaceForTensorflow\\20200831\\picture")
#print(filename)
#拼接路径+文件名
file_list = [os.path.join("D:\\NewForWwy\\workspaceForTensorflow\\20200831\\picture\\",file) for file in filename]
#print(file_list)
picture_read(file_list)
3.6 神经网络原理
神经网络解决多分类问题最常用的方法是设置n个输出节点,其中n为类别的个数。
任意事件发生的概率都在0和1之间,且总有某一个事件发生(概率的和为1)。如果将分类问题中“一个样例属于某一个类别"看成一 个概率事件,那么训练数据的正确答案就符合一个概率分布。如何将神经网络前向传播得到的结果也变成概率分布呢? Softmax回归就是一个非常常用的方法。
3.6.1softmax回归
softmax回归将神经网络输出转换成概率结果
3.6.2 交叉熵损失
2损失大小
神经网络最后的损失为平均每个样本的损失大小。对所有样本的损失求和取其平均值
3.6.3网络原理总结
训练过程中计算机会尝试一点点增大或减小每个参数, 看其能如何减少相比于训练数据集的误差,以望能找到最优的权重、偏置参数组合。
3.6.4 softmax、交叉熵损失API
tf.nn.softmax_cross_entropy_with_logits(labels=None,logits=None,name=None)
计算logits和labels之间的交叉损失熵
labels:标签值(真实值)
logits:样本加权之后的值
return:返回损失值列表
tf.reduce_mean(input_tensor)
计算张量的尺寸的元素平均值
3.7案例:Mnist数据集,手写数字识别
3.7.1数据集介绍
Mnist数据集:官网下载
3.7.2Mnist数据获取API
TensorFlow框架自带了获取这个数据集的接口.所以不需要自行读取。
from tensorlow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets(path, one_hot=True)
. mnist.train.next_batch(100)(提供批量获取功能)
. mnist.train.images. labels
. mnist.test.images. labels
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
def full_connection():
#用全连接来对手写识别进行识别
#1.准备数据
mnist=input_data.read_data_sets("./data",one_hot=True)
x=tf.placeholder(dtype=tf.float32,shape=[None,784])#特征值
y_true=tf.placeholder(dtype=tf.float32,shape=[None,10])#真实值
#2.构建模型
weights=tf.Variable(initial_value=tf.random_normal(shape=[784,10]))
bias=tf.Variable(initial_value=tf.random_normal(shape=[10]))
y_predict=tf.matmul(x,weights)+bias
#3.构造损失函数
error=tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_true,logits=y_predict))
#4.优化损失
optimizer=tf.train.GradientDescentOptimizer(learning_rate=0.01).minimize(error)
#5.准确率计算
#1)比较输出的结果最大值所在位置和真实值所在位置
#np.argmax()
#y_true的形状(None,10)
equal_list=tf.equal(tf.argmax(y_true,1),tf.argmax(y_predict,1))
#2)求平均
accuracy=tf.reduce_mean(tf.cast(equal_list,tf.float32))
#初始化变量
init=tf.global_variables_initializer()
#开启会话
with tf.Session() as sess:
sess.run(init)
image,label=mnist.train.next_batch(100)
print("训练之前,损失为:%f" % sess.run(error,feed_dict={x:image,y_true:label}))
#开始训练
for i in range(100):
_,loss,accuracy_value= sess.run([optimizer,error,accuracy],feed_dict={x:image,y_true:label})
print("第%d次的训练,损失为%f,准确率为%f" % (i+1,loss,accuracy_value))
return None
if __name__ == '__main__':
full_connection()
4.卷积神经网络CNN
原理可以看别人的博客,我已经懒得写了
案例:CNN识别手写数字代码实现
import tensorflow as tf
import os
from tensorflow.examples.tutorials.mnist import input_data
def creat_weights(shape):
return tf.Variable(initial_value=tf.random_normal(shape=shape))
def create_model(x):
# 构造卷积神经网络
#1)第一个卷积大层
with tf.variable_scope("conv1"):
#卷积层
#将x[None,784]形状进行修改
input_x=tf.reshape(x,shape=[-1,28,28,1])
#定义filter和偏置
conv1_weights=creat_weights(shape=[5,5,1,32])
conv1_bias = creat_weights(shape=[32])
conv1_x = tf.nn.conv2d(input=input_x,filter=conv1_weights,strides=[1,1,1,1],padding="SAME")+conv1_bias
#激活层
relu1_x=tf.nn.relu(conv1_x)
#池化层
pool1_x=tf.nn.max_pool(value=relu1_x,ksize=[1,2,2,1],strides=[1,2,2,1],padding="SAME")
#2)第二个卷积大层
with tf.variable_scope("conv2"):
# 卷积层
# 定义filter和偏置
conv2_weights = creat_weights(shape=[5, 5, 32, 64])
conv2_bias = creat_weights(shape=[64])
conv2_x = tf.nn.conv2d(input=pool1_x, filter=conv2_weights, strides=[1, 1, 1, 1], padding="SAME") + conv2_bias
# 激活层
relu2_x = tf.nn.relu(conv2_x)
# 池化层
pool2_x = tf.nn.max_pool(value=relu2_x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding="SAME")
#3)全链接层
with tf.variable_scope("full_connection"):
#[None,7,7,64]→[None,7*7*64}
#[None,7*7*64]*[7*7*64,10]=[None,10]
x_fc = tf.reshape(pool2_x,shape=[-1,7*7*64])
weights_fc=creat_weights(shape=[7*7*64,10])
bias_fc=creat_weights(shape=[10])
y_predict=tf.matmul(x_fc,weights_fc)+bias_fc
return y_predict
def full_connection_mnist():
#用全连接来对手写识别进行识别
#1.准备数据
mnist=input_data.read_data_sets("./data",one_hot=True)
with tf.variable_scope("mnist_data"):
x=tf.placeholder(dtype=tf.float32,shape=[None,784])#特征值
y_true=tf.placeholder(dtype=tf.float32,shape=[None,10])#真实值
y_predict=create_model(x)
#3.构造损失函数
error=tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_true,logits=y_predict))
#4.优化损失
optimizer=tf.train.GradientDescentOptimizer(learning_rate=0.01).minimize(error)
#5.准确率计算
#1)比较输出的结果最大值所在位置和真实值所在位置
#np.argmax()
#y_true的形状(None,10)
equal_list=tf.equal(tf.argmax(y_true,1),tf.argmax(y_predict,1))
#2)求平均
accuracy=tf.reduce_mean(tf.cast(equal_list,tf.float32))
#初始化变量
init=tf.global_variables_initializer()
#开启会话
with tf.Session() as sess:
sess.run(init)
image,label=mnist.train.next_batch(100)
print("训练之前,损失为:%f" % sess.run(error,feed_dict={x:image,y_true:label}))
#开始训练
for i in range(100):
_,loss,accuracy_value= sess.run([optimizer,error,accuracy],feed_dict={x:image,y_true:label})
print("第%d次的训练,损失为%f,准确率为%f" % (i+1,loss,accuracy_value))
return None
if __name__ == '__main__':
full_connection_mnist()