如何减少大图像的 GPU 内存使用量?

人工智能 卷积神经网络 张量流 训练 喀拉斯 显卡
2021-10-22 20:04:35

我正在尝试训练 CNN-LSTM 模型。我的图像大小为 640x640。我有一个 GTX 1080 ti 11GB。我正在使用带有 TensorFlow 后端的 Keras。

这是模型。

img_input_1 = Input(shape=(1, n_width, n_height, n_channels))
conv_1 = TimeDistributed(Conv2D(96, (11,11), activation='relu', padding='same'))(img_input_1)
pool_1 = TimeDistributed(MaxPooling2D((3,3)))(conv_1)
conv_2 = TimeDistributed(Conv2D(128, (11,11), activation='relu', padding='same'))(pool_1)
flat_1 = TimeDistributed(Flatten())(conv_2)
dense_1 = TimeDistributed(Dense(4096, activation='relu'))(flat_1)
drop_1 = TimeDistributed(Dropout(0.5))(dense_1)
lstm_1 = LSTM(17, activation='linear')(drop_1)
dense_2 = Dense(4096, activation='relu')(lstm_1)
dense_output_2 = Dense(1, activation='sigmoid')(dense_2)
model = Model(inputs=img_input_1, outputs=dense_output_2)

op = optimizers.Adam(lr=0.00001, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.001)

model.compile(loss='mean_absolute_error', optimizer=op, metrics=['accuracy'])

model.fit(X, Y, epochs=3, batch_size=1)

现在,使用这个模型,我只能在图像大小调整到 60x60 时使用训练数据,或者更大,并且我的 GPU 内存用完了。

我想使用尽可能大的尺寸,因为我想保留尽可能多的歧视性信息。(标签将是 0 - 640 之间的鼠标屏幕坐标)。

在许多其他问题中,我发现了这个问题:如何在 CNN 中处理大尺寸的图像?

尽管我不确定如何“限制您的 CNN”或“在每个时期流式传输您的数据”,或者这些是否会有所帮助。

如何减少使用的内存量以便增加图像大小?

是否有可能牺牲训练时间/计算速度来支持更高分辨率的数据,同时保持模型的有效性?

注意:以上模型不是最终的,只是一个基本的支出。

1个回答

正如其他链接所建议的那样,您基本上有四个选择:

  • “限制你的 CNN”。这意味着让你的模型更小更简单,可能通过在前面插入一个池化层,或者减少总层数。从内存的角度来看,这不太可能产生非常大的收益。
  • “在每个时代流式传输您的数据”。默认情况下,整个训练集将存储在 GPU 上。这是一个好主意,因为连接 GPU 和 RAM 的总线具有极高的延迟。开始通过总线发送数据需要很长时间。但是,大多数系统在 RAM 中的空间比在 GPU 上的视频内存中的空间大得多。您可以将其存储在主内存中,然后手动移动您想要用于给定更新的一批数据,而不是将所有训练数据存储在 GPU 中。计算更新后,您可以释放分配给批次的内存。我不确定如何在 Keras 中执行此操作。过去,我通过编写自定义 CUDA 内核来做到这一点。
  • “使用更少的数据”。如果您在训练数据的随机子集上进行训练,则可以使图像保持高质量,但您的模型可能会过拟合。如果您对下采样图像进行训练,您的模型可能无法很好地区分它们。但是,这两个选项都很容易做到。
  • “获得更多内存”。如果您购买具有更多视频 RAM 的视频卡,则可以训练更复杂的模型。这就是为什么科学级卡的内存比游戏卡大得多的原因。Tesla V100有 32GB 内存,16GB 卡很常见,而即使是最先进游戏卡也只有 11GB。