1. 世上并无负样本
softmax的标签是一个向量,但是这个向量中只有一个值为1,所以损失函数中也只会有一项是有值的,其他都是0,所以值也都为0。但是交叉熵损失函数中,不管0还是1都是有只的,正样本的时候,值为 log p \text{log} p logp,负样本的时候值为 log ( 1 − p ) \text{log}(1-p) log(1−p)。这就非常的奇怪,为什么负样本有值呢?
其实,我们只要把二分类写成一个向量就可以明白了,正样本有 [ 1 , 0 ] [1,0] [1,0],而负样本呢,则为 [ 0 , 1 ] [0,1] [0,1]。所以在计算损失函数的时候,负样本也是有值的。
出现这个错觉还有一个原因是,我们把正负样本和标签弄混淆了。
仔细想想,多分类的问题中有所谓的负样本吗?并没有,一个样本就是对应一个标签向量。当我们把二分类的标签也写成向量的时候,你就会发现没有所谓的负样本了。很有意思的是,当二分类的时候,我们说正负样本不均衡,当多分类的时候,我们说类别不均衡。
2. 绘制交叉熵函数
如何绘制交叉熵函数,我当时是一脸懵逼的,交叉熵的损失函数我是知道的
L = ∑ i y log y ^ + ( 1 − y ) log ( 1 − y ^ ) L=\sum_i y \text{log}\ \hat{y}+(1-y) \text{log}\ (1-\hat{y}) L=i∑ylog y^+(1−y)log (1−y^)
计算每一个样本的损失值,所有样本的值进行累加,就可以得到一个batch样本的损失值,然后我们进行优化,使这个值最小。我的经验中,只会求损失值,并不会绘制函数图像。
当正样本的时候 y = 1 y=1 y=1,此时损失函数为 L = − log y ^ L=-\text{log}\ \hat{y} L=−log y^,可以看出这是一个log函数,当 y = 0 y=0 y=0时,此时损失函数为 L = − log ( 1 − y ^ ) L=-\text{log}\ (1-\hat{y}) L=−log (1−y^),这是log函数进行了平移,并且 y ^ \hat{y} y^的定义域为 0 ∼ 1 0 \sim 1 0∼1之间。
其实这就可以绘制出损失函数了,这样来了一个正样本,我们就可以通过这个函数计算出损失值,来了一个负样本,也可以计算出一个损失值,N个样本的损失值累计则为最终的loss。
当时很奇怪的一个点是,正负都合并到一个函数中了,为什么还会分0和1两种情况来绘制呢?其实y就相当于是一个超参数,只有确定了超参数才能确定最终的图像。举个例子
y = x 2 + 2 θ x + 1 y=x^2 + 2 \theta x +1 y=x2+2θx+1
我们假定 θ \theta θ只有-1和+1两种取值,现在要求你绘制 y y y的曲线,你会怎么做呢?肯定只有确定了 θ \theta θ才能绘制,因为 θ \theta θ就是一个超参数。
3.softmax求导
p ( w o ∣ w c ) p(w_o|w_c) p(wo∣wc)是概率模型,给定中心词 w w w,输出每个词的概率值,我们的目标就是最大化MLE损失
MLE = 1 T ∑ t = 1 T ∑ − l ≤ j ≤ l , j ≠ 0 log p ( w t + j ∣ w t ) \text{MLE} =\frac{1}{T} \sum_{t=1}^{T}\sum_{-l\leq j \leq l,j \neq 0 } \text{log}\ p(w_{t+j}|w_t) MLE=T1t=1∑T−l≤j≤l,j=0∑log p(wt+j∣wt)
通常在最后一层会使用softmax来进行归一化
p θ ( o ∣ c ) = u θ ( o , c ) ∑ o ′ ∈ V u θ ( o ′ , c ) = u θ ( o , c ) Z θ ( c ) p_{\theta}(o|c)=\frac{u_{\theta}(o,c)}{\sum_{o'\in V}u_{\theta}(o',c)}=\frac{u_{\theta}(o,c)}{Z_\theta(c)} pθ(o∣c)=∑o′∈Vuθ(o′,c)uθ(o,c)=Zθ(c)uθ(o,c)
其中 u θ ( o , c ) = e s θ ( o , c ) u_{\theta}(o,c)=e^{s_{\theta}(o,c)} uθ(o,c)=esθ(o,c),如果我们使用神经网络,我们用 v c ⃗ \vec{v_c} vc表示中心词向量,使用 u o ⃗ \vec{u_o} uo表示输出词向量。这两个向量的点积表征了两个词的相似度, s θ ( o , c ) = u o ⃗ ⋅ v c ⃗ s_{\theta}(o,c)=\vec{u_o}\cdot \vec{v_c} sθ(o,c)=uo⋅vc
但是这就有一个问题,我们的损失函数中包含了一个复杂的 Z θ Z_{\theta} Zθ,这求导起来非常的麻烦,也仅仅是麻烦而已
∇ θ log p θ ( o ∣ c ) = ∇ θ log u θ ( o , c ) − ∇ θ l o g ∑ u θ ( o ′ , c ) = ∇ θ s θ ( u o ⃗ , v c ⃗ ) − 1 ∑ u θ ( o ′ , c ) ∑ u θ ( o ′ , c ) ∇ θ s θ ( u o ′ ⃗ , v c ⃗ ) = ∇ θ s θ ( u