tensorflow可以通过dataset的方法对tfrecords文件进行读取,并产生训练数据进行网络训练,一般使用的是mini-batch的方法,一次给网络feed一个batchsize大小的数据,在开始查找dataset读取tfrecords文件方案时,获取到一般的方法如下:
首先定义读取的规则
def _parse_function(example_proto):
features = {'image':tf.FixedLenFeature([], tf.string),
'label':tf.FixedLenFeature([], tf.int64)}
parsed_features = tf.parse_single_example(example_proto, features)
img = tf.decode_raw(parsed_features['image'], tf.uint8)
img = tf.reshape(img, [128, 128, 1])
# 在流中抛出img张量和label张量
img = tf.cast(img, tf.float32) / 255
label = tf.cast(parsed_features['label'], tf.int64)
return img, label
然后进行参数设定(开始将以下过程理解为操作过程,后来认为理解为数据获取过程的参数设定更为合理)
dataset_train = tf.data.TFRecordDataset(fileName_train)
dataset_train = dataset_train.map(_parse_function)
dataset_train = dataset_train.shuffle(shuffle_size)
dataset_train = dataset_train .batch(batch_size)
dataset_train = dataset_train .repeat(epoch)#**********本次重点
iterator_train = dataset_train.make_one_shot_iterator()#或iterator = dataset.make_initializable_iterator()
由于开始对该过程理解为操作流程,所以擅自对得到的方案按照自己的理解进行修改(也是介绍方案的文章都只写的方法,没有介绍更多的含义),将dataset_train = dataset_train .repeat(epoch) 这句删掉了,因为看很多的文章示例,我将其理解为复制,将最后输出的结果复制指定的epoch次返给调用者,也就是我错误的将该句理解为,如果使用该语句,则得到的mini_batch的大小为batch_size的epoch倍(一篇文章给出的具体数据例看起来是这样的),之后就顺利的开始训练过程。training...
就等漫长的训练结束,结果第二天却发现,报错了,“OutOfRangeError: End of sequence”
根据报错内容进行查找资料,知道应该是我的数据集用完了,数据集已经全部循环一遍完成了,没有数据了,再取batch就报错了,错就错在对dataset_train = dataset_train .repeat(epoch)的理解错误,这句其实很重要,因为一般训练不会将数据集只训练一遍就结束,而是有很多遍的训练,而我把将整个训练集重复的设置语句删除了,也就是系统认为,我的训练集只读取一遍就结束,iterator迭代器迭代到了数据集的末尾发现没有数据可取,而写的程序确实继续进行读取数据的,因此报错。
一般来讲,dataset_train = dataset_train .repeat(epoch)中的epoch,之所以参数名称写成epoch,也是因为这个参数跟将整个训练集训练多少遍(epoch)是息息相关的,因为迭代器只能从指定的数据集来进行数据batch的获取,如果不进行repeat()的设定,那么数据集就是一遍,当超过一遍的读取数据集,就会报错。
解决方法一:根据训练过程的epoch次数设定dataset_train = dataset_train .repeat(epoch)
解决方法二:仍然需要进行repeat()设定,但epoch参数为空,即:
dataset_train = dataset_train .repeat()
当repeat()参数为空时,意思是重复无数遍,永远不会有读取不到数据batch的情况。