如何为深度学习模型添加新类别?


15

假设我已经在经过预先训练的网络上进行了转移学习,可以识别10个对象。如何添加网络可以分类的第11个项目,而又不丢失我已经训练的所有10个类别或原始预训练模型的信息?一位朋友告诉我,该领域正在积极研究中,但是我找不到任何相关论文或名称来搜索?

谢谢。


如果您要上更多的课,那有什么?那可以帮助吗?例如,假设您知道不超过1000个课程。您从一开始就在您当前拥有的10个班级中使用1000个班级进行分类训练,而当您有更多班级时,只需继续对它们进行分类……这可以是一个好的解决方案吗?是否有关于此方法的论文?
迈克尔

Answers:


13

如果这只是一次性情况,则可以简单地重新训练神经网络。如果您经常不得不添加新的类,那么这是一个坏主意。在这种情况下,您要执行的操作称为基于内容的图像检索(CBIR),或简称为图像检索或视觉搜索。我将在下面的答案中解释这两种情况。

一次性案件

如果这种情况只发生过一次-您忘记了第11类,或者您的客户改变了主意-但不会再次发生,那么您只需将第11个输出节点移到最后一层即可。随机初始化此节点的权重,但将您已有的权重用于其他输出。然后,像往常一样训练它。固定一些重量可能会有所帮助,即不要训练这些重量。

一个极端的情况是只训练新的砝码,而其他所有砝码保持固定。但是我不确定这是否能很好地工作-值得一试。

基于内容的图像检索

请考虑以下示例:您正在CD商店工作,该商店希望他们的客户能够为专辑封面拍照,然后该应用程序向他们显示他们在其在线商店中扫描的CD。在这种情况下,您将不得不为商店中的每张新CD重新培训网络。每天可能有5张新CD,因此以这种方式重新训练网络是不合适的。

解决方案是训练网络,该网络将图像映射到特征空间。每个图像将由描述符表示,例如256维矢量。您可以通过计算该描述符并将其与描述符数据库(即商店中所有CD的描述符)进行比较来对图像进行“分类”。数据库中最接近的描述符获胜。

您如何训练神经网络来学习这样的描述符向量?那是一个活跃的研究领域。您可以通过搜索“图像检索”或“量度学习”之类的关键字来查找最新作品。

现在,人们通常采用预先训练的网络,例如VGG-16,切断FC层,并使用最终的卷积作为描述符向量。您可以进一步训练该网络,例如,使用具有三重态损失的暹罗网络。


我一直在研究一次性学习。您认为这对我有帮助吗?
nnrales

我真的不知道一键式学习。但是我发现的一口深度学习论文看起来与CBIR方法非常相似,因此它绝对对您有用
hbaderts

2

您的网络拓扑可能看起来有所不同,但最后,您的预训练网络具有一层,可处理10个原始类别的识别。引入第11、12..nth类的最简单(也是可行的)技巧是授予最后一个之前使用所有层并添加一个新的层(在新模型中或作为并行层)除了最后一层之外,所有层都将类似于10class层(最有可能是致密层的覆盖层和[len(dense layer), 10]具有可选偏置的形状矩阵)。

您的新层将是形状为matmul的层[len(dense layer), len(new classes)]

如果没有原始训练数据的访问,您将有两个选择:

  1. 通过允许“新”模型仅优化新权重来冻结原始图层中的所有权重。这将为您提供与原始10个班级完全相同的预测能力,并可能为新班级带来不错的性能。
  2. 一次训练整个网络(通过传播新类别的错误),这可能适用于新类别,但是最终将导致无效的原始解决方案(适用于10个类别)(因为权重将针对较低类别和最终层进行更改)不会进行更新以匹配这些更改)。

尽管可以访问原始培训数据,但是您可以轻松地将新课程添加到原始网络,并对其进行重新培训以支持现成的11个课程。


2

这很容易做到。

首先使用这10个类构建模型,并将模型另存为base_model。

加载base_model并定义一个新模型new_model as-

new_model = Sequential()

然后将base_model的图层添加到new_model-

# getting all the layers except the last two layers
for layer in base_model.layers[:-2]: #just exclude the last two layers from base_model
    new_model.add(layer)

现在,使新模型的层不可训练,因为您不希望再次训练模型。

# prevent the already trained layers from being trained again
for layer in new_model.layers:
    layer.trainable = False

现在,当您转移学习内容时,在删除最后一层时,该模型会忽略10个类,因此我们必须将base_model的权重保留给new_model-

weights_training = base_model.layers[-2].get_weights()
new_model.layers[-2].set_weights(weights_training) 

现在在最后添加一个密集层,在此示例中,我们将只训练该密集层。

new_model.add(Dense(CLASSES, name = 'new_Dense', activation = 'softmax'))

现在训练模型,希望它能为所有11个班级提供正确的输出。

学习愉快。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.