时间有点空,就把还没updata的编程练习拿来做了(coursera上一期的课程作业)
神经网络,确实不是很好理解,但是磕磕绊绊还是完成了,回头再看看《机器学习》上比较系统的定义
以及《集体智慧编程》上搜索引擎章节的一个神经网络样例,我也算从门缝看了一眼屋内的精彩世界吧
废话就不多说了
样例还是上一个exercise的数字手写识别,不同的是这次用neural network来进行学习
neural network的关键(至少是我目前学到的关键)是Back propagation(反向传播)
与之相应的是正向传播,即是知道Theta后进行predict的过程,而这个过程在neural network的学习中也是很重要的
(neural network最基础的就不解释了,什么layer,perceptron……,毕竟这是笔记。。)
下图正向传播过程(相对要好理解一些,也比较简单)
下图是反向传播过程,底部是相关公式(简单吧,可是实现起来就很麻烦了,主要原因还是因为我是新手!)
整个练习的主要文件时nnCostFunction.m,但算法过程是一步一步实现的,记住是honor code,在上课的童鞋就不要Ctrl+C了
另:用了loop,因为“
We recommend implementing backpropagation using a for-loop
over the training examples if you are implementing it for the
first time.
”大神些就先别吐槽了
首先是下面这个公式的前半部分(没有进行regularization 的部分),J是costfunction用来衡量学习出来的和样例的匹配程度
X=[ones(size(X,1),1) X];
a2=(sigmoid(X*Theta1')); a2=[ones(size(a2,1),1) a2]; h=sigmoid(a2*Theta2'); J=0; for k=1:num_labels y_temp=(y==k); h_temp=h(:,k); J=J-(y_temp'*log(h_temp)+(1-y_temp)'*log(1-h_temp)); end J=J/m;
加上regularization 之后:
J=J+lambda/2/m*(sum(sum(Theta1.*Theta1))+sum(sum(Theta2.*Theta2)));
然后就是一个大loop对每个样例进行如下的一个过程:
1.正向传播:
z2=X(t,:)*Theta1'; a2=(sigmoid(z2)); a2=[1 a2]; z3=a2*Theta2'; a3=sigmoid(z3); [lp,p]=max(a3, [], 2); y_temp=[1:num_labels]==y(t);
2.反向传播:
Delta3(t,:)=a3-y_temp; z2=[0 z2]; Delta2_temp=Delta3(t,:)*Theta2.*sigmoidGradient(z2); Delta2_temp(1)=[]; Delta2(t,:)=Delta2_temp;
3.统计gradient,用如下公式
DDDelta1=DDDelta1+Delta2(t,:)'*X(t,:); DDDelta2=DDDelta2+Delta3(t,:)'*a2;
其实光给个公式和代码有些不厚道,但详细的一时半会也说不清楚
代码中有很多的细节需要自己去一步步实践才能体会到,比如对Delta3和Delta2的表示格式
只有真正去实现一次,你才能对neural network有更深的了解
最后在loop外根据
得到相应的grad,再用fmincg函数进行学习,迭代次数50次为宜
算法跑起来那是相当慢,所以为什么迭代次数50次就差不多了,最后试了一下400次,跑了估计得有20分钟,待会会给个结果的
有时间我会进行矩阵化,到时候可能会快很多吧,即使50次到现在也已经跑了快5分钟了。。。。。等等。。
下面是hidden layer的可视化结果(50次),根本看不出规律,这就是neural network的奇妙之处
50次的识别率为95.68%,因为随机的选择,可能会有1%以内的误差,可见识别率已经是相当高了
那么400次的结果如何呢:下面是400次的hidden layer可视化结果:可见变化的确是有,只是人为无法识别
神经网络产生的东西,往往人是难以理解的
识别率如何呢,高达
但我感觉这个已经overfit了,对新的测试样例表现可能不如50次的结果了
第一个neural network,说实话,收获很多,嗯,加油!