深度学习与自然语言处理(4)_斯坦福cs224d 大作业测验1与解答 | 数盟社区

作业内容翻译:@胡杨(superhy199148@hotmail.com) && @胥可(feitongxiaoke@gmail.com)
解答与编排:寒小阳 && 龙心尘
时间:2016年6月
出处:
http://blog.csdn.net/han_xiaoyang/article/details/51760923
http://blog.csdn.net/longxinchen_ml/article/details/51765418

说明:本文为斯坦福大学CS224d课程的中文版内容笔记,已得到斯坦福大学课程@Richard Socher教授的授权翻译与发表

0 前言

前面一个接一个的Lecture,看得老衲自己也是一脸懵逼,不过你以为你做一个安安静静的美男子(总感觉有勇气做deep learning的女生也是一条汉纸)就能在Stanford这样的学校顺利毕业啦?图样图森破,除掉极高的内容学习梯度,这种顶尖大学的作业和考试一样会让你突(tong)飞(bu)猛(yu)进(sheng)。

说起来,怎么也是堂堂斯坦福的课,这种最看重前言研究在实际工业应用的学校,一定是理论和应用并进,对动手能力要求极强的,于是乎,我们把作业和小测验(MD你这也敢叫小测验!!)也扒过来,整理整理,让大家都来体验体验。反正博主君自己每次折腾完这些大学的assignment之后,都会感慨一句,“还好不生在水生火热的万恶资本主义国家,才能让我大学和研究僧顺利毕业(什么?phd?呵呵…博主是渣渣,智商常年处于欠费状态,我就不参与你们高端人士的趴体了)”。

不能再BB了,直接开始做作业考试吧…

1 Softmax (10 分)

(part a) (5分)
证明针对任何输入向量x和常数c,softmax函数的输出不会随着输入向量偏移(也就是常数c)而改变。即:

softmax(x)=softmax(x+c)

其中x+c就是给x每一个元素加上常数c。注意:

softmax(x)i=exijexj

提示:在实际应用中,经常会用到这个性质。为了稳定地计算softmax概率,我们会选择c=maxixi。(即将x的每个元素减去最大的那个元素)。

博主:熬过了高中,居然又看见证明了,也是惊(ri)喜(le)万(gou)分(le),答案拿来!!!

解答:

证明,针对所有维度1idim(x)

(softmax(x+c))i=exp(xi+c)dim(x)j=1exp(xj+c)=exp(c)exp(xi)exp(c)dim(x)j=1exp(xj)=exp(xi)dim(x)j=1exp(xj)=(softmax(x))i

(part b) (5 分)
已知一个N行d列的输入矩阵,计算每一行的softmax概率。在q1_softmax.py中写出你的实现过程,并使用Python q1_softmax.py执行。

要求:你所写的代码应该尽可能的有效并以向量化的形式来实现。非向量化的实现将不会得到满分。

博主:简直要哭晕在厕所了,当年毕业设计也是加论文一星期都可以写完的节奏,这里一个5分的作业,还这么多要求…社会主义好…答案拿来!!!

2 神经网络基础(30分)

(part a) (3 分)
推导sigmoid函数的导数,并且只以sigmoid函数值的形式写出来(导数的表达式里只包含σ(x),不包含x)。证明针对这个问题没必要单独考虑x。方便回忆:下面给出sigmoid函数形式:

σ(x)=11+ex

旁白:我年纪轻轻干嘛要走上深度学习这条不归路,真是生无所恋了。

答案σ(x)=σ(x)(1σ(x))

(part b) (3 分)
当使用交叉熵损失来作为评价标准时,推导出损失函数以softmax为预测结果的输入向量θ的梯度。注意,

CE(y,y^)=iyilog(y^i)

其中y是一个one-hot向量,y^是所有类别的预测出的概率向量。(提示:你需要考虑y的许多元素为0,并且假设y仅有第k个类别是1)

