引子在最近的工作中，用到了互信息量，但是我对这些知识已经忘记了，这次就来一个比较系统的梳理。熵信息论中的熵，和我们中学学的热力学的熵不是一个概念。在热力学中，熵用于衡量「系统的混乱程度」，比如过氧化氢的分解就是一个熵增反应，反应让系统变混乱了：$$ 2H_2O_2(l)\rightarrow2H_2O(l)+O_2(g) $$两摩尔液体生成了两摩尔液体，却又生成了一摩尔的气体。信息论中的熵，与其说是衡量系统的混乱程度，不如说是一种衡量「不确定性」的尺度，也是一种「能够包含多少信息」的尺度。对于一条消息，如果消息已经在我们的预料之中，那么其不确定性就很小，包含的新信息也就少；如果一条消息大大出乎我们的预料，那么它对于我们来说，不确定性就很高，包含的新信息也就更多。这个概念感性总结起来就是：「熵越高，越难猜，包含的信息量越大」。但是，只是单纯的感性认识是远远不够的，我们需要一个公式来定量衡量一条信息的熵的大小。香农在20世纪中叶提出来了一个公式，对于一个随机变量$\rm X$，其信息熵$\rm H(X)$被定义为如下的公式：$$ \rm H(X) = -\sum_{i=1}^nP(x_i)\log(P(x_i)) $$为什么是这样？这里不过多研究，可以参考[为什么香农要将信息熵公式要定义成 -Σp·log₂(p) 或 -∫p·log₂(p)dp？ - 大永顺帝国gxh的回答 - 知乎](https://www.zhihu.com/question/30828247/answer/2146861892)。信息熵满足这么几个性质：连续性。也就是说，随着概率的变化，信息熵不能够出现跳变和间断点。极值性。若随机变量的每个取值的概率都相等，信息熵将最大。因为这个变量预测的难度特别大。两个同时发生的事件的熵，不超过两个事件分别发生的熵的和。也就是$\rm H(X,Y)\leq H(X)+H(Y)$。如果两个事件独立，就是等于，否则就是小于。但是，容易知道：$\rm H(X,Y)=H(Y)+H(X\mid Y)$。最后一条可能不好感性理解，我们来举个例子，比如我们在丢骰子，如果丢到6，就出去吃烤肉。那么$\rm H(X,Y)$衡量的就是「能不能丢到6」并且「能不能出去吃烤肉」这个信息究竟能包含多少信息，这个事件的信息分为两个部分，一个部分是$\rm H(Y)$，也就是「能不能出去吃烤肉」承载的信息，但是，这个信息和「能不能丢到6」是息息相关的。我们的心里早有预料，丢到6一定要吃烤肉，所以在丢到6之后，吃烤肉这个事情就是必然发生的，没有「我突然告诉你要出去吃烤肉」来得意外，所以，总体包含的信息就不是$\rm H(X)+H(Y)$，而是$\rm H(Y)+H(X\mid Y)$。信息量我们现在弄明白了信息熵究竟是什么，其实它就是一个衡量「能够包含多少信息」的量度，但是我们还需要一个东西来衡量一条消息究竟「包含了多少消息」。这里就引入了信息量的概念。对于随机变量$\rm X$的某个取值$\rm x_i$，其自信息（信息量）$\rm I(x_i)$是：$$ \rm I(x_i) = -\log P(x_i) $$感性认知一下，如果$\rm P(x_i)$越小，那么自信息就越大，就表明，这个事情发生了，非常出乎我的预料。互信息量与KL散度回到刚才的例子，我们还想衡量「能不能丢到6」和「能不能出去吃烤肉」之间的依赖关系，又该怎么办呢？这个时候就引入了互信息量的概念，对于两个随机变量$\rm X$和$\rm Y$而言，它们两个之间的互信息量（依赖程度）$\rm I(X;Y)$是：$$ \rm I(X;Y) = \sum_{y\in Y}\sum_ {x\in X}P(x,y)\log(\frac{P(x,y)}{P(x)P(y)}) $$这个公式看起来非常的丑陋，我们还可以将它化作另一种形式：$$ \rm I(X;Y)=H(X,Y)-H(X\mid Y)-H(Y\mid X) $$这里的含义就是，两个随机变量的联合起来的不确定程度，减去给定$\rm Y$后，$\rm X$的混乱程度和给定$\rm X$后，$\rm Y$的混乱程度。因为如果知道了一个变量，再去算混乱程度，就和已知变量无关了，无法看出两个随机变量之间的相关性。相关性一定是二者之间的彼此制约、辅助的关系。互信息量还有一种格式：$$ \rm I(X;Y) = D_{KL}(P(x,y)||P(x)P(y)) $$KL散度衡量用后分布拟合前分布所带来的数据损失。如果$\rm X$和$\rm Y$完全无关，那么损失就是0，表示二者没有什么关联，但是如果二者相关，那么互信息量就不为0。
引子最近我在用C语言手写一个机器学习库，涉及到了矩阵乘法的反向传播过程。发现网络上并没有非常好的矩阵乘法求导的资料，这里简单地记录一下。标记假设$\mathbf{A},\mathbf{B}$分别是一个\(m\)行\(n\)列的矩阵和一个\(n\)行\(p\)列的矩阵，那么我们有： \mathbf{Y}_{m\times p}=\mathbf{A}_{m\times n}\mathbf{B}_{n\times p} 其中：$$ \mathbf{Y}=\begin{bmatrix} y_{11} & y_{12} & \cdots & y_{1p}\\\\ \cdots & \cdots & \cdots & \cdots\\\\ y_{m1} & y_{m2} & \cdots & y_{mp}\\\\ \end{bmatrix} $$$$ \mathbf{A}=\begin{bmatrix} a_{11} & a_{12} & \cdots & a_{1n}\\\\ \cdots & \cdots & \cdots & \cdots\\\\ a_{m1} & a_{m2} & \cdots & a_{mn}\\\\ \end{bmatrix} $$$$ \mathbf{B}=\begin{bmatrix} b_{11} & b_{12} & \cdots & b_{1p}\\\\ \cdots & \cdots & \cdots & \cdots\\\\ b_{n1} & b_{n2} & \cdots & b_{np}\\\\ \end{bmatrix} $$推导根据矩阵乘法的定义我们知道：$$ y_{ij}=\sum_{k=1}^{n}a_{ik}b_{kj}, i\in [1,m],j\in [1,p] $$其中，\(i,j,k\)为整数，那么我们有：$$ \frac{\partial y_{ij}}{\partial a_{st}} = b_{tj}\ \text{if}\ s=i\ \text{otherwise}\ 0 $$$$ \frac{\partial y_{ij}}{\partial b_{st}} = a_{is}\ \text{if}\ s = i\ \text{otherwise}\ 0 $$如果应用科罗涅克delta函数进行表示：$$ \frac{\partial y_{ij}}{\partial a_{st}} = b_{tj}\delta_{is} $$$$ \frac{\partial y_{ij}}{\partial b_{st}} = a_{is}\delta_{is} $$根据偏导数的加法规则以及链式法则：$$ \frac{\partial \mathbf{Y}}{\partial a_{st}} = \sum_{i=1}^m\sum_{j=1}^p\frac{\partial \mathbf{Y}}{\partial y_{ij}}\frac{\partial y_{ij}}{\partial a_{st}}=\sum_{i=1}^m\sum_{j=1}^p \frac{\partial \mathbf{Y}}{\partial y_{ij}} b_{tj}\delta_{is} $$由于当\(i\neq s\)的时候，\(\delta_{is}=0\)，故上式可变为更简单的形式：$$ \frac{\partial \mathbf{Y}}{\partial a_{st}}=\sum_{j=1}^p \frac{\partial \mathbf{Y}}{\partial y_{sj}} b_{tj} $$这是这样一个矩阵：$$ \frac{\partial \mathbf{Y}}{\partial a_{st}} = \begin{bmatrix} 0 & 0 & \cdots & 0\\\\ \cdots & \cdots & \cdots & \cdots\\\\ b_{t1} & b_{t2} & \cdots & b_{tp}\\\\ \cdots & \cdots & \cdots & \cdots\\\\ 0 & 0 & \cdots & 0\\\\ \end{bmatrix} $$非0的行为第s行。那么\(\frac{\partial \mathbf{Y}}{\partial \mathbf{A}}\)也就很显然了，是一个矩阵的矩阵，也是一个高阶张量。实际应用那么这就衍生出来一个问题，在实际的反向传播过程中，每一个元素的梯度通常是一个标量，而不会是一个矩阵，我们该如何设计机器学习的反向传播过程呢？其实，在手写机器学习库的过程中，我们所需要的并不是$\frac{\partial \mathbf{Y}}{\partial \mathbf{A}}$，而是$\frac{\partial L}{\partial \mathbf{A}}$，这里$L$是损失函数，是标量。对于任意一层的矩阵来说，每一个元素的梯度实际上是下面的式子：$$ \frac{\partial L}{\partial a_{st}} =\sum_{j=1}^p \frac{\partial L}{\partial y_{sj}} b_{tj} $$其中，$\frac{\partial L}{\partial y_{sj}}$是来自前面一层的梯度矩阵的某个元素，这里蕴含的公式是： (\frac{\partial L}{\partial \mathbf{Y}})_{sj}=\frac{\partial L}{\partial y_{sj}} 那么，上面的“每一个元素梯度”的式子其实就是一个矩阵的乘法，也就是说：$$ \frac{\partial L}{\partial \mathbf{A}} =\frac{\partial L}{\partial \mathbf{Y}}\mathbf{B}^T $$类似的，我们有：$$ \frac{\partial L}{\partial \mathbf{B}} =\mathbf{A}^T\frac{\partial L}{\partial \mathbf{Y}} $$最后这两个式子，是我们需要用在机器学习库中的式子。