分层softmax

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分层softmax相关的知识,希望对你有一定的参考价值。

参考技术A

中文名叫霍夫曼树/霍夫曼编码,是个二叉树(注意 不是 二叉搜索树),这部分内容比较简单, 维基百科 上也说的非常清楚, 下面搬运一下维基百科上的例子
示例:
霍夫曼树常处理符号编写工作。根据整组数据中符号出现的频率高低,决定如何给符号编码。 如果符号出现的频率越高,则给符号的码越短,相反符号的号码越长 。假设我们要给一个英文单字"F O R G E T"进行霍夫曼编码,而每个英文字母出现的频率分别列在Fig.1。

演算过程:

(一)进行霍夫曼编码前,我们先创建一个霍夫曼树。

最后产生的树状图就是霍夫曼树,参考Fig.2。

(二)进行编码

word2vec Parameter Learning Explained这篇论文中介绍了 Continuous Bag-of-Word Model(连续词袋模型)和skip-gram model(跳字模型),分别对应了词向量的两种训练方法:利用context预测中心词以及利用中心词去预测context。对于连续词袋模型(CBOW)来说,一般的做法(如下图所示)是先对每个单词进行one-of-N编码(one-hot encoded),作为训练网络的输入,接着构建一层hidden layer,最后构建输出层,这一层是一个softmax层,每个context单词到中心单词的事件都被认为是 独立的 ,所以将这些事件发生的 概率相乘 ,最后构建损失函数,即:将输出概率分布和实际选中的词概率分布进行Corss Entropy计算,接下来使用SGD对参数进行更新。这里,hidden layer的训练结果就是最终的 word vector 了。

上述方法看起来是没毛病的,问题是计算量有点大,尤其是进行反向传播更新参数的时候:

式(1)说明,参数更新的时候,对于每一个单词每一次迭代都 至少 有 的计算量,如此大的计算量是由于softmax引用了词典中的所有单词。

在skip-gram模型中也是一样的:

为了减少计算量,作者提出了两种近似计算方法,第一种叫做 Negative Sampling (负采样),该方法就是对词典中的特定属性的单词进行特定分布的采样,将计算的数据量降低了(详见论文);第二种就是 Hierarchical Softmax (分层softmax/层次softmax),该方法将 softmax层 替换成了 分层softmax层 。
分层softmax 的计算过程如下图所示:

图片来自 这里

从图中可以看出,hidden layer到output layer的连接原本是一个简单的softmax,有 V个神经元 和所有的hidden layer两两连接,现在变成了一个树,有 V-1个神经元 和所有的hidden layer两两连接。计算概率的方法也发生了变化:

其中,当 时,中括号内为1,否则为-1,这是用到了一个sigmoid函数的小trick: 。所以式(2)的意思就是从根节点到目标单词,有且仅有一条路径可以到达,在这条路径上往左走的概率是 ,往右走的概论自然就是 , 逻辑回归 那篇也介绍过,sigmoid函数是用来做二分类的,在这里正好合适;当路径上的所有二分类的概率都连乘后,得到的就是预测单词的概率,可以证明,词典中所有单词被预测到的概率和为1。这也是这个方法被叫做分层softmax的原因了。

如此一来,计算某个单词被预测的概率就仅仅和该单词到hidden layer的神经元连接的唯一路径相关了,更新参数的时候计算量一下子降到了O(log(n))。

关于这方面的源码编写可以参考 这个美国老哥的博客 。

使神经网络具有分层输出会更好吗?

【中文标题】使神经网络具有分层输出会更好吗?【英文标题】:Is it better to make neural network to have hierarchical output? 【发布时间】:2018-06-22 14:10:57 【问题描述】:

我对神经网络很陌生,我最近构建了用于车牌号码分类的神经网络。它有 3 层:1 个输入层用于 16*24(382 个神经元)数字图像,具有 150 dpi,1 个隐藏层(199 个神经元)具有 sigmoid 激活函数,1 个 softmax 输出层(10 个神经元)用于每个数字 0 到 9。

我正在尝试扩展我的神经网络以对车牌中的字母进行分类。但我担心如果我只是简单地在输出中添加更多类,例如在分类中添加 10 个字母,所以总共 20 个类,神经网络很难将特征与每个类分开。而且,我认为当输入是数字之一并且神经网络错误地将其归类为概率最大的字母之一时,即使所有数字输出的概率之和超过了它,它也可能会导致问题。

