1. 配套使用: tf.train.Examples将数据转换为二进制,提升IO效率和方便管理

对于int类型 : tf.train.Examples(features=tf.train.Features(feature=tf.train.Feature(int64_list=tf.train.Int64List(value=[value]))))

对于bytes类型: tf.train.Examples(features=tf.train.Features(feature=tf.train.Feature(int64_list=tf.train.BytesList(value=[value]))))

2. tf.image.decode_jpeg(image, channel=3) # 将图片进行解码操作,通道数是3

参数说明:image表示图片,channel表示通道数

3. tf.image.encode_jpeg(image, format='rgb', quality=100) # 将解码后的图片,转码成jpeg

参数说明:image表示图片,format表示rgb的类型,quality表示图片的质量

4. tf.train.Coordinator() # 构建多线程通道,使用coord.join(threads)将线程列表添加

5.t = threading.Thread(target=, args=) # 建立单线程

参数说明:target表示对应的函数,args表示传入的参数

6. tf.python_io.TFRecordWriter(output_path) 构造TFR的写入器writer,使用writer.write将打包的参数写入

参数说明:output_path表示保存TFR文件的路径

7.np.linspace(0, len(3), 3) # 表示将数据进行切分,

参数说明:0表示第一个数,len(3)表示第二个数,3表示切分成3个数,

8. sys.stdout.flush() 进行数据的刷新

数据说明:在flower文件中,存在5个文件,每个文件的文件名分别对应的是标签名,在flower_label.txt保存的5个标签名

代码说明:这个采用了多线程的方式,即如果要生成n个shards,有2个thread, 那么每个thread就处理n/2个shards的生成

参数说明:使用tf.app.flags.DEFINE_string 进行参数的设置,使用FLAGS = tf.app.flags.FLAGS将参数并入FLAGS中

代码主要分为第一部分和第二部分,使用tf.app.run()执行代码,定义model(),在model中分为两部分

第一部分:用于进行文件名的读取filenames,标签的制作labels,以及存入标签名texts

第二部分:建立多个线程,在每个线程中,调用函数,建立TFR的写入writer,循环一个线程的shards数,将标准化后的example进行写入,关闭writer

第一部分:

第一步:构建find_image_files, 传入参数为文件名,标签名

第二步:使用[l.strip() for l in TF.gfile.FastGFile(f).readlines()] 来获得标签值

