3

目前我正在使用 VGG16 + Keras + Theano 认为迁移学习方法来识别植物类。它工作得很好,给了我很好的准确性。但我要解决的下一个问题是找到一种方法来识别输入图像是否包含植物。我不想让另一个分类器来做这件事,因为它不是很有效。

所以我做了一些搜索,发现我们可以从最新的模型层(激活层之前)获取激活并对其进行分析。

from keras import backend as K

model = util.load_model() # VGG16 model
model.load_weights(path_to_weights)

def get_activations(m, layer, X_batch):
    x = [m.layers[0].input, K.learning_phase()]
    y = [m.get_layer(layer).output]
    get_activations = K.function(x, y)
    activations = get_activations([X_batch, 0])

    # trying to get some features from activations
    # to understand how can we identify if an image is relevant
    for l in activations[0]:
        not_nulls = [x for x in l if x > 0]

        # shows percentage of activated neurons
        c1 = float(len(not_nulls)) / len(l)
        n_activated = len(not_nulls)
        print 'c1:{}, n_activated:{}'.format(c1, n_activated)

    return activations

get_activations(model, 'the_latest_layer_name', inputs)

从上面的代码中我注意到,当我们有非常不相关的图像时,激活的神经元数量比包含植物的图像要大:

  1. 对于用于模型训练的图像,激活的神经元数量为 19%-23%
  2. 对于包含未知植物物种的图像 20%-26%
  3. 对于不相关的图像 24%-28%

了解与百分比值相关的图像是否相交并不是一个很好的功能。

那么,有没有解决这个问题的好方法呢?

4

1 回答 1

0

感谢上面评论中的 Feras 的想法。经过一些试验,我想出了最终的解决方案,可以解决这个问题,准确率高达 99.99%。

步骤是:

  1. 在数据集上训练你的模型;
  2. 通过使用上一步中的训练模型预测相关和不相关的图像来存储激活(参见上面的方法如何获取它们)。您应该从倒数第二层获得激活。对于 VGG16,它是两个 Dense(4096) 中的最后一个,对于 InceptionV3 - 一个额外的倒数第二个 Dense(1024) 层,对于 resnet50 - 一个额外的倒数第二个 Dense(2048) 层。
  3. 使用存储的激活数据解决二进制问题。我尝试了一个简单的平面神经网络和逻辑回归。两者的准确性都很好(平面神经网络更准确一些),但我选择了逻辑回归,因为它更简单、更快并且消耗更少的内存和 CPU/GPU。

每次重新训练模型后,都应重复此过程,因为每次 CNN 的最终权重都不同,而以前的工作方式下次会有所不同。

因此,我们有另一个解决问题的小模型。

于 2017-05-12T07:46:42.547 回答