答案:CE(y,y^)θ=y^y

或者等价于下面表达式,其中假设k是正确的类别

CE(y,y^)θ={y^i1,i=ky^i,otherwise

(part c) (6 分)
推导出单隐层神经网络关于输入x的梯度(也就是推导出Jx,其中J是神经网络的损失函数)。这个神经网络在隐层和输出层采用了sigmoid激活函数,y是one-hot编码向量,使用了交叉熵损失。(使用σ(x) 作为sigmoid梯度,并且你可以任意为推导过中的中间变量命名)


前向传播方程如下:

h=sigmoid(xW1+b1)y^=softmax(hW2+b2)

在编程问题中,我们假设输入向量(隐层变量和输出概率)始终是一个行向量。此处我们约定,当我们说要对向量使用sigmoid函数时,也就是说要对向量每一个元素使用sigmoid函数。Wibi(其中i=1,2)分别是两层的权重和偏移。

旁白:好好的100分总分,硬要被你这么5分6分地拆,人家5分6分是一道选择题,你特么是一整个毕业设计!!好吧,不哭,跪着也要把题目做完,代码写完。哎,博主还是太年轻,要多学习啊。

答案:令 z2=hW2+b2z1=xW1+b1x,于是可得:

δ1=CEz2=y^yδ2=CEh=δ1z2h=δ1WT2δ3=CEz1=δ2hz1=δ2σ(z1)CEx=δ3z1x=δ3WT

(part d) (2 分)
上面所说的这个神经网络有多少个参数?我们可以假设输入是Dx维,输出是Dy,隐层单元有H个。

旁白:还有part d!!!

答案: (Dx+1)H+(H+1)Dy.

(part e) (4 分) 在q2_sigmoid.py中补充写出sigmoid激活函数的和求它的梯度的对应代码。并使用python q2_sigmoid.py进行测试,同样的,测试用例有可能不太详尽,因此尽量检查下自己的代码。

旁白:如果博主没有阵亡,就在走向阵亡的路上…

(part f) (4 分)
为了方便debugging,我们需要写一个梯度检查器。在q2_gradcheck.py中补充出来,使用python q2_gradcheck.py测试自己的代码。

旁白:做到昏天黑地,睡一觉起来又是一条好汉…

(part g) (8 分)
现在,在q2 neural.py中,写出只有一个隐层且激活函数为sigmoid的神经网络前向和后向传播代码。使用python q2_neural.py测试自己的代码。

旁白:一入DL深似海…

3 word2vec(40分+5附加分)

(part a) (3分)
假设你得到一个关联到中心词c的预测词向量υc,并且这个词向量使用skip-gram方法生成,预测词使用的是softmax预测函数,它能够在word2vec模型中被找到。

y^o=p(o|c)=exp(μoυc)Ww=1exp(μwυc)(4)

式中,w代表第w个词,μw(w=1,,W)是词库中全体词汇的输出词向量。假设为交叉熵损失函数,且词o是被预测的词汇(noe-hot/独热模型的标记向量中第o个元素为1),求解预测词向量 υc的所对应的梯度。
提示:问题2中的标记法将有助于此问题的解答。比如:设y^为各个词汇使用softmax函数预测得到的向量,y为期望词向量,而损失函数可以表示为:

JsoftmaxCE(o,υc,U)=CE(y,y^)(5)

其中,U=[μ1,μ2,,μW]是全体输出向量形成的矩阵,确保你已经规定好你的向量和矩阵的方向。

旁边:是的,旁白我已经不知道写什么了,感谢党感谢祖国吧。

解答:y^为词汇softmax预测结果的列向量,y是同样形为列向量的独热标签,那么有:

Jυc=UT(y^y).

或者等同于:

Jυc=μi+w=1Wyw^μw

(part b) (3分)
条件仍然如前一题所描述,求解输出词向量μw的梯度(包括μo在内)

旁白:我还是安安静静在天朝搬砖吧

解答:

JU=υc(y^y)

或者等同于:

Jμw={(yw^1)υc,yw^,w=ootherwise

(part c) (6分)
仍然延续(part a)和(part b),假设我们使用为预测的向量υc使用负采样损失的计算方式,并且设定期望输出词为o。假设获得了K个负样例(词),并且被记为1,,K,分别作为这些样例的标签(o1,,K)。那么,对于一个给定的词o,将其输出向量记作μo。这里,负采样损失函数如下:

Jnegsample(o,υc,U)=log(σ(μoυc))k=1Klog(σ(μkυc))(6)

其中,σ()为sigmoid激活函数。

当你完成上述操作之后,尝试简要描述这个损失函数比softmax-CE损失函数计算更为有效的原因(你可以给出递增式的学习率,即,给出softmax-CE损失函数的计算时间除以负采样损失函数的计算时间的结果)。

注释:由于我们打算计算目标函数的最小值而不是最大值,这里提到的损失函数与Mikolov等人最先在原版论文中描述的正好相反。

旁白:突然想起来,小时候好焦虑,长大后到底去清华还是去北大,后来发现多虑了。我想如果当初走了狗屎运进了贵T大贵P大,也一定完不成学业。

解答:

JυcJμoJμk=(σ(μoυc)1)μok=1K(σ(μkυc)1)μk=(σ(μoυc)1)υc=(σ(μkυc)1)υc,for all k=1,2,,K

(part d) (8分)
试得到由skip-gram和CBOW算法分别算出的全部词向量的梯度,前提步骤和词内容集合[wordc-m,…,wordc-1,wordc,wordc+1,…,wordc+m]都已给出,其中,m是窗口的大小。将词wordk的输入和输出词向量分别记为υkμk
提示:可以随意使用函数F(o,υc)(其中o代表词汇)作为这一部分中JsoftmaxCE(o,υc,)Jnegsample(o,υc,)损失函数的占位符——你将在编程部分看到一个非常有用的抽象类,那意味着你的解决方法可以用这样的形式表达:F(o,υc)
回忆skip-gram算法,以c为中心周边内容的损失值计算如下:

Jskipgram(wordcmc+m)=mjm,j0F(wc+j,υc)(7)

其中,wc+j代表距离中心词的第j个词。
CBOW略有不同,不同于使用υc作为预测向量,我们以υ^为底,在CBOW中(一个小小的变体),我们计算上下文输入词向量的和:

υ^=mjm,j0υc+j(8)

于是,CBOW的损失函数定义为:

JCBOW(wordcmc+m)=F(wc,υ^)(9)

注释:为了符合υ^在诸如代码部分中的各种表达规范,在skip-gram方法中,令:υ^=υc

旁白:我诚实一点,这个部分真的是翻了课件抄下来的。

解答:为了表达得更为清晰,我们将词库中全部词汇的全部输出向量集合记作U,给定一个损失函数F,我们可以很容易获得以下引出结果:
F(wi,υ^)UF(wi,υ^)υ^
对于skip-gram方法,一个内容窗口的损失梯度为:

Jskipgram(wordcm,,c+m)UJskipgram(wordcm,,c+m)υcJskipgram(wordcm,,c+m)υj=mjm,j0F(wc+j,υc)U,=mjm,j0F(wc+j,υc)υc=0, for all jc.

同样地,对于CBOW则有:

JCBOW(wordcm,,c+m)UJCBOW(wordcm,,c+m)υjJCBOW(wordcm,,c+m)υj=F(wc,υ^)U,(using the definition of υ^ in the problem)=F(wc,υ^)υ^,for all j{cm,,c1,c+1,,c+m}=0,for all j{cm,,c1,c+1,,c+m}

(part e) (12分)
在这一部分,你将实现word2vec模型,并且使用随机梯度下降方法(SGD)训练属于你自己的词向量。首先,在代码q3_word2vec.py中编写一个辅助函数对矩阵中的每一行进行归一化。同样在这个文件中,完成对softmax、负采样损失函数以及梯度计算函数的实现。然后,完成面向skip-gram的梯度损失函数。当你完成这些的时候,使用命令:python q3_word2vec.py对编写的程序进行测试。
注释:如果你选择不去实现CBOW(h部分),只需简单地删除对NotImplementedError错误的捕获即可完成你的测试。

旁白:前方高能预警,代码量爆炸了!

(f) (4分) 在代码q3_sgd.py中完成对随即梯度下降优化函数的实现。并且在该代码中运行测试你的实现。

旁白:想到这篇文章有可能会被无数可以智商碾压我的大神看到,就脸一阵发烫。

(part g) (4分)
开始秀啦!现在我们将要载入真实的数据并使用你已经实现的手段训练词向量!我们将使用Stanford Sentiment Treebank (SST)数据集来进行词向量的训练,之后将他们应用到情感分析任务中去。在这一部分中,无需再编写更多的代码;只需要运行命令python q3 run.py即可。
注释:训练过程所占用的时间可能会很长,这取决于你所实现的程序的效率(一个拥有优异效率的实现程序大约需要占用1个小时)。努力去接近这个目标!
当脚本编写完成,需要完成对词向量的可视化显示。相应的结果同样被保存下来,如项目目录中的图片q3 word_vectors.png所示。包括在你作业中绘制的坐标图。简明解释最多三个句子在你的坐标图中的显示状况。
解答:


(part h) 附加题(5分)

在代码q3_word2vec.py中完成对CBOW的实现。注释:这部分内容是可选的,但是在d部分中关于CBOW的梯度推导在这里并不适用!

4 情感分析(20分)

现在,随着词向量的训练,我们准备展示一个简单的情感分析案例。随着词向量的训练,我们准备展示一个简单的情感分析。对于每条Stanford Sentiment Treebank数据集中的句子,将句子中全体词向量的平均值算作其特征值,并试图预测所提句子中的情感层次。短语的情感层次使用真实数值在原始数据集中表示,并被我们用以下5个类别来表示:

“超级消极”,“比较消极”,“中立”,“积极”,“非常积极”
对其分别进行从0到4的编码。在这一部分,你将学习用SGD来训练一个softmax回归机,并且通过不断地训练/调试验证来提高回归机的泛化能力。
(part a)(10分)
实现一个句子的特征生成器和softmax回归机。在代码q4_softmaxreg.py中完成对这个任务的实现,并运行命令python q4_ softmaxreg.py,对刚才完成的功能函数进行调试。

(part b)(2分)
解释当分类语料少于三句时为什么要引入正则化(实际上在大多数机器学习任务都这样)。
解答:为了避免训练集的过拟合以及对未知数据集的适应力不佳现象。

(part c)(4分)
q4 sentiment.py中完成超参数的实现代码从而获取“最佳”的惩罚因子。你是如何选择的?报告你的训练、调试和测试精度,在最多一个句子中校正你的超参数选定方法。 注释:在开发中应该获取至少30%的准确率。
解答:参考值为1e-4,在调试、开发和测试过程中准确率分别为29.1%,31.4%和27.6%

(d)(4分)绘出在训练和开发过程中的分类准确率,并在x轴使用对数刻度来对正则化值进行相关设置。这应该自动化的进行。包括在你作业中详细展示的坐标图q4_reg_acc.png简明解释最多三个句子在此坐标图中的显示情况。
解答:


注:转载文章均来自于公开网络,仅供学习使用,不会用于任何商业用途,如果侵犯到原作者的权益,请您与我们联系删除或者授权事宜,联系邮箱:contact@dataunion.org。转载数盟网站文章请注明原文章作者,否则产生的任何版权纠纷与数盟无关。
期待你一针见血的评论,Come on!

不用想啦,马上 "登录"  发表自已的想法.