从感知器开始
开始学习ANN了,把学习中的点滴成长记录下来。
从Ronny的博客看起,实践了他第一篇ANN的文章《神经网络:感知器与梯度下降》。
程序是照着样子写的。因为代码并不是100%,所以也费了周折。主要是几个变量的定义没交代清楚,需要猜一下。
对那个结果做一点点小的议论吧。
对于需要进行分类的那个问题,如果不考虑偏置项,训练的结果是可以解析的获得的:
w1=-1.09861
w2=0
w3=1.09861
w4=43.74911(此时能与1的误差小于10-20).
考虑偏执项则得到类似的关系:
w1+w0=-1.09861
w2+w0=0
w3+w0=1.09861
w4+w0=43.74911
所以最优解从四维空间的一个点变成五维空间的一条线了。
有了这个,可以通过观察w的变化而直到神经网络的收敛情况。如果想了解神经网络的一些调试特性,可以通过观察w的变化来进行。
当然对于实际的问题,是不可能得到这样精确的解析解的,所以只是一个机会观察一下收敛的性能,并把握收敛的情况。
除此之外,Ronny用了 15K个点做训练,但是我的结果并不是特别好。学习因子选到0.32是ABB表现的比较好的一次。
我尝试了只用150个点来做区分结果,但是迭代了100次。发现样本从15K变到150,获得了样本内更好的结果。当然这也有可能是过拟合造成的。
void getSamplesData();//初始化过程 void initialWgt(); void cmtForward(const vector<double>& inVect); void updataWgt(const vector<double>& inVect, const double true_output, const double actual_output1);
初始化的部分可以这样写:
void getSamplesData() { const int iterations=15000; for(int j=0;j<100;j++) { if(j==0) { for( int i =0; i<iterations/100;i++) { int index=i%4; vector<double> dvect(4,0); dvect[index]=1; true_output.push_back((index+1)/4.0); for (size_t i=0; i!=dvect.size();i++) { dvect[i]+=(5e-3*rand()/RAND_MAX -2.5e-3); } inputData.push_back(dvect); } } else { for(int i=0;i<150;i++) { inputData.push_back(inputData[i]); true_output.push_back(true_output[i]); } } } }