Tensorflow 的 ResNet 在自定义图像数据上

Tensorflow's ResNet on custom image data

我正在尝试 运行 Tensorflow 的 ResNet implementation 在我拥有的自定义图像数据集上。我以前没有使用 Tensorflow 和 neural/conv 网络的经验,所以这对我来说也是一种学习经历。

有两个实现示例,一个用于 CIFAR10 数据集,另一个用于 ImageNet 数据集。我选择使用 CIFAR10 的示例作为基准,因为它似乎更容易上手,而且我已经熟悉 CIFAR10 数据集。我 运行 它在 CIFAR10 数据集上遵循可用的 README 文件并设法切换数据和 运行 它相对容易地用于我自己的 32x32 图像数据集。

问题是,我的原始数据集包含 512x512 图像,我想 运行 使用这个原始大小。我将数据集转换为 cifar10 的二进制格式(保持 512x512 大小)并调整实现以尝试 运行 它。也就是说,我更改了文件路径和文件名,并更改了大小常量以反映数据集:

_HEIGHT = 512
_WIDTH = 512
_NUM_CHANNELS = 3
_DEFAULT_IMAGE_BYTES = _HEIGHT * _WIDTH * _NUM_CHANNELS
_RECORD_BYTES = _DEFAULT_IMAGE_BYTES + 1
_NUM_CLASSES = 5
_NUM_DATA_FILES = 10

_NUM_IMAGES = {
    'train': 1000,
    'validation': 200,
}

但是,当我尝试 运行 时出现了一些问题。如果我按原样尝试 运行,我会收到以下错误的内存分配错误:

INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
terminate called after throwing an instance of 'std::bad_alloc'
what():  std::bad_alloc

我的数据集包含 1200 多张图像,但如果我尝试一次使用它们,我的计算机 运行 就会内存不足并崩溃(我目前正在设置一台更足智多谋的计算机来解决这个问题问题)。因此,我想知道这是否仍然意味着我没有足够的内存来 运行 包含 512x512 图像的代码。我看到 tensorflow 使用 batch_size 参数来决定要缓冲多少图像

dataset = dataset.prefetch(buffer_size=batch_size)

所以我也尝试减小批大小,看看是否是为图像缓冲区分配内存时出现问题。在我得到低至 16 张图像的批次之前,会出现相同的错误。但是,对于 8 张图像,此问题不再出现,而是我收到不同的错误消息:

INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
Traceback (most recent call last):
  File "path-to/venv/lib/python3.4/site-packages/tensorflow/python/client/session.py", line 1327, in _do_call
return fn(*args)
  File "path-to/venv/lib/python3.4/site-packages/tensorflow/python/client/session.py", line 1312, in _run_fn
options, feed_dict, fetch_list, target_list, run_metadata)
  File "path-to/venv/lib/python3.4/site-packages/tensorflow/python/client/session.py", line 1420, in _call_tf_sessionrun
status, run_metadata)
  File "path-to/venv/lib/python3.4/site-packages/tensorflow/python/framework/errors_impl.py", line 516, in __exit__
c_api.TF_GetCode(self.status.status))
tensorflow.python.framework.errors_impl.InvalidArgumentError: logits and labels must be same size: logits_size=[117128,5] labels_size=[8,5]
 [[Node: softmax_cross_entropy_loss/xentropy = SoftmaxCrossEntropyWithLogits[T=DT_FLOAT, _device="/job:localhost/replica:0/task:0/device:CPU:0"](softmax_cross_entropy_loss/xentropy/Reshape, softmax_cross_entropy_loss/xentropy/Reshape_1)]]

似乎数据集大小和标签数组之间存在不匹配,但只有当我在 512x512 图像上尝试 运行 时才会出现该问题,它适用于 32x32 图像上的任何批量大小。

最后,我的问题是, 是否有一些其他参数我必须更改或我必须对 运行 我的 512x512 上的 ResNet CIFAR10 代码进行其他调整数据集?这些错误是否与我做错了什么有关,或者我可能需要解决两件事?任何关于导致这些错误的原因的见解也会有很大帮助。

简而言之,要将我自己的 512x512 数据集输入到 TensorFlow 的 ResNet CIFAR10 实现中,我需要做哪些更改?

这是我在 Whosebug 上的第一个问题,正如我所说,我对这个问题领域的很多事情都是陌生的,所以请原谅任何菜鸟的错误。

回答我自己的问题,代码有两个不同的问题。

首先,由于网络和图像的大小,机器没有足够的内存来 运行 代码。一种解决方法是使用内存更大的机器,它起作用并解决了第一个问题。然而,由于增加内存并不总是一种选择,我后来发现我可以通过增加第一个卷积层的大小或步幅来减少内存消耗。这对于 运行在通常受内存限制的 GPU 上使用 ResNet 特别有用。

其次,网络输出的大小与我的标签向量的大小(预期大小)不匹配。发生这种情况是因为输入大小发生了变化。网络通过其卷积层和池化层对输入进行下采样。问题是网络没有针对预期的输出大小对输入进行足够的下采样。更改网络超参数中的层大小解决了这个问题。

为了回答这个简短的问题,为了 运行 自定义数据集上的代码,我必须更改问题中的变量(_HEIGHT、_WIDTH 等)和模型定义中层的大小在代码中。