用最大熵搞懂Softmax

先前我们学习到的sigmoid函数它可以用来解决单一分类问题, 因为sigmoid函数本质上就是把感知机的输出投影到一个区间在\([0,1 ]\)的概率分布中, 但问题是如果我们的分类有多个那么就不能使用sigmoid了, 因为我们虽然可以把每个感知机输出的结果归一但我们无法把整层所以感知机的输出做归一化。这里我们就要引出softmax函数了, 那么它是证明计算的呢?

什么是softmax

这里可以看到, \(y^{(k)}\) 表示的是输入的\(k\)个类别每个类别用一个向量表示。\(a^{[l](k)}\)表示的是\(l\)层最后输出的结果,这里是一个概率分布, 我们要求每一个值是一个概率并且概率总和要等于1. \(z^{[l](k)}\)表示的是\(l\)层感知机的输出, 在设计softmax函数的的时候我么首先需要考虑的是把每一个输出值转换为一个大于等于0的数, 因此我们引入\(e\)将输出作为\(e\)的指数, 由于\(e^{[l](k)}\)的值域是大于0的,虽然少了等于零的情况但在这里并不重要。 接着我们需要把所有结果归一化, 因此就可以把所有值求和将每个值作为分子,这样最终\(l\)层的输出结果就归一了。由于激活函数改变了那么损失函数也需要做相应的变换。

这里的\(p_i^{(k)}\)就是我们计算出来的概率, \(q_i^{(k)}\) 是标签里的那个值, 我们需要对每一个概率都做一次交叉熵的计算, 然后再对所有的值做一次求和作为我们最后的损失值。

我们都说其实softmax就是一个放大sigmoid那就是为什么呢?我们从sigmoid的函数来看看 \[ sigmoid(z^{[l](k)}) = \frac{1}{1 + e^{-z^{[l](k)}}} = \frac{e^{z^{[l](k)}}}{e^{z^{[l](k)}} + 1} \] 我们将sigmoid函数变换了一下他是不是久很像softmax了呢, 如果我们令 \[ \begin{bmatrix} t_1\\ t_2 \end{bmatrix} = \begin{bmatrix} e^{z^{[l](k)}}\\ e^0 \end{bmatrix} = \begin{bmatrix} e^{z^{[l](k)}}\\ 1 \end{bmatrix} \]

\[ sigmoid(z^{[l](k)}) = \frac{t_1}{t_1+t_2} \, ;\, 1-sigmoid(z^{[l](k)}) = \frac{1}{t_1+t_2} = \frac{t_2}{t_1+t_2} \]

那么他和有2个分类的softmax没有什么区别了, 可能从结果来看他两并没有太大区别, 但是本质上他们是有很大区别的。 如果我们说sigmoid的分类一个是是猫的类别一个是不是猫的类别,那么softmax的结果表示的就是一个是猫的类别一个是狗的类别。


对于softmax我们本质上就是需要寻求一个归一化函数但归一化函数有那么多为什么softmax就选择了以\(e\)为底的这种形式呢, 这其实就和最大熵有关了。 我们说神经网络是可以用来逼近任意一个概率模型即使这个概率模型我们写不出来也能逼近, 我们是使得似然值最大或者交叉熵最小。其实我们使用这种方法的默认前提是我们认为似然值最大的那个概率模型最接近我们想要的那个概率模型,而当我们使用了sigmoid, softmax函数时其实我们还默任其满足了另外一个条件就是最大熵原理。

首先这里,我们用一个最简单的高斯分布来举例子。 为了确定一个高斯分布,我们只需要确定他的期望和方差就能够确定一个数据分布。 我们的希望是对于任何一个概率分布都能用类似的方法,准确地表示出来。首先我们来看一下,期望和方差是如何表示的:

