机器学习的核心就是对大数据集的分析,所有机器学习的入门就是对数据的预处理和如何把数据应用的训练的里面。以我的理解对于最高效的tensorflow数据训练方法,一个是利用GOOGLE提供的标准数据集dataset_utils,直接从网络上下载,这个方法是最简单的,但不是我今天讨论的内容。
今天介绍的是如何使用自己的数据集进行训练的方法。
首先tensorflow最高效的就是把准备的数据集生成tfrecord文件,然后再通过读取tfrecord文件列表的方式进行训练,这样比直接用CSV文件等方式更加的高效。因为读取tfrecord文件可以直接生成张量,不再需要特别的转换。
一下是一段简单的生成tfrecord文件的代码:
!usr/bin/env python3
# -*- coding:utf-8 -*-
import tensorflow as tf
import numpy as np
import random
rand_num=5000
same=0
diff=0
same=0
# 这两个函数(_bytes_feature和_int64_feature)是将我们的原生数据进行转换用的,
# 尤其是图片要转换成字符串再进行存储。这两个函数的定义来自官方的示例。
# 这三个函数基本包含了需要的类型,其中_bytes_feature基本万能了
def _bytes_feature(value):
return tf.train.Feature(bytes_list=tf.train.BytesList(value=[value]))
def _int64_feature(value):
return tf.train.Feature(int64_list=tf.train.Int64List(value=[value]))
def _float_feature(value):
return tf.train.Feature(float_list=tf.train.FloatList(value=[value]))
data_path ='/home/face/TfWebFace/'
tfrecords_filename = data_path + 'train.tfrecords'
tfrecords_filename = '/home/face/TfWebFace/train.tfrecords'
# 创建一个TFRecordWriter实例,相当于待会写数据的入口
writer = tf.python_io.TFRecordWriter(tfrecords_filename)
# img_height = 32
# img_width = 32
# sio.loadmat(test.mat)
#train_list 是需要训练的列表包含 图像文件PATH,和分类LABLE
#用tf.gfile.FastGFile 可以减少文件大小,但在之后需要解压
for line in train_list:
[file,lab]=line
image_jpg = tf.gfile.FastGFile(file,'rb').read()
example = tf.train.Example(features=tf.train.Features(
feature={
'image': _bytes_feature(image_jpg),
"label": _int64_feature(int(lab))
}
))
# print (lab1)
writer.write(example.SerializeToString())
writer.close()
print (len(train_list))
文件生成以后就是用于训练了,用于训练和标准的tensorflow流程一样,先定义流图,然后通过Session去执行,这里还可以打个包,用tf.train.batch一次执行多条来提高训练效率,当然花哨一些可以用随机的tf.train.shuffle_batch。
我们先定义流
batch_size = 50
height, width = 128, 128
tfrecords_filename = '/home/face/TfWebFace/train.tfrecords'
filename_queue = tf.train.string_input_producer([tfrecords_filename])
reader = tf.TFRecordReader()
_,serialized_example = reader.read(filename_queue)
features = tf.parse_single_example(serialized_example,
features={
"image": tf.FixedLenFeature([], tf.string),
"label": tf.FixedLenFeature([], tf.int64)
}
)
label=features["label"]
image = tf.image.decode_jpeg(features['image'], channels=3)
image = tf.cast(image, tf.float32)
###这里要指定张量的维度,不然之后会报错
image = tf.reshape(image, [height, width, 3])
images, labels = tf.train.batch(
[image, label],
batch_size=batch_size,
num_threads=1,
capacity=100)
最后我们来跑一把,下面就是执行Session,我见过更加高大上的slim.learning.train,但参数过多,还是来点容易理解的
import sys
with tf.Session() as sess:
###初始化全局和局部变量
tf.global_variables_initializer().run()
tf.local_variables_initializer().run()
####生成训练列
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(sess=sess, coord=coord)
for i in range(100000):
img,lab = sess.run([images, labels])
if i%100==0:
sys.stdout.write('.')
sys.stdout.flush()
if i%10000==0:
print (len(img),lab)
coord.request_stop()
coord.join(threads)
下面介绍一下string、图像和list三种数据类型的打包和解压方式,基本涵盖了所有的类型。
(一)tfrecord文件打包
前面的例子已经说明了用到的三个函数:
# 这两个函数(_bytes_feature和_int64_feature)是将我们的原生数据进行转换用的,
# 尤其是图片要转换成字符串再进行存储。这两个函数的定义来自官方的示例。
# 这三个函数基本包含了需要的类型,其中_bytes_feature基本万能了
def _bytes_feature(value):
return tf.train.Feature(bytes_list=tf.train.BytesList(value=[value]))
def _int64_feature(value):
return tf.train.Feature(int64_list=tf.train.Int64List(value=[value]))
def _float_feature(value):
return tf.train.Feature(float_list=tf.train.FloatList(value=[value]))
(1)STRING的类型打包比较简单,只要加入'name' : _bytes_feature(name.encode()),把字符串转换为 b''
(2)_bytes_feature() 比较万能,可以把各种类型的数据打包成bytes的格式进行保持,其中图片可以用
Color_image_jpg = tf.gfile.FastGFile(Color_image_path,'rb').read()
对于list 和array也要进行转换,首先要把list转换为np.array,让后用bytes(ImageList)打包,在解压的时候可以用tf.decode_raw(features['Lableimage'],tf.int64)解压,最后指定张量格式Labimage= tf.reshape(Labimage, [1710, 3384, 12])。
###打包程序片段
for H in range(1710):
ImageList.append([])
for W in range(3384):
ImageList[H].append([1,0,0,0,0,0,0,0,0,0,0,0])
ImageList=np.array(ImageList)
Lable_image_jpg=bytes(ImageList)
example = tf.train.Example(features=tf.train.Features(
feature={
'Colorimage': _bytes_feature(Color_image_jpg),
'Lableimage': _bytes_feature(Lable_image_jpg),
'Roadname' : _bytes_feature(Roadname.encode()),
'Picname' : _bytes_feature(Lable_image_path.encode())
}
))
####解压片段
features = tf.parse_single_example(serialized_example,
features={
'Colorimage': tf.FixedLenFeature([], tf.string),
'Lableimage': tf.FixedLenFeature([], tf.string),
'Roadname' : tf.FixedLenFeature([], tf.string),
'Picname' :tf.FixedLenFeature([], tf.string)
}
)
Labimage = tf.decode_raw(features['Lableimage'],tf.int64)
Labimage= tf.reshape(Labimage, [1710, 3384, 12])