第三步: 循环标签值,使用os.path.join(‘%s/%s/*’%())标签值和文件路径进行拼接,获得每一个文件夹的名字

第四步: 使用tf.gfile.Glob(文件名) 获得文件名中所有的图片名称,如果报错,打印文件名,continue

第五步:定义filenames, labels, texts = []

第六步:使用.extend() 将图片列表添加到filenames, 使用[label_index] * len(matchfile)制作标签,以及[text] * len(matchfile) 制作标签名,使用.extend() 进行添加

第七步: 构造shuffed_index = np.arange(len(filenames)), 使用random.shuffle(shuffed_index) 获得混乱的标签索引值

第八步:使用filenames = [filename[i] for i in shuffed_index] 构造打乱的filenams,labels,和texts, 返回结果

第二部分:将生成的filenams,labels和texts, train_shards传入到process_image_files函数

第一步:使用assert len(filenames) == len(labels),即filenams的大小是否和labeles以及texts的大小相同

第二步:使用np.linspace(0, len(filenames), train_shards+1) 根据train_shards大小进行切分,

第三步:循环切分的列表,将两个之间的索引值添加到ranges中, ranges.append([split_index[i], split_index[i+1]]), 使用sys.stdout.flush() 刷新操作

第四步:实例化coder = ImageCode()

第一步:构造png转jpg的初始化函数,使用tf.placeholder初始化,使用tf,image.decode_png()解码png,使用tf.image.encode_jpeg()编码jpeg

第二步:构造jpg的解码的初始化函数, 使用tf.placeholder初始化,使用tf.image.decode_jpeg()解码jpg

第三步:构造函数png_to_jpeg(self, image_data), sess.run(self._png_to_jpg, feed_dict={self.png_image:image_data}),进行实际转换

第四步:构造函数decode_jpeg(self, image_data):, sess.run(self._decode_jpg) 进行实际转换

第五步:使用coord = tf.train.Coordinator() 建立线程的通道

第六步:循环num_thread, 建立args参数,使用threading.Thread(target=_precess_image_files_batch, args) 构建单线程,使用t.start()启动单线程,threads.append(t), 然后再将coord.join(threads)构建出了多线程

函数target = _precess_image_files_batch 说明:主要是用于构建Tfrecord数据集

第一步:将train_shards / num_threads相除,获得每个线程所需要建立的shards的个数

第二步:使用np.linspace(range[thread_index][0], range[thread_index][1],num_shards_per_batch + 1) # 获得每一个shards的数据索引

第三步:使用ranges[thread_index][1] - ranges[thread_index][0] 获得当前线程所执行的样本数

第四步:循环num_shard_per_batch,即每个线程所需要建立的shards个数

第五步:使用shard = thread_index * num_per_batch + s,获得当前的shards的索引

第六步:使用name,shard, trian_shard建立当前的路径

第七步:使用os.path.join() 将文件路径与当前路径进行拼接,获得保存路径

第八步:使用writer = tf.python_io.TFRecordWriter(output_path) 构造一个TFR写入的writer函数

第九步:循环每一个shards的数据索引值

第十步:使用_image_process获得图片的image_buff, 如果是png格式使用coder转换为jpg格式

第十一步:使用tf.train.Example(features=tf.train.Features(feature={

}))  # 将参数进行打包,返回example

第十二步:writer.write(example.SerializeToString()) 将数据写入到writer中

第十三步:如果执行1000次,打印当前时间,第几个线程,第几张图片, 该线程的图片数,使用sys.stdout.flush() 刷新

第十四步:一个shards结束后,writer.close() ,打印,并进行刷新

第十五步:整个循环结束后,打印,并刷新

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function from datetime import datetime
import os
import random
import sys import threading
import numpy as np
import tensorflow as tf tf.app.flags.DEFINE_string('train_directory', './flower_photos/',
'Training data directory')
tf.app.flags.DEFINE_string('validation_directory', './flower_photos',
'Validation data directory') tf.app.flags.DEFINE_string('output_directory', './data/',
'Output data directory') tf.app.flags.DEFINE_integer('train_shards', 2, 'Number of shards in training TFRecord files.') tf.app.flags.DEFINE_integer('validation_shards', 0, 'Number of shards in validation TFRecord files.') tf.app.flags.DEFINE_integer('num_threads', 2, 'Number of thread to preprocess the images') tf.app.flags.DEFINE_string('labels_file', './flower_label.txt', 'labels file') FLAGS = tf.app.flags.FLAGS def _int64_feature(value): if not isinstance(value, list):
value = [value]
# 将数据转换为int的列表类型
return tf.train.Feature(int64_list=tf.train.Int64List(value=value)) def _bytes_feature(value):
# 将数据转换为bytes的列表类型
return tf.train.Feature(bytes_list=tf.train.BytesList(value=[value])) def _convert_to_example(filename, image_buff, label, text, height, width): colorspace= 'RGB'
channels = 3
image_format = 'JPEG'
# 使用tf.train.Example和tf.train.Features构造打包数据
example = tf.train.Example(features=tf.train.Features(feature={
'image/height': _int64_feature(height),
'image/width': _int64_feature(width),
'image/colorspace': _bytes_feature(tf.compat.as_bytes(colorspace)),
'image/channels': _int64_feature(channels),
'image/class/label': _int64_feature(label),
'image/class/text': _bytes_feature(tf.compat.as_bytes(text)),
'image/format': _bytes_feature(tf.compat.as_bytes(image_format)),
'image/filename': _bytes_feature(tf.compat.as_bytes(os.path.basename(filename))),
'image/encoded': _bytes_feature(tf.compat.as_bytes(image_buff))
}))
return example def is_png(filename): return '.png' in filename def _process_image(filename, coder): # 打开文件夹,使用bytes数据类型
with tf.gfile.FastGFile(filename, 'rb') as f:
# 进行数据的读取
image_data = f.read()
# 如果数据是png的格式的话就转换为jpeg类型
if is_png(filename):
image_data = coder.png_to_jpeg(image_data)
# 将iamge_data进行解码
image = coder.decode_jpeg(image_data)
# 判断图片的维度是否是3
assert len(image.shape) == 3
# 图片的高度
height = image.shape[0]
# 图片的宽度
width = image.shape[1] return image_data, height, width def _process_image_files_batch(coder, thread_index, ranges, name, filenames, texts, labels, train_shards): # 获得线程数
num_threads = len(ranges)
# 保证线程和train_shards可以整除
assert not train_shards % num_threads
# 每个线程所需要执行的shards数
num_shards_per_batch = int(train_shards / num_threads)
# 根据每个线程的shars数,获得每个线程切分后的数据索引值
shard_ranges = np.linspace(ranges[thread_index][0],
ranges[thread_index][1], num_shards_per_batch + 1)
# 获得线程的样本数目
num_files_in_thread = ranges[thread_index][1] - ranges[thread_index][0]
# 用于图片的统计
counter = 0
# 循环线程
for s in range(num_shards_per_batch):
# 获得当前是第几个shards
shard = thread_index * num_shards_per_batch + s
# 构造TFR的路径
output_filename = '%s-%.5d-of-%.5d.tfrecord'%(name, shard, train_shards)
# 拼接获得最终的路径
output_file = os.path.join(FLAGS.output_directory, output_filename)
# 输入路径,构造TFR的读入器
writer = tf.python_io.TFRecordWriter(output_file)
#
shard_counter = 0
# 获得数据索引值的列表
file_in_shard = np.arange(shard_ranges[s], shard_ranges[s+1]).astype('int')
# 循环列表
for i in file_in_shard:
# 获得文件名
filename = filenames[i]
# 获得标签值
label = labels[i]
# 获得标签名
text = texts[i]
# 使用tf.gfile.FastGFile(filename, 'rb'): 打开文件
image_buff, height, width = _process_image(filename, coder)
# 将各个参数进行打包
example = _convert_to_example(filename, image_buff, label, text,
height, width)
# 将一张图片打包好的参数写入到writer里面
writer.write(example.SerializeToString())
shard_counter += 1
counter += 1
# 如果读取了1000张图片,打印并进行刷新操作
if not counter % 1000:
print('%s [thread %d]:Processed %d of %d images in thread batch.'%(
datetime.now(), thread_index, counter, num_files_in_thread
))
sys.stdout.flush()
# 循环了一个shards就关闭writer,打印和刷新操作
writer.close()
print('%s [thread %d]:Processed %d of %d images in thread batch.' % (
datetime.now(), thread_index, counter, num_files_in_thread
))
sys.stdout.flush()
# 循环结束,打印和刷新操作
print('%s [thread %d]:Processed %d of %d images in thread batch.' % (
datetime.now(), thread_index, counter, num_files_in_thread
))
sys.stdout.flush() class ImageCoder(object): def __init__(self):
# 构造sess函数
self._sess = tf.Session()
# 初始化png的输入数据
self.png_img = tf.placeholder(dtype=tf.string)
# 将png进行解码操作,使用tf.image.decode_png
image = tf.image.decode_png(self.png_img, channels=3)
# 对解码的图片,使用tf.image.encode_jpeg进行加码操作,format表示rgb, quality表示图片的质量
self._png_to_jpeg = tf.image.encode_jpeg(image, format='rgb', quality=100)
# 初始化输入jpeg_image的图片
self.jpeg_image = tf.placeholder(dtype=tf.string)
# 使用tf.image.decode_jpeg对图片进行解码操作
self._decode_jpeg = tf.image.decode_jpeg(self.jpeg_image, channels=3) def png_to_jpeg(self, image_data):
# 输入数据,获得实际的png_to_jpeg的转换
return self._sess.run(self._png_to_jpeg, feed_dict={self.png_img:image_data}) def decode_jpeg(self, image_data):
# 输入数据,进行实际的decode_jpeg的解码操作
image = self._sess.run(self._decode_jpeg, feed_dict={self.jpeg_image:image_data}) return image def _process_image_files(name, filenames, labels, texts, train_shards):
# 第一步:确认维度是否相等
assert len(filenames) == len(texts)
assert len(filenames) == len(labels) # 第二步:使用np.linspace()将len(filenames)根据train_shards的个数进行切片,获得每一份的索引值
ranges = []
split_index = np.linspace(0, len(filenames), train_shards+1)
# 第三步:根据索引值,构造range列表,即每一个列表,对于前后的索引值
for i in range(len(split_index) - 1):
ranges.append([split_index[i], split_index[i+1]]) # 刷新操作
print('Launching %d threads for spacings: %s'%(FLAGS.num_threads, ranges))
sys.stdout.flush()
# 第四步:实例化ImageCoder() 进行png_to_jpeg,或者对jpeg进行解码操作
coder = ImageCoder() # 第五步:使用tf.train.Coordinator获得线程的通道
coord = tf.train.Coordinator()
# 构造线程的列表
threads = []
# 第六步:循环线程的个数,构造多线程
for thread_index in range(len(ranges)):
# 构造线程参数,coder表示解码器,thread_index当前是第几个线程,ranges表示线程的范围,name表示名字,filenames表示文件的图片名
args = (coder, thread_index, ranges, name, filenames, texts, labels, train_shards)
# 构建线程
t = threading.Thread(target=_process_image_files_batch, args=args)
# 开始线程
t.start()
# 线程添加到线程列表中
threads.append(t)
# 将线程添加到通道中
coord.join(threads) def _find_image_files(data_path, labels_file): # 使用tf.gfile.FastGFile读取标签文件,获得标签的列表
upload_labels = [l.strip() for l in tf.gfile.FastGFile(labels_file).readlines()] # 第一种类别的标签值
label_index = 1
# 文件图片的名字列表
filenames = []
# 标签列表
labels = []
# 图片标签名列表
texts = []
# 循环标签文本
for text in upload_labels:
# 构造相对路径
jpeg_path_join = '%s/%s/*' % (data_path, text)
try:
# 使用tf.gfile.Glob遍历相对路径下所有的图片,获得图片的路径
matchfile = tf.gfile.Glob(jpeg_path_join)
except:
print(jpeg_path_join)
continue # 将获得的路径列表添加到filenames中
filenames.extend(matchfile)
# 产生[1] * len(filenams)的标签,并添加到标签列表中
labels.extend([label_index] * len(matchfile))
# 产生[test] * len(filenames)的标签名,并添加到标签名列表中
texts.extend([text] * len(matchfile))
# 标签值加1,作为下一个类比的标签值
label_index += 1
# 获得len(filenames)的索引值
shuffled_index = np.arange(len(filenames))
# 将索引值进行打乱
random.seed(1234)
random.shuffle(shuffled_index)
# 根据打乱的索引值重新构造filenames,labels,和texts
filenames = [filenames[i] for i in shuffled_index]
labels = [labels[i] for i in shuffled_index]
texts = [texts[i] for i in shuffled_index]
# 返回filenames,labels和texts
return filenames, labels, texts def _process_dataset(name, data_path, train_shards, labels_file): # 第一部分:找出文件名,构造标签列表以及文件名列表,并使用random.shuffle获得乱序的索引
filenames, labels, texts = _find_image_files(data_path, labels_file)
# 第二部分:将文件图片的名字,标签值,标签名,以及生产shards个数传入,用于生成tfrecord
_process_image_files(name, filenames, labels, texts, train_shards) def main(unused_argv):
# 确认train_shards是够能被线程整除
assert not FLAGS.train_shards % FLAGS.num_threads, ('在训练过程中线程的数目应该与文件的数目相对应') assert not FLAGS.validation_shards % FLAGS.num_threads, ('在验证集制作中线程的数目应该与文件的数目相对应')
# 构建process_dataset执行函数,传入的参数有name, 训练数据文件路径,训练集的num,以及标签的文件名
_process_dataset('train', FLAGS.train_directory,
FLAGS.train_shards,
FLAGS.labels_file) if __name__ == '__main__':
tf.app.run()

深度学习原理与框架-Tfrecord数据集的制作 1.tf.train.Examples(数据转换为二进制) 3.tf.image.encode_jpeg(解码图片加码成jpeg) 4.tf.train.Coordinator(构建多线程通道) 5.threading.Thread(建立单线程) 6.tf.python_io.TFR(TFR读入器)的更多相关文章

  1. 深度学习原理与框架-Tfrecord数据集的读取与训练(代码) 1.tf.train.batch(获取batch图片) 2.tf.image.resize_image_with_crop_or_pad(图片压缩) 3.tf.train.per_image_stand..(图片标准化) 4.tf.train.string_input_producer(字符串入队列) 5.tf.TFRecord(读

    1.tf.train.batch(image, batch_size=batch_size, num_threads=1) # 获取一个batch的数据 参数说明:image表示输入图片,batch_ ...

  2. 深度学习原理与框架-神经网络-cifar10分类(代码) 1.np.concatenate(进行数据串接) 2.np.hstack(将数据横着排列) 3.hasattr(判断.py文件的函数是否存在) 4.reshape(维度重构) 5.tanspose(维度位置变化) 6.pickle.load(f文件读入) 7.np.argmax(获得最大值索引) 8.np.maximum(阈值比较)

    横1. np.concatenate(list, axis=0) 将数据进行串接,这里主要是可以将列表进行x轴获得y轴的串接 参数说明:list表示需要串接的列表,axis=0,表示从上到下进行串接 ...

  3. 深度学习原理与框架-Tensorflow基本操作-变量常用操作 1.tf.random_normal(生成正态分布随机数) 2.tf.random_shuffle(进行洗牌操作) 3. tf.assign(赋值操作) 4.tf.convert_to_tensor(转换为tensor类型) 5.tf.add(相加操作) tf.divide(相乘操作) 6.tf.placeholder(输入数据占位

    1. 使用tf.random_normal([2, 3], mean=-1, stddev=4) 创建一个正态分布的随机数 参数说明:[2, 3]表示随机数的维度,mean表示平均值,stddev表示 ...

  4. 深度学习原理与框架-图像补全(原理与代码) 1.tf.nn.moments(求平均值和标准差) 2.tf.control_dependencies(先执行内部操作) 3.tf.cond(判别执行前或后函数) 4.tf.nn.atrous_conv2d 5.tf.nn.conv2d_transpose(反卷积) 7.tf.train.get_checkpoint_state(判断sess是否存在

    1. tf.nn.moments(x, axes=[0, 1, 2])  # 对前三个维度求平均值和标准差,结果为最后一个维度,即对每个feature_map求平均值和标准差 参数说明:x为输入的fe ...

  5. 深度学习原理与框架-Alexnet(迁移学习代码) 1.sys.argv[1:](控制台输入的参数获取第二个参数开始) 2.tf.split(对数据进行切分操作) 3.tf.concat(对数据进行合并操作) 4.tf.variable_scope(指定w的使用范围) 5.tf.get_variable(构造和获得参数) 6.np.load(加载.npy文件)

    1. sys.argv[1:]  # 在控制台进行参数的输入时,只使用第二个参数以后的数据 参数说明:控制台的输入:python test.py what, 使用sys.argv[1:],那么将获得w ...

  6. 深度学习原理与框架-递归神经网络-RNN_exmaple(代码) 1.rnn.BasicLSTMCell(构造基本网络) 2.tf.nn.dynamic_rnn(执行rnn网络) 3.tf.expand_dim(增加输入数据的维度) 4.tf.tile(在某个维度上按照倍数进行平铺迭代) 5.tf.squeeze(去除维度上为1的维度)

    1. rnn.BasicLSTMCell(num_hidden) #  构造单层的lstm网络结构 参数说明:num_hidden表示隐藏层的个数 2.tf.nn.dynamic_rnn(cell, ...

  7. 深度学习原理与框架-递归神经网络-RNN网络基本框架(代码?) 1.rnn.LSTMCell(生成单层LSTM) 2.rnn.DropoutWrapper(对rnn进行dropout操作) 3.tf.contrib.rnn.MultiRNNCell(堆叠多层LSTM) 4.mlstm_cell.zero_state(state初始化) 5.mlstm_cell(进行LSTM求解)

    问题:LSTM的输出值output和state是否是一样的 1. rnn.LSTMCell(num_hidden, reuse=tf.get_variable_scope().reuse)  # 构建 ...

  8. 深度学习原理与框架-猫狗图像识别-卷积神经网络(代码) 1.cv2.resize(图片压缩) 2..get_shape()[1:4].num_elements(获得最后三维度之和) 3.saver.save(训练参数的保存) 4.tf.train.import_meta_graph(加载模型结构) 5.saver.restore(训练参数载入)

    1.cv2.resize(image, (image_size, image_size), 0, 0, cv2.INTER_LINEAR) 参数说明:image表示输入图片,image_size表示变 ...

  9. 深度学习原理与框架-Tensorflow卷积神经网络-cifar10图片分类(代码) 1.tf.nn.lrn(局部响应归一化操作) 2.random.sample(在列表中随机选值) 3.tf.one_hot(对标签进行one_hot编码)

    1.tf.nn.lrn(pool_h1, 4, bias=1.0, alpha=0.001/9.0, beta=0.75) # 局部响应归一化,使用相同位置的前后的filter进行响应归一化操作 参数 ...

随机推荐

  1. L333 Should You Listen to Music While You Work?

    Should You Listen to Music While You Work? "Whistle while you work" is classic advice, str ...

  2. HTML5:定位

    定位 一.介绍: position设置块级元素相对于其父块的位置和相对于它自身应该在的位置,任何使用定位的元素都会成为块级元素. 1.属性值 属性值 描述 absolute 生成绝对定位的元素,相对于 ...

  3. java面向对象编程(六)--四大特征之继承

    本文将介绍继承.方法重载和方法覆盖.其中方法重载和方法覆盖是在讲多态时必须要清楚的一个知识点. 一.继承 1.继承的概念 继承可以解决代码复用,让我们的编程更加靠近人类思维.当多个类存在相同的属性(变 ...

  4. Django runserver UnicodeDecodeError

    编码问题可以说是我遇到过的python 2.7最大的败笔 今天写django时,很简单的一个项目却报UnicodeDecodeError,而我的代码中一个中文字符都没有出现. 如下: 网上找到的所谓解 ...

  5. RPi 3B Aduio 3.5mm output

    /********************************************************************** * RPi 3B Aduio 3.5mm output ...

  6. 初见 fultter for MAC

    第一步:下载flutter https://flutter.io/docs/development/tools/sdk/archive?tab=macos#macos 第二步:(development ...

  7. 2018.4.26 lvm

    lvm(Logical Volume Manager)逻辑卷管理,是Linux环境下对磁盘分区进行管理的一种机制. 基本概念: 1. 物理卷-----PV(Physical Volume)物理卷在逻辑 ...

  8. Go Example--panic

    package main import "os" func main() { //panic会中断程序执行,在此处一直往上抛panic,需要上游的recover来捕获 panic( ...

  9. LeetCode - X of a Kind in a Deck of Cards

    In a deck of cards, each card has an integer written on it. Return true if and only if you can choos ...

  10. Docker之数据卷Volume(七)

    一.简介   Docker数据卷(volume)机制.volume是存在于一个或多个容器中的特定文件或文件夹,这个目录以独立于联合文件系统的形式在宿主机中存在,并为数据的共享与持久化提供便利. 1)v ...