首先这里的\(\mu\) 表示的是对于概率分布\(P(x)\)的期望, \(\sigma^2\) 表示的是概率分布的方差。 如果我们将方差展开就能发现他是数据平方的期望减去期望的平方\(E[x^2] - \mu^2\) 。 我们会发现在期望和方差中出现了\(E[x]\)和\(E[x^2]\)。 所以数学家们就想对于更复杂的概率分布我们是否也可以用含有类似的形式表达出来。 于是,他们就引入了一个新的概念叫偏度,他是统计数据分布倾斜方向和程度的度量。 如果我们将它展开,就能发现他确实也有类似的形式。 数学家们把\(E[x]\)称之为一阶矩, \(E[x^2]\)称之为二阶矩。 到此我们就可以思考是否可以使用不同的矩组成的向量来表示一个概率分布的特征, 事实上,数学家们已经证明了,是可以的,具体的证明就需要去发数学教材了这里就不过多证明了, 接下来我只是把他的正确性呈现一下。

这里定义了一个特征函数\(\varphi_X(t)\) , 我们把一个复数\(e^{itx}\)放进概率分布求期望。 任何一个概率分布都可以有一个特征函数表示,也就是说任何一个概率分布都有一个特征函数与其一一对应。 对于一个特征函数,我们只要对其进行泰勒展开就能变成上面的形式,到这里我们就非常熟悉了。 特征函数展开后就含有我们所说的一阶矩, 二阶矩等等, 而且我们可以看出特征函数展开后和我们的矩组成的向量其实是线性关系。 因此,对于两个不一样的概率分布我们只需要去比较它们的矩向量,并不需要计算准确的概率分布也能比较它们之间的差距。 到这里,其实我们还有一个小疑问就是数学家们是如何确定一个概率分布有且唯一有一个特征函数与其一对应的呢? 我们只需要把特征函数展开,然后对其概率密度函数做傅立叶变换就可以发现他的傅立叶变换和特征函数是共轭的, 他们是一个一一对应的关系。 而傅立叶变换就可以和概率分布做一一对应, 于是一个概率分布就可以和一个特征函数做一一对应。 因此假设我们有一个函数\(f(x)\), 我们只需要把它丢到两个概率分布模型中去求期望, 然后比较两个期望是否相等,就可以比较两个模型是否相等了。

Screen Shot 2022-03-08 at 4.32.49 pm

当我们了解什么是矩之后,我们就可以拿去和交叉熵作比较了。对于两个形式类似的模型,我们可以用矩来精确的定量比较两个概率模型是否相等,但是如果两个概率模型的形式都差别非常大的话, 使用矩就很难比较两个模型的差别,那我们就可以使用交叉熵来衡量模型之间的差距了。

经验概率

那么接下来我们看看如何把我们前面所学到的东西运用在真正的数据里,我们先举一个非常简单的例子。

我们先引入一个新的概念也就是这里的\(\tilde{p}\) 他叫作经验概率。 也就是我们从数据中可以直接总结出来的概率。 那他究竟是如何计算出来的呢,我们可以看到下面的\(\tilde{p}_1, \tilde{p}_2, \tilde{p}_3\) 分别都是数据中不同的条件组合的数量除以数据集的总数计算出来的概率,我们把所有的组合的概率计算之后做一个结合,就是这里的经验概率。 当然这是一个结构型的数据,当我们放到神经网络中以图片为数据的话,又是怎么做的呢?

这里的\(x, y\) 分别是样本和标签, 也就是图片啦,当然这里的\(x, y\) 都是向量。 我们计算每个样本的每个像素的经验分布。 但是,这里就会有个疑问,样本中不可能有两张完全一模一样的图片,那么这样的话这里就很出来的经验概率永远都是\(\frac{1}{N}\), 那不就没有任何意义了吗? 当然,这是我们从输入层来看是对每一个像素求经验分概率, 但是随着网络的加深感知机的数量越来越少,那每一个感知机就会关注不同的特征,那经验概率的意义就体现出来了。 当我们在隐藏层中再做经验概率时, \(\tilde{p}(x, y) = \frac{count(\cdots x_j, \cdots y_i)}{N}\)我们得到了可能就不是简简单单的\(\frac{1}{N}\)。当然我们也可以不考虑\(y\)求\(\tilde{p}(x) = \frac{count(\cdots x_j, \cdots y_i)}{N}\) 。我们的目标是求\(P(y\,|\,x)\), 其中包含了一部分已知的信息,一部分未知的信息,已知的信息要求完全相等,未知的信息我们使用最大熵。

