我有一个图像分类任务,我为每个图像创建了多个裁剪图以及翻转/翻转版本以扩展有限的数据集。我已将数据集写入tfrecords文件,其中每个记录均由文件组成(这里简化为两个农作物,只有一个翻转的版本):
{
lbl: int,
crop_0: np.ndarray,
crop_1: np.ndarray,
crop_0_flipped: np.ndarray,
crop_1_flipped: np.ndarray
}
基本上每张输入4张图像。在训练过程中,我想将每张图像都分开对待,即将每条记录作为具有相同标签的4张图像进行处理,并与数据集中的其余图像进行混洗,以使 N 图像变为< em> 4N 张图片。在测试期间(使用单独的但结构类似的数据集),我想拍摄每张图像,仅使用crop_0和crop_1图像,并对softmax输出求平均值以进行分类。
我的问题是-训练这种数据集的最佳和最有效的方法是什么?如果这会使培训效率降低,我愿意改变我的方法,而且似乎最简单的方法是将每个版本的tfrecords文件(裁剪和翻转/翻页图像)分开并将文件插入一个数据集,但如果能提供帮助,我不想拥有一堆文件。
答案 0 :(得分:0)
将包含4N个图像的数据集写入磁盘是一种方法,您稍后会讨厌(我最初是这样做的,现在讨厌该代码)。更好的方法是将原始数据集保持在磁盘上,不要将预处理步骤写入磁盘。训练时在CPU中进行这种预处理。 tensorflow数据集预处理管道使这一过程变得简单,模块化,并提供了利用多核所需的并行化,而无需支付额外的编码费用。
这是主要指南:
https://www.tensorflow.org/programmers_guide/datasets
您的方法应该是创建2个数据集对象,一个用于训练,一个用于测试。火车数据集管道将执行您提到的所有数据扩充。测试数据集管道自然不会。
理解这种方法的一个关键是您不会使用feed_dict
将数据馈送到tensorflow,相反,tensorflow只会调用数据集管道来提取每批所需的数据。
要获得并行化,您将使用Dataset.map
函数应用一些转换集,并使用属性num_parallel_calls
在多个内核之间分配操作。如果您可以使用张量流代码进行预处理,那很好,否则,您需要使用tf.py_func
来使用python预处理代码。
我上面链接的指南很好地描述了所有这些。您将需要我们在“创建迭代器”一节中介绍的可填充迭代器。这将允许您从2个数据集中的每个数据集(训练和测试)中获取一个字符串ID,并通过feed_dict
将该字符串传递给tensorflow,指示应从两个数据集中的tensorflow中提取样本。