1. 三种获取数据到TensorFlow程序的办法
- QueueRunner:根据行列的输入管道从TensorFlow图形开头的文件中读取数据
- Feeding:运转每一步时,Pyhon代码提供数据
- 预加载数据:TensorFlow图中的张量包括一切数据(对于小数据集)
1.1 文件读取流程
大概分为三个阶段
- 第一阶段:结构文件名行列
- 方便咱们快速高效读取这组文件,先读取文件名
- 第二阶段:读取与解码
- 有读取器Reader,从上一步的文件名行列文件中以样本为单位去读取
- 第三阶段:批处理行列
- 将解码出的样本放到批处理行列中,进行后续练习
- 还需求手动敞开线程使其活动起来
下面将为这三个阶段进行具体讲解与演示。
2. 结构文件名行列
将需求读取的文件的文件名放入文件名行列
- tf.train.string_input_producer(string_tensor, shuffle=True)
- string_tensor:传入含有文件名+途径的列表
- shuffle:是否打乱数据
- num_epochs:过几遍数据,默许无限过数据,直到满意设定的批处理巨细停止
- return:文件行列
首要,咱们先导入所需模块,本事例运用Tensorflow1.x版别进行演示,但是安装了TensorFlow2.x版别,因而,咱们需求敞开兼容方式,然后使其支持运转Tensorflow1.x版别的语法。
import tensorflow as tf
import tensorflow.compat.v1 as tf
tf.disable_v2_behavior()
import os
咱们将想要读取的图片保存在了当前途径下的picture目录中。具体内部命名方式如下图所示:
然后,咱们运用os.path.join的办法拼接一下途径与图片文件名,通过变量来接收,然后传入行列函数tf.train.string_input_producer中。
def picture_read():
"""
狗图片读取事例
"""
# 1. 结构文件名行列
file_queue = tf.train.string_input_producer(file_list)
return None
filename = os.listdir("./picture")
file_list = [os.path.join("./picture/", file) for file in filename]
#print(file_list)
picture_read()
3. 读取与解码
从行列傍边读取文件内容,并进行解码操作。
3.1 读取文件内容
不同的文件类型,读取与解码的办法也会不一样。阅览器默许每次只读取一个样本。换句话说,文本文件默许一次读取一行;图片文件默许一次读取一张图片;二进制文件一次读取指定字节数(最好是一个样本的字节数)TFRecords默许一次读取一个example。
-
tf.TextLineReader
:- 阅览文本文件逗号分隔值(CSV)格局,默许按行读取
- return:读取器实例
-
tf.WholeFileReader
:- 以一张图片作为一个样本
- 用于读取图片文件
- return:读取器实例
-
tf.FixedLengthRecordReader(record_bytes)
- 二进制文件
- 要读取每个记载是固定数量字节的二进制文件
- record_bytes:整型,指定每次读取(一个样本)的字节数,要告知它固定字节数是多少
- return:读取器实例
-
tf.TFRecordReader
:- 读取TFRecords文件
- return:读取器实例
以上一切不同类型的读取器,都有一个共同的办法
.read()
。都会回来一个Tensors元组(key表示文件名,value表示读取到的这个样本内容) 由于默许只会读取一个样本,所以假如想要进行批处理,需求运用tf.train.batch或tf.train.shuffle_batch进行批处理操作,便于之后指定每批次多个样本的练习。
在结构行列代码基础上继续增加图片读取部分代码。因为咱们要读取图片类型的文件,因而选择tf.WholeFileReader
读取方式。
def picture_read():
"""
狗图片读取事例
"""
# 1. 结构文件名行列
file_queue = tf.train.string_input_producer(file_list)
# 2. 读取图片与解码
# 2.1 读取阶段
reader = tf.WholeFileReader()
# key是文件名 value是一张图片的原始编码方式
key, value = reader.read(file_queue)
print("key:\n", key)
print("value\n", value)
3.2 内容解码
读取不同类型的文件,也应该对读取到的不同类型的内容进行相对应的解码操作,解码成赞同的Tensor格局
-
tf.decode_csv:
- 解码文本文件内容
-
tf.image.decode_jpeg(contents)
- 将JPEG编码的图画解码为uint8张量
- return:uint8张量,3-D形状[height, width, channels]
-
tf.decode_raw
- 解码二进制文件内容
- 与tf.FixedLengthRecordReader搭配运用,二进制读取为uint8类型
解码阶段,默许一切的内容都解码成tf.uint8类型,假如之后需求转化成指定类型则可运用tf.cast()进行相应转化。
运用tf.image.decode_jpeg对图片进行解码
def picture_read():
"""
狗图片读取事例
"""
# 1. 结构文件名行列
file_queue = tf.train.string_input_producer(file_list)
# 2. 读取图片与解码
# 2.1 读取阶段
reader = tf.WholeFileReader()
# key是文件名 value是一张图片的原始编码方式
key, value = reader.read(file_queue)
print("key:\n", key)
print("value\n", value)
# 2.2 解码阶段
image = tf.image.decode_jpeg(value)
print("image:\n", image)
4. 批处理
解码之后,可以直接获取默许的一个样本内容了,但是假如想要获取多个样本,需求加入到新的行列进行批处理。
-
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
在批处理之前,针对本事例(狗辨认)还需求增加图片resize进程,对输入的图片的宽、高、通道数进行一致,本事例中咱们将图片的宽和高都修正(resize)成200*200,通道数设定为3。此进程需求在读取阶段后进行完结,图片解码今后运用tf.image.resize_images
函数进行图片尺度修正。
- 假如只修正了图片尺度200*200,运转程序还是会报错,咱们还需求指定图片的通道数
运用.set_shape
办法,对静态形状进行指定,指定图片的通道数为3,就可以了。
完结图片尺度修正进程后,咱们就可以进行批处理阶段了,运用tf.train.batch
函数进行批处理。
- 批处理量batch_size设定为100
- 线程数为1
- 容量100
- 将resize后的图片张量
image_AfterResize
以列表方式传入该函数
def picture_read():
"""
狗图片读取事例
"""
# 1. 结构文件名行列
file_queue = tf.train.string_input_producer(file_list)
# 2. 读取图片与解码
# 2.1 读取阶段
reader = tf.WholeFileReader()
# key是文件名 value是一张图片的原始编码方式
key, value = reader.read(file_queue)
print("key:\n", key)
print("value\n", value)
# 2.2 解码阶段
image = tf.image.decode_jpeg(value)
print("image:\n", image)
## 2.3 一致图片形状,再放入批处理行列
# (1)图画的形状、类型修正
image_AfterResize = tf.image.resize_images(image, [200, 200]) # 先修正了宽和高
print("image_AfterResize:\n", image_AfterResize)
# (2)静态形状修正
image_AfterResize.set_shape(shape=[200,200,3]) # 再修正了维度
print("image_AfterResize:\n", image_AfterResize)
# 3. 批处理
image_batch = tf.train.batch([image_AfterResize], batch_size=100, num_threads=1, capacity=100)
print("image_batch:\n", image_batch)
最终,咱们敞开会话,使其能够运转,张量就能稀有值了。敞开会话这一进程相同需求在咱们自定义的picture_read()函数中进行。
# 4. 敞开会话
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_AfterResize_new, image_batch_new = sess.run([key, value, image, image_AfterResize, image_batch])
print("key_new:\n", key_new)
print("value_new:\n", value_new)
print("image_new:\n", image_new)
print("image_AfterResize_new:\n", image_AfterResize_new)
print("image_batch_new:\n", image_batch_new)
# 回收线程
coord.request_stop()
coord.join(threads)
最终调用此自定义函数,并指定好图片数据所在途径,即可运转。 部分运转成果如下图片展现:
重要张量形状展现:
尺度修正后的图片:每一个基本单元三个元素表示一个像素点。
批处理后的图片:通过批处理,图片数据变成了四维数据,因为,100张图片组成了一个批次的新数据,而不是单张图片,因而多了一个维度。
本文正在参加「金石计划 . 分割6万现金大奖」