Screen Shot 2022-03-08 at 6.01.05 pm

这里我们使用贝叶斯公式将其展开, 然后我们就可以发现我们可以使用前面求到的经验概率\(\tilde{p}(x, y), \tilde{p}(x)\)去替换\(p(x, y), p(x)\)。 那这一部分就是我们已知的信息, 而另一部分未知的信息,我们就使他熵最大。 其实上面两种方法都可以,但是为了之后的求导更方便我们使用第一种。

在这之前我们希望两个模型求出来的期望相等,但是我们只知道经验概率是没办法求期望的, 一个函数的期望是随机变量乘以概率再相加,因此我们还需要设计一个随机变量。 我先把随机变量是怎么设计的写出来,我们再来看为什么这么设计。

Screen Shot 2022-03-08 at 6.09.10 pm

这里设计了一个随机变量\(X\),当样本空间中的样本满足事件\(A\)就等于1如果不满足事件\(A\)就等于0。 那为什么这么设计呢,我们来看对随机变量\(X\)求期望,我们会发现对随机变量\(X\)求得的期望其实就是\(\tilde{p}(A)\),就是满足\(A\)的概率本身。 因此对于更多的样本和更多的事件,我们其实不需要去求两个模型的期望。 我们只需要把每一个样本在每个事件中的概率求出来然后进行对比就可以了。 而且,由于这里的随机变量的设计他满足伯努利分布, 而伯努利分布是一个比正态分布更简单的分布,因此这里的函数分量只需要求一阶矩就够了。

Screen Shot 2022-03-08 at 6.20.10 pm

条件熵

前面那个问题搞定之后我们就要来求最大熵了,但是在求最大熵之前,我们遇到另外一个问题就是之前我们求交熵的时候用的都是一般的概率分布, 而我们现在使用的是条件概率分布在熵的方面还是一样的计算方法吗? 我们先来看一下熵的定义: \[ H(x):=-\sum_{i=1}^n P(X)\cdot \log P(X) \] 那对于条件熵来说,我们是否也可以直接将条件概率分布带入呢? \[ H(x):=-\sum_{i=1}^n P(Y\, |\, X)\cdot \log P(Y\, |\, X) \] 对于只有一个事件的情况下,我们当然可以怎么做,但是如果有多个事件的话情况就不一样了。 对于每个事件我们都会得到一个不一样的熵。 那我们怎么做一个统一化呢,最简单的想到就是求期望,我们把每一个事件的熵乘以概率再求和就能得到我们想要的条件熵。这里我们把条件熵定义为: \[ H(Y\, |X):=-\sum_{x, y} P(x) P(y \, |\, x)\log (y \, |\, x) = E(H(Y \, |\, X = x^{(k)})) \]

最大化条件熵

接下来我们需要做的就是最大化条件熵,怎么对\(p, x, y\) 取值才能最大化熵。在揭示的过程中我们就真知道为什么都说sigmoid和softmax的本质是最大熵了。首先我们改变一下求熵最大的形式变成求最小, 实际上我们不仅仅是求最小这么简单还需要满足两个条件。

Screen Shot 2022-03-08 at 7.05.28 pm

第一个是我们希望从样本空间中得到的经验概率分布的期望和真实的概率分布期望相等。 第二个条件,实际上是满足整个样本空间所有概率的归一。 因为经验概率分布的期望是个常数所以这里直接用\(\Delta_k\) 代替。 对于求它的最小值并且满足两个约束条件,我们就会用到高数上非常熟悉的拉格朗日乘数法,我们引入一个变量\(\lambda\) 接着就可以把式子改写成这样。 Screen Shot 2022-03-08 at 7.10.52 pm

