TFRecords数据集读取与存储借鉴于 http://blog.csdn.net/wiinter_fdd/article/details/72835939
运行平台: Windows
Python版本: Python3.x
IDE: Spyder
笔者近几日在研究如何用自制的数据集来进行深度学习的训练,开始尝试把图片以np的形式存储成txt格式,并手动采用one-hot标签,但是数据集标签标注复杂,不适用于数据分类多的数据集,并且数据存储与读取缓慢。由于以上原因,这时我们就采用了TFRecords数据集存储与读取,但是TFRecords数据集的标签为数字(如:1,2,3,8等),这时候我们在获取TFRecords数据集的标签进行one-hot编码,这样就可以进行深度学习的训练了。
笔者的数据集基于实验室的荧光小球与微片,一共有8类,在TFRecords数据集下标签为0—7.
####TFRecords数据集存储
cwd = "E://玻片小球//"
classes = {'clips', 'balls'} #预先自己定义的类别
cwd = os.getcwd()#自动获取当前目录路径
cwd = "E:/玻片小球/"#手动输入路径
classes = {'clips_red', 'clips_yellows','clips_Microscopic','balls_green','balls_red','balls_yellow','balls_Microscopic', 'clips_green'} #类别设定
#定义writer用于写入数据,tf.python_io.TFRecordWriter 写入到TFRecords文件中
writer = tf.python_io.TFRecordWriter("train1.tfrecords")#定义生成的文件名为“train1.tfrecords”
for index, name in enumerate(classes):
class_path = cwd + name + "/"
for img_name in os.listdir(class_path):
img_path = class_path + img_name #每一个图片的地址
img = Image.open(img_path)
img = img.resize((height, weight)) #将数据集中的所有图片保存成100×100大小
img_raw = img.tobytes() #将图片转化为原生bytes,#tf.train.Example 协议内存块包含了Features字段,通过feature将图片的二进制数据和label进行统一封装
example = tf.train.Example(features=tf.train.Features(feature={
"label": tf.train.Feature(int64_list=tf.train.Int64List(value=[index])),
'img_raw': tf.train.Feature(bytes_list=tf.train.BytesList(value=[img_raw]))
})) #example对象对label和image进行封装
writer.write(example.SerializeToString()) #序列化为字符串,example协议内存块转化为字符串
writer.close()
#######数据的读取
def read_and_decode(filename):#读入tfrecords文件
filename_queue=tf.train.string_input_producer([filename])
reader=tf.TFRecordReader()
_,serialized_example=reader.read(filename_queue)#生成一个queue队列
#将image数据和label数据读取出来放入features
features=tf.parse_single_example(serialized_example,features={
'label':tf.FixedLenFeature([],tf.int64),
'img_raw':tf.FixedLenFeature([],tf.string)})
img=tf.decode_raw(features['img_raw'],tf.uint8)
img=tf.reshape(img,[height, weight,3])#将图像reshape成128*128
img=tf.cast(img,tf.float32)*(1./255)-0.5#将image归一化
label=tf.cast(features['label'],tf.int32)#将label转化成int32
return(img,label)
这里笔者有话要说,大家可能在数据读取的时候遇到如下的问题:
tensorflow.python.framework.errors.InvalidArgumentError: Input to reshape is a tensor with xxx values, but the requested shape requires a multiple of xxx values
大家可以检查一下自己的数据集是否有问题,如:数据集里有黑白图片,有gif格式图片,都会出现如下问题,笔者因为这个原因卡了一晚上。
CNN网络的搭建主要借鉴了这篇博客https://blog.csdn.net/qq_38375282/article/details/81542795
但是由于这篇博客只有猫狗两种分类,没有one-hot编码,所以标签只有0和1,笔者认为有一定问题,欢迎大家来指正。
batch_size=432
#定义初始化权重和偏置函数
def weight_variable(shape):
return(tf.Variable(tf.random_normal(shape,stddev=0.01)))
def bias_variable(shape):
return(tf.Variable(tf.constant(0.1,shape=shape)))
#定义输入数据和dropout占位符
X=tf.placeholder(tf.float32,[batch_size,height, weight,3])
y_=tf.placeholder(tf.float32,[batch_size,8])
keep_pro=tf.placeholder(tf.float32)
#搭建网络
def model(X,keep_pro):
w1=weight_variable([5,5,3,32])
b1=bias_variable([32])
conv1=tf.nn.relu(tf.nn.conv2d(X,w1,strides=[1,1,1,1],padding='SAME')+b1)
pool1=tf.nn.max_pool(conv1,ksize=[1,4,4,1],strides=[1,4,4,1],padding='SAME')
w2=weight_variable([5,5,32,64])
b2=bias_variable([64])
conv2=tf.nn.relu(tf.nn.conv2d(pool1,w2,strides=[1,1,1,1],padding='SAME')+b2)
pool2=tf.nn.max_pool(conv2,ksize=[1,4,4,1],strides=[1,4,4,1],padding='SAME')
tensor=tf.reshape(pool2,[batch_size,-1])
dim=tensor.get_shape()[1].value
w3=weight_variable([dim,1024])
b3=bias_variable([1024])
fc1=tf.nn.relu(tf.matmul(tensor,w3)+b3)
h_fc1=tf.nn.dropout(fc1,keep_pro)
w4=weight_variable([1024,8])
b4=bias_variable([8])
y_conv=tf.nn.softmax(tf.matmul(h_fc1,w4)+b4)
return(y_conv)
#定义网络,并设置损失函数和训练器
y_conv=model(X,keep_pro)
cost=tf.reduce_mean(-tf.reduce_sum(y_*tf.log(y_conv),reduction_indices=[1]))
train_step=tf.train.AdamOptimizer(0.001).minimize(cost)
#计算准确率
correct_prediction=tf.equal(tf.argmax(y_conv,1),tf.argmax(y_,1))
accuracy=tf.reduce_mean(tf.cast(correct_prediction,tf.float32))
a1=tf.argmax(y_,1)
#读取tfrecords数据
image,label=read_and_decode("train1.tfrecords")
#定义会话,并开始训练
with tf.Session() as sess:
tf.global_variables_initializer().run()
#定义多线程
coord=tf.train.Coordinator()
threads=tf.train.start_queue_runners(coord=coord)
#定义训练图像和标签
example=np.zeros((batch_size,height, weight,3))
l=np.zeros((batch_size,1))
try:
#将数据存入example和l,并将转化成one_hot形式
for epoch in range(batch_size):
example[epoch],l[epoch]=sess.run([image,label])
print(l)
enc=OneHotEncoder()
l=enc.fit_transform(l)
l=l.toarray()
print(l)
for i in range(100):
#开始训练
sess.run(train_step,feed_dict={X:example,y_:l,keep_pro:0.5})
if i%10==0:
print('train step','%04d ' %(i+1),'Accuracy=',sess.run(accuracy,feed_dict={X:example,y_:l,keep_pro:0.5}))
except tf.errors.OutOfRangeError:
print('done!')
finally:
coord.request_stop()
coord.join(threads)
import os
import tensorflow as tf
from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
from sklearn.preprocessing import OneHotEncoder
height=100
weight=100
####################################################################################################数据集存储
cwd = "E://玻片小球//"
classes = {'clips', 'balls'} #预先自己定义的类别
cwd = os.getcwd()#自动获取当前目录路径
cwd = "E:/玻片小球/"#手动输入路径
classes = {'clips_red', 'clips_yellows','clips_Microscopic','balls_green','balls_red','balls_yellow','balls_Microscopic', 'clips_green'} #类别设定
#定义writer用于写入数据,tf.python_io.TFRecordWriter 写入到TFRecords文件中
writer = tf.python_io.TFRecordWriter("train1.tfrecords")#定义生成的文件名为“train1.tfrecords”
for index, name in enumerate(classes):
class_path = cwd + name + "/"
for img_name in os.listdir(class_path):
img_path = class_path + img_name #每一个图片的地址
img = Image.open(img_path)
img = img.resize((height, weight)) #将图片保存成100×100大小
img_raw = img.tobytes() #将图片转化为原生bytes,#tf.train.Example 协议内存块包含了Features字段,通过feature将图片的二进制数据和label进行统一封装
example = tf.train.Example(features=tf.train.Features(feature={
"label": tf.train.Feature(int64_list=tf.train.Int64List(value=[index])),
'img_raw': tf.train.Feature(bytes_list=tf.train.BytesList(value=[img_raw]))
})) #example对象对label和image进行封装
writer.write(example.SerializeToString()) #序列化为字符串,example协议内存块转化为字符串
writer.close()
##########################################################################################数据集读取
def read_and_decode(filename):#读入tfrecords文件
filename_queue=tf.train.string_input_producer([filename])
reader=tf.TFRecordReader()
_,serialized_example=reader.read(filename_queue)#生成一个queue队列
#将image数据和label数据读取出来放入features
features=tf.parse_single_example(serialized_example,features={
'label':tf.FixedLenFeature([],tf.int64),
'img_raw':tf.FixedLenFeature([],tf.string)})
img=tf.decode_raw(features['img_raw'],tf.uint8)
img=tf.reshape(img,[height, weight,3])#将图像reshape成100*100*3
img=tf.cast(img,tf.float32)*(1./255)-0.5#将image归一化
label=tf.cast(features['label'],tf.int32)#将label转化成int32
return(img,label)
#############################################网络搭建
batch_size=432
#定义初始化权重和偏置函数
def weight_variable(shape):
return(tf.Variable(tf.random_normal(shape,stddev=0.01)))
def bias_variable(shape):
return(tf.Variable(tf.constant(0.1,shape=shape)))
#定义输入数据和dropout占位符
X=tf.placeholder(tf.float32,[batch_size,height, weight,3])
y_=tf.placeholder(tf.float32,[batch_size,8])
keep_pro=tf.placeholder(tf.float32)
#搭建网络
def model(X,keep_pro):
w1=weight_variable([5,5,3,32])
b1=bias_variable([32])
conv1=tf.nn.relu(tf.nn.conv2d(X,w1,strides=[1,1,1,1],padding='SAME')+b1)
pool1=tf.nn.max_pool(conv1,ksize=[1,4,4,1],strides=[1,4,4,1],padding='SAME')
w2=weight_variable([5,5,32,64])
b2=bias_variable([64])
conv2=tf.nn.relu(tf.nn.conv2d(pool1,w2,strides=[1,1,1,1],padding='SAME')+b2)
pool2=tf.nn.max_pool(conv2,ksize=[1,4,4,1],strides=[1,4,4,1],padding='SAME')
tensor=tf.reshape(pool2,[batch_size,-1])
dim=tensor.get_shape()[1].value
w3=weight_variable([dim,1024])
b3=bias_variable([1024])
fc1=tf.nn.relu(tf.matmul(tensor,w3)+b3)
h_fc1=tf.nn.dropout(fc1,keep_pro)
w4=weight_variable([1024,8])
b4=bias_variable([8])
y_conv=tf.nn.softmax(tf.matmul(h_fc1,w4)+b4)
return(y_conv)
#定义网络,并设置损失函数和训练器
y_conv=model(X,keep_pro)
cost=tf.reduce_mean(-tf.reduce_sum(y_*tf.log(y_conv),reduction_indices=[1]))
train_step=tf.train.AdamOptimizer(0.001).minimize(cost)
#计算准确率
correct_prediction=tf.equal(tf.argmax(y_conv,1),tf.argmax(y_,1))
accuracy=tf.reduce_mean(tf.cast(correct_prediction,tf.float32))
a1=tf.argmax(y_,1)
#读取tfrecords数据
image,label=read_and_decode("train1.tfrecords")
#定义会话,并开始训练
with tf.Session() as sess:
tf.global_variables_initializer().run()
#定义多线程
coord=tf.train.Coordinator()
threads=tf.train.start_queue_runners(coord=coord)
#定义训练图像和标签
example=np.zeros((batch_size,height, weight,3))
l=np.zeros((batch_size,1))
try:
#将数据存入example和l,并将转化成one_hot形式
for epoch in range(batch_size):
example[epoch],l[epoch]=sess.run([image,label])
print(l)
enc=OneHotEncoder()
l=enc.fit_transform(l)
l=l.toarray()
print(l)
for i in range(100):
#开始训练
sess.run(train_step,feed_dict={X:example,y_:l,keep_pro:0.5})
if i%10==0:
print('train step','%04d ' %(i+1),'Accuracy=',sess.run(accuracy,feed_dict={X:example,y_:l,keep_pro:0.5}))
except tf.errors.OutOfRangeError:
print('done!')
finally:
coord.request_stop()
coord.join(threads)