我使用了从Caffe zoo下载的预训练网络权重来构建张量流中的特征提取器(VGG-16)。
因此我在TF中重新定义了网络的体系结构,导入的权重作为常量,并添加了一个额外的完全连接的层与tf.Variables,以按照铰链损失成本训练SGD的线性SVM。
我的初始训练集由numpy阵列形式的100000个32x32x3图像组成。 因此,我不得不将它们调整为224x224x3,这是VGG的输入大小,但不适合内存。
所以我删除了不必要的例子并将其缩小到10000x224x224x3图像,这很糟糕但仍然可以接受,因为只有支持向量很重要但是即便如此,我仍然在训练时获得带有TF的OOM。
不应该是这种情况,因为唯一重要的表现形式是来自4096的倒数第二层的一个很容易管理,而背负的权重只有大小(4096 + 1bias)。
所以我能做的就是首先将我的所有图像转换为TF网络的特征,只使用常数形成10000x4096数据集,然后训练第二个张量流模型。 或者在每个批次中重新计算批次的所有功能。在next_batch方法中。或者使用TF提供的panoply缓冲区/队列运行程序,但由于我并不熟悉它们,所以它有点可怕。
我不喜欢那些我认为应该有更优雅的方法(如果可能的话,没有太多的队列)。
处理此问题的Tensorflow-ic方法最多?
答案 0 :(得分:2)
如果我理解你的问题,100K图像根本不适合内存,而10K图像确实适合内存,但网络本身就是OOM。这听起来非常合理,因为假设它们每个通道每个像素使用4个字节来表示10K图像,占用5.6GiB的空间(如果你以某种方式每个通道只花费1个字节,则为1.4GiB),所以即使数据集发生也是如此为了适应内存,当您添加模型时,将会占用更多的GiB,您将获得OOM。
现在,有几种方法可以解决它:
您应该使用小型车进行培训(如果您还没有)。如果尺寸为512,则使用小批量处理器,您将向GPU加载少得多的数据。使用minibatches,您也不需要在开始时将整个数据集加载到numpy数组中。以一种一次加载512个图像,向前和向后运行(sess.run(train...)
),加载下512个图像等方式构建迭代器。这样在任何时候你都不需要在内存中有10K或100K图像同时
当您的原始图像小得多时,放大图像似乎也非常浪费。你可能会考虑做的是从VGG网络中获取卷积层(转换层的尺寸不依赖于原始图像的尺寸),并从头开始训练完全连接的层。要做到这一点,只需在展平图层后修剪VGG网,为所有图像运行它,并为每个图像生成展平图层的输出,然后在这些图像上训练三层完全连接的网络(这将相对较快)与训练整个转换网络相比,并在原始VGG网络的展平层之后插入生成的网络。这也可能产生更好的结果,因为卷积层经过训练可以找到原始尺寸图像中的特征,而不是模糊的放大图像。
答案 1 :(得分:2)
我想使用某些队列和线程的方法可以使用tf.python_io.TFRecordWriter
将训练集保存为tensorflow protobuf格式(或几个)。
然后创建一个方法来读取和解码protobuf中的单个示例,最后使用tf.train.shuffle_batch
使用前一种方法将BATCH_SIZE示例提供给优化程序。
这样,内存中最多只有一个容量(在shuffle_batch中定义)张量。
这awesome tutorial from Indico解释了这一切。