【发布时间】:2020-08-05 03:33:24
【问题描述】:
我有一个由不同层组成的 Keras 模型。其中一层实际上是另一个完整的模型。当该层模型是 VGG16 时,我可以训练超级模型。这是model.summary():
当我简单地换掉 VGG16 并换入 EfficientNetB0( 更小的模型!)时,我无法再训练超级模型。这是model.summary():
“啊,”你说,“一些可训练的东西赋予了一些东西在记忆中的梯度。”
好的,当然。让我们缩小和/或核对一堆层,以便将可训练的权重降低到 VGG16 版本以下。这样做之后,我仍然无法训练超级模型!这是model.summary():
为什么我不能训练具有 30% 总权重和 25% 可训练权重的小得多的模型?
示例代码:
img = Input(shape = (224,224,3))
# ^ Don't reuse img= or Tensorflow will break!
x = BatchNormalization()(img)
x = Efnet(x)
# x = Vgg16(x)
x = Activation('linear')(x)
# ^ Don't remove pass through or Tensorflow will break!
x = GeneralizedMeanPool2D(x)
x = NormActDrop(x)
x = DenseNormActDrop(x, 32)
x = DenseNormActDrop(x, 32)
x = DenseNormActDrop(x, 32)
x = Dense(1)(x)
model = Model(inputs = img, outputs = x)
model.summary()
自定义块与您想象的一样简单,例如:
def NormActDrop(x, activation_function = mish, dropout_rate = 0.2):
x = BatchNormalization()(x)
x = Activation(activation_function)(x)
x = Dropout(dropout_rate)(x)
return x
【问题讨论】:
-
你能分享一下内存不足的堆栈跟踪吗?
-
您是否有可重现的代码,以便我们更好地了解您到底在使用什么?还要记住,大多数时候,激活是最大的内存消耗者。例如,请参见:cs231n.github.io/convolutional-networks/#case。我为 VGG 和效率网络运行了一些数字,看起来效率网络确实比 VGG 激活更少,但应该考虑到这一点,
-
@MaxCrous 什么是内存不足堆栈跟踪?如果你的意思是当一切都崩溃和燃烧时控制台吐出的任何东西,那就是成千上万行的垃圾。
-
@ZaccharieRamzi 代码在结构上与模型摘要相同,但可以肯定的是,我添加了一些代码。 VGG 和 Efnet 都被冻结了,只是在一个字面上完全相同的结构中相互交换。
-
@Nickolas 感谢分享!但是,我不知道您是如何导入
Efnet或GeneralizedMeanPool2D的,或者NormActDrop和DenseNormActDrop是否相同。最好的办法是,我可以将您的代码复制粘贴到 colab 笔记本中,然后使用 2 个不同的配置运行它,亲自查看并在其中挖掘一下。理想情况下,您甚至可以编写该 colab 笔记本并与我们分享。我知道这些事情需要特别长时间,但根据我的经验,它们对我非常有益,有时可以让我自己解决问题。
标签: python tensorflow keras out-of-memory