掌握一个深度学习框架的用法,从训练一个模型的流程来看,需要掌握以下几个步骤:
1. 数据的处理,包括训练数据转成网络的输入,模型参数的存储与读取
2. 网络结构的定义,包括网络主体的搭建以及loss的定义
3. solver的定义,也就是如何对网络进行优化
4. 模型评估的定义,也就是对模型训练结果进行评测
这篇博文主要介绍第一部分,数据处理中的训练数据读取部分
tensorflow当中读取数据的方式一共有三种:
1. 供给数据(feeding):在定义graph的时候,可以用placeholder来表示其中的某些节点,在运行的时候,通过向这些节点填入数据来运行整个graph
2. 预加载数据:仅仅适用于可以完全加载到存储器中的小的数据集
3. 从文件中加载数据:在图运行的时候,通过一个pipeline从文件中读取数据,作为网络的输入
前面两种方法并不适用于平时的大数据集处理的情况,因此这里我只介绍第三种方法:从文件中加载数据,重点介绍通过tensorflow特有的tfrecords进行存储和读取的方法
1.tfrecords
tfrecords是一种二进制文件,我们可以实现把image文件夹里面的图片和label文件夹里面的标签读进来制作成tfrecords文件,之后就都使用tfrecords进行数据的读取,能够更好的利用内存,更方便复制和移动,类似caffe里面的hdf5,下面我们将详细介绍如果制作tfrecords文件,以及如何从tfrecords文件里面读取数据
2.tfrecords文件的制作
每一个训练样例在tfrecords里面叫一个example,tensorflow使用名为tf.train.Example的协议来存储训练样例,一个example就类似一个词典(dict),它的key名为feature,每一个feature对应的值是tensorflow预定义好的Feature message(必须要是ByteList,FloatList以及Int64List中的一种数据类型),这样的话一个训练样例就可以表示为很多键-值对的组合。
example通过SerializeToString()方法将样例序列化成字符串存储,tensorflow通过TFRecordWriter将这些序列化之后的字符串存成tfrecord形式
下面表示一个制作tfrecords的例子
#image_set可以选择'训练'或者'测试',images表示所有的图片数据,labels表示所有的标签,包括训练和测试
def convert(self, image_set, images, labels):
filename = os.path.join(self._image_set_path, 'dianli_{:s}.tfrecords'.format(image_set))
print('writing ', filename)
#创建一个tfrecords的writer
writer = tf.python_io.TFRecordWriter(filename)
if image_set == 'train':
names = self.train_list
elif image_set == 'test':
names = self.test_list
else:
raise ValueError
#max_object表示一张图最多有多少个object,设置这个参数是为了保证写入时所有label项的形状都是固定的
max_object_num = cfg.TRAIN.MAX_OBJECT
for ix, name in enumerate(names):
image_raw = images[ix].tostring()
single_label = labels[ix]
if single_label.shape[0] > max_object_num:
raise ValueError('number of gt object is {:d}, more than max object num!'.format(single_label.shape[0]))
#加0确保label维度固定,这样后面就可以使用tf.train.shuffle_batch
non_obj_label = np.zeros((max_object_num - single_label.shape[0], 6))
comp_label = np.vstack((single_label, non_obj_label))
#这里用(cls,xc,yc,xita,w,h)表示一个斜框标签,cls表示框里面目标的类别
cls = comp_label[:, 0].tolist()
xc =