所以我想知道是否可以通过以下方式构建分层神经网络:

有 3 个神经网络:'Item'、'Number'、'Letter'

    'Item' 神经网络对输入是数字还是字母进行分类。

    如果“项目”神经网络将输入分类为数字(字母),则输入通过“数字”(“字母”)神经网络。

    返回数字(字母)神经网络的最终输出。

每个网络的学习机制如下:

    “项目”神经网络学习数字和字母的所有图像。所以有 2 个输出。 'Number'('Letter') 神经网络只学习数字(字母)的图像。

我应该选择哪种方法来进行更好的分类?只需简单地添加 10 个以上的类或使用上述方法构建分层神经网络?

【问题讨论】:

+1 一些错别字但归零(这不值得-1),作为在工作宽度神经网络时要问的一个非常合理的问题,这里的一些人可能会拒绝任何没有代码的问题,或者研究证明,征求意见也很复杂。但对于 NN 来说,这样做是合理的。但是思考它的工作原理也是研究 【参考方案1】:

我强烈建议只训练一个神经网络,输出您希望能够检测的所有类型的图像(因此您希望能够识别的每个字母都有一个输出节点,每个字母都有一个输出节点)您希望能够识别的数字)。

这样做的主要原因是因为识别数字和识别字母实际上是完全相同的任务。直观地说,您可以将经过训练的多层神经网络理解为分多个步骤执行识别。在隐藏层中,它可以学习检测各种简单的原始形状(例如,隐藏层可以学习检测垂直线、水平线、对角线、某些简单的曲线形状等)。然后,在隐藏层和输出层之间的权重中,它可以学习如何将多个这些原始形状的组合识别为特定的输出类(例如,大致正确位置的垂直和水平线可以识别为大写字母@ 987654322@)。

它在隐藏层中学到的那些“东西”将与数字和字母完全相关(当与其他形状组合时,可能表示L 的垂直线也可能表示1)。因此,有一些有用的东西需要学习,它们与这两个“任务”都相关,如果它可以在同一个网络中学习它们,它可能会更容易地学习这些东西。

另请参阅this answer I gave to a related question in the past。

【讨论】:

那么,你是说在实践中,神经网络在区分类别方面比我想象的要好,尽管这对我们来说很常见,比如区分“l”和“1”? @강신욱 我认为区分“I”和“1”实际上对于网络来说可能非常困难。但在分层思想的情况下,这个问题会变得更糟。假设网络显示为“I”,并且必须首先确定这是字母还是数字(尚未确定它是哪个特定字母或数字)。与简单地直接区分“I”和“1”相比,这将是一个更容易的问题吗?我认为不会,最好的情况是同样困难。 如果您确定字母和数字的位置(可能因国家和使用的系统而异),问题会变得更容易。如果他们固定,您可以拥有 2 个网络,否则我推荐一个,尤其是一个会发现 1 和 l 本身之间的真相。顺便说一句,我希望你知道这样的网络已经存在,它实际上是一个非常有名的问题。【参考方案2】:

我正在尝试扩展我的神经网络以对车牌中的字母进行分类。但是我担心如果我只是简单地在输出中添加更多的类,例如在分类中添加 10 个字母,所以总共 20 个类,神经网络很难将特征与每个类分开。

您离问题严重的地方还很远。 ImageNet 有 1000 个类,通常在单个网络中完成。请参阅AlexNet paper。如果您想了解有关 CNN 的更多信息,请查看 chapter 2 of "Analysis and Optimization of Convolutional Neural Network Architectures"。当你使用它时,请参阅第 4 章了解等级分类。您可以阅读摘要……嗯,是它的摘要。

【讨论】:

以上是关于分层softmax的主要内容,如果未能解决你的问题,请参考以下文章

TensorFlow 入门之手写识别(MNIST) softmax算法

一起学习用Verilog在FPGA上实现CNN----SoftMax层设计

分层开发——软件系统的分层开发

数据仓库的分层架构与演进

弄不懂java项目的分层思想

将非分层变换应用于分层骨架?