基于神经网络的人脸识别tensorflow(数据的存储与加载)
正文:
1.数据存储与加载方式
这里将数据的存储与加载方式分为两种,一种是在tensorflow框架中,提供的统一格式——TFRecord。另外一种是直接利用数组的形式进行存储与加载。
- TFRecord
- 数组
2.数据的存储
1)TFRecord
TFRecord是一种文件的存储格式,通过将数据按照一定的格式生成 .tfrecords文件进行储存。 关键步骤如下。
读取图片(三维)/标签→ 存储为四维数组/二维数组 → 将数组存为.tfrecords文件
以下实现利用TFRecord存储十张图片以及标签。
import tensorflow as tf
import os
import cv2
import numpy as np
def get_int64(value):
"""获取整型属性"""
return tf.train.Feature(int64_list=tf.train.Int64List(value=[value]))
def get_bytes(value):
"""获取字符串属性"""
return tf.train.Feature(bytes_list=tf.train.BytesList(value=[value]))
#--------第一/二步————读取图片/标签并存储为数组
#从txt文件中读取十张图片和标签
image_txt = 'train_images.txt'
label_txt = 'train_labels.txt'
#神经网络输入维度
input_h = 224
input_w = 224
input_c = 3
#获取10张照片
number = 10
#初始化数组
images = np.zeros((number,input_h,input_w,input_c),dtype='uint8')
labels = np.zeros((number,2),dtype='uint8') #每个标签维度为1*2
#把图片存入数组
image_root_path = r"C:\Users\user\Desktop\wider_data"
with open(image_txt) as obj1:
i = 0
for l1 in obj1.readlines()[:10]:
image_name = l1.strip('\n')
all_path = os.path.join(image_root_path, image_name) #图片根目录
iamge_data = cv2.imread(all_path, 1)
image = cv2.resize(iamge_data, (input_h, input_w))
images[i] = image
i += 1
#把标签存入数组
with open(label_txt) as obj2:
i = 0
for l2 in obj2.readlines()[:10]:
label_str = l2.strip('\n') #'[0, 1]' (第一位数在第二位,第二位数在第五位)
label_array = (float(label_str[1]), float(label_str[4]))
labels[i] = label_array
i += 1
#--------第三步————存储为.tfrecords格式
#输出文件名称
output_path = 'data.tfrecords'
#写入器
writer = tf.io.TFRecordWriter(output_path)
for i in range(number):
image_str = images[i].tostring() #写入形式为字符串 将图片转为字符串
label = np.argmax(labels[i]) #取最大值下标 即正确答案
#以字典的结构生成样例
example = tf.train.Example(features=tf.train.Features(feature={
'label': get_int64(label),
'image': get_bytes(image_str)}))
#写入样例
writer.write(example.SerializeToString())
writer.close() #关闭写入器
2)数组
数组的存储方法很简单,对于图片存储而言,首先初始化一个数组,再把所有的图片数据存到大数组中。关键步骤如下:
创建一个大数组(四维,第一维是图片数,其他三维是图片维度) → 读取图片(三维数组) → 把小数组储存到大数组中
可以看出 ——TFRecord的存储方式比直接利用数组的存储方法只是多了一个存储为.tfrcords文件的步骤。具体来说,.tfrecords这个文件是tensorflow提供的一种文件格式,可以起到统一的作用,方便数据的存储和加载。以下实现直接利用数组存储。
import cv2
import numpy as np
import os
def get_image_arrary(image_h, image_w, image_c):
"""输入参数:图片的三个维度(神经网络输入维度)"""
#初始化列表
images = []
labels = []
root_path = r"C:\Users\user\Desktop\wider_data" #图片根目录
images_txt = 'train_images.txt' #图片地址文件
labels_txt = 'train_labels.txt' #对应的标签文件
with open(images_txt) as obj:
for l in obj.readlines():
images.append(l.strip('\n'))
with open(labels_txt) as obj2:
for l in obj2.readlines():
labels.append(l.strip('\n'))
sum_number = len(images)
#创建数组
shape=(sum_number, image_h, image_w, image_c)
images_array = np.zeros(shape,dtype='uint8')
shape2 = (sum_number, 2)
labels_array = np.zeros(shape2)
for i in range(sum_number):
#图片
path = images[i]
all_path = os.path.join(root_path, path)
image = cv2.imread(all_path, 1)
image = cv2.resize(image, (image_h, image_w))
images_array[i] = image
#标签
label_str = labels[i] #字符串列表
label_array = np.zeros((1,2), dtype=int)
label_array = (float(label_str[1]), float(label_str[4]))
labels_array[i] = label_array
return images_array, labels_array
3.数据的加载
1)TFRecord
TFRecord的文件读取要求与写入的格式一致。另外,由于图片在存储时以字符串的格式进行存储,所以读取出的图片也是字符串格式。在使用或者显示一张图片之前,需要将图片转为数组的形式。同时,读取出的图片维度为1xn,所以还需要将图片重塑为3维。下面是.tfrecords文件的读取。
#tfrecords的加载
import tensorflow as tf
import cv2
#创建读取器
reader = tf.TFRecordReader()
#创建文件队列(管理文件,用于文件读取)
filename_queue = tf.train.string_input_producer(
['data.tfrecords'])
#读取一个样例
_,serialized_example = reader.read(filename_queue)
#解析样例 格式需要与存储时一致
features = tf.parse_single_example(
serialized_example,
features = {
'label': tf.FixedLenFeature([], tf.int64),
'image': tf.FixedLenFeature([], tf.string)
})
#将图像字符串转为数组
images = tf.decode_raw(features['image'], tf.uint8)
labels = features['label']
sess = tf.compat.v1.Session() #创建会话
coord = tf.train.Coordinator() #生成 Coordinator 管理多线程
threads = tf.train.start_queue_runners(sess=sess,coord=coord)
#读取结果展示
for i in range(10):
image = sess.run(images)
print(image.shape) #150528 = 224 x 224 x 3(存储时的维度)
image = image.reshape(224,224,3)
cv2.imshow(str(i), image) #展示
label = sess.run(labels)
print(image, label)
2)数组
在存储数组时,只是将多个小的数组存储为一个大的数组。所以读取时只需要从大的数组中进行遍历。采用数组方法的缺点是,由于没有存储为类似.tfrecords的文件,所以数组的储存和读取其实是在同时进行的(也就是要读取必须先进行储存)。这样就会导致速度变慢,测试了将几万张图片进行储存为数组的情况下,大概需要花几分钟的时间。下面是数组的加载,采用随机加载一部分的方法进行加载,这样符合训练神经网络时的数据输入方法。
import cv2
import numpy as np
def get_batch(btch_size, images_array, labels_array, image_h, image_w, image_c):
"""得到一部分图片和标签"""
#输入参数 一部分(batch)的大小,一部分的图片,一部分的标签,图片维度(h,w,c)
lim = len(images_array)
shape = (btch_size,image_h, image_w, image_c)
shpae1 = (btch_size,2)
batch_img_array = np.zeros(shape)
batch_lab_array = np.zeros(shpae1)
randoms = [] #避免重复
for i in range(btch_size):
flag = True
while flag:
random = np.random.randint(lim)
if random not in randoms:
flag = False
batch_img_array[i] = images_array[random]
batch_lab_array[i] = labels_array[random]
randoms.append(random)
batch_lab_array = batch_lab_array.astype(np.float32) #类型转换
return batch_img_array, batch_lab_array
结语:
如果对你有帮助,就给我一个赞吧,如何有问题,可以在评论区进行讨论。
上一篇:[基于tensorflow的人脸检测] 基于神经网络的人脸检测5——神经网络的搭建
本文地址:https://blog.csdn.net/qq_43260356/article/details/107080566
上一篇: 老生常谈js-react组件生命周期
下一篇: PS制作漂亮清晰的天空云彩文字的效果