Mxnet deepdog(热狗不是热狗)示例 - 网络如何知道它正在对热狗进行分类

数据挖掘 机器学习 深度学习 卷积
2022-01-22 21:54:45

查看mxnet 文档

它采用预训练的 squeenext1_1 权重,并将 imagenet_hotdog_index 变量设置为 713。

    net = models.squeezenet1_1(pretrained=True, prefix='deep_dog_', ctx=contexts)
# hot dog happens to be a class in imagenet.
# we can reuse the weight for that class for better performance
# here's the index for that class for later use
imagenet_hotdog_index = 713

然后他们在上面设置了一个 2 类输出层

    deep_dog_net = models.squeezenet1_1(prefix='deep_dog_', classes=2)
deep_dog_net.collect_params().initialize(ctx=contexts)
deep_dog_net.features = net.features
print(deep_dog_net)

我感到困惑的是classify_hotog函数——它将softmax应用于输出层,然后返回最高的结果索引。如果我们以某种方式告诉网络与索引 713 进行比较,这将非常有意义。但是在重新使用索引变量之前调用它进行预测?网络如何知道要比较的类是索引 713/hot dog?我们基本上采用了squeezenet并将其减少到2类输出。但是网络如何知道将其与哪个类进行比较?为什么在展示热狗时它会给第二个参数/类提供很高的概率 - 在我看来,它不应该知道它将它与哪个类进行比较?

out = mx.nd.SoftmaxActivation(net(image.as_in_context(contexts[0])))
print('Probabilities are: '+str(out[0].asnumpy()))
result = np.argmax(out.asnumpy())

我原以为它可能会使用完整的squeezenet输出层,并设置类似

if np.argmax(out.asnumpy()) == 713:
     "Hot Dog!'
Else:
     "Not hot dog!"

从来没有理解这一点,如果有人能帮助我得到这个细节,我将不胜感激。

1个回答

你在正确的轨道上。但是您必须意识到 713 只是有效地用作索引查找来获取该类的权重并“播种”您的新模型。从那里,模型变成了一个二进制分类模型,其中 0 是 nothotdog,1 是 hotdog。一旦拿起重量,713 就不应该在您的模型中的其他任何地方找到。

因此,最初的输出将是 something [0.493, 0.507],每个对应于图像属于两个类别之一的概率。从那里,调用argmax()根据二进制选择寻找哪个概率最高。所以它会选择 0.507 并将其称为热狗,因为它对应于二进制值 1。

如果您想在所有这些上验证我,请转到您的输出代码并执行类似的操作print(out.asnumpy()),您就会明白我的意思。