这里需要大家对拉格朗日乘数法有基本的了解(不了解的谷歌去)。 接着我们对拉格朗日函数进行展开, 其实就是对后面的函数的期望展开然后用贝叶斯公式展开就可以获得上面的式子。 接着我们就考虑拉格朗日对偶问题。我们将\(P\)作为常数,先求\(\lambda\)作为参数的最大值接着把\(P\)作为常数,\(\lambda\)作为常数求最小值等价于他的对偶问题。Screen Shot 2022-03-08 at 7.16.23 pm

接着对于求拉格朗日对偶问题的最小值我们就很熟悉了,就是使他的偏导等于零那么拉格朗日函数就能取到最小值。 我们对\(L(P,\lambda)\)求关于\(P\)的偏导就是上面这样。通过观察我们可以发现每一项都有一个\(\tilde{p}(x)\)并且\(\sum_x \tilde{p}(x) = 1\)所以我么可以将所有的\(\sum_x \tilde{p}(x)\)提出来。然后使它等于0就可以使它的熵大了。Screen Shot 2022-03-08 at 7.21.05 pm

对于上式我们可以看出使得\(\frac{\partial L(P, \lambda)}{\partial P(y|x)} = 0\) 显然就是使得括号中的部分等于0就可以。因此我们对它进行一个变化就可以得到\(P(y\, |\, x)\)的函数形式。 到这里我们应该就感觉到熟悉了

Screen Shot 2022-03-08 at 7.26.31 pm

我们接着对他进行化简,对于前面\(e\)的部分我们只需要在指数加个负号就可让他变成分母,对于分子的\(e\)的指数如果我们把它用向量的形式表示就可以变成 \(\eta\)是一个关于\(\lambda\)的向量。 那么关于分母的部分,我们别忘了我们是为什么引入\(\lambda_0\), 我们的目的是加入概率归一这个约束条件。那么对于\(P(y\,|\,x)\)这个条件概率我们只需要让他的分母为所有分子的合就可以了。到这里我们就非常熟悉了。

我们只要把它放到神经网络,你去看一看就明白为什么了, 我们把它的分子当作\(t\)的话,这不就是softmax函数吗。softmax是怎么得出来的其实就是在求最大熵的时候得出来的,而这里的\(e\)也没有我们原来想的那么简单,他其实是在考虑熵的时候引入的。所以当我们使用了softmax或者sigmoid函数是其实就默认选择了最大熵的方式进行机器学习了。

References

https://www.bilibili.com/video/BV1cP4y1t7cP?spm_id_from=333.999.0.0

https://zhuanlan.zhihu.com/p/19763358

https://zhuanlan.zhihu.com/p/23739221


知识来源作者为b站UP主王木头学科学

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: 最大熵模型是一种常用的机器学习算法,它可以用于分类问题。在Python中,可以使用第三方库如scikit-learn来进行最大熵模型的分类。 具体步骤是: 1. 准备训练数据集,将样本数据和其对应的标签存储在数据结构中。 2. 对数据集进行特征提取,将样本转化为特征向量。 3. 训练最大熵模型,并得到训练好的模型。 4. 对待分类样本进行特征提取,将其转化为特征向量。 5. 利用训练好的模型进行分类预测。 使用scikit-learn库中的最大熵模型可以通过以下代码实现: ``` from sklearn.linear_model import LogisticRegression from sklearn.feature_extraction.text import CountVectorizer # 准备训练数据集 X_train = ['this is a pen', 'this is a book', 'that is a desk', 'that is a chair'] y_train = [0, 0, 1, 1] # 创建特征提取器 vectorizer = CountVectorizer() # 将文本转化为特征向量 X_train_vector = vectorizer.fit_transform(X_train) # 创建最大熵分类器 classifier = LogisticRegression() # 训练最大熵分类器 classifier.fit(X_train_vector, y_train) # 待分类文本 new_texts = ['this is a laptop', 'that is a table'] # 将待分类文本转化为特征向量 new_texts_vector = vectorizer.transform(new_texts) # 进行分类预测 predictions = classifier.predict(new_texts_vector) print(predictions) ``` 输出结果为:`[0 1]`,表示第一条待分类文本属于第0类,第二条待分类文本属于第1类。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值