深度学习实验系列(1)
开篇粘贴导师的几句话:
要学习深度学习,多少要了解一下神经网络,神经网络的典型就是BP,而BP本身是很简单的。
引例:判断一个人是否长得帅??? 有如下feature: 身高,体重,三围,颜值,学习成绩(帅的人学习成绩好的少...为何如此说先不讨论,本人作为女生,认为此说法并无什么依据)等等。
假设有一个标准:每一个评分项给予多少分的权重,当所有feature与权重相乘的和大于某一个值的时候,那这个人就是帅哥!!
例子: 180*5+150*3+....>1000 帅哥! 小于则.....
感知器任务:通过已知的实例调节权重,使其能够预测出未知实例的结果。
符号表示:
if (w1*x1+w2*x2+.......>b) return true
else return false
由于b是常数,我们可以将b表示为-w0×X0,则可以表示为
if (w1*x1+w2*x2+.......+w0×x0>0) return true
else return false
训练方法:
当预测值等于我们期待的结果时: 什么也不用做
但当预测值小于我们期待的结果时,说明我们增加的权值小了,应补上一个正数数,例如所有xi*×2的和数学表达推导如下:
w1*x1+a*x1*x1+w2*x2+a*x2*x2+...... 注:a为学习速率因子,会影响学习速率
w的更新值相当于wi=wi+a*xi
当预测值大于我们期待的结果时应改为减号,归结起来应为如下表达式:wi=wi+a*(y-h(x))*xi
伪代码表示:
1 while(循环结束条件) {#此处可设为让样本循环执行多少次 2 delta_w[ ]={0}; 3 for(每个样本){ 4 for(每个特征 i){ 5 delta_w[i]+=a*(y-h(x))*wi; 6 } 7 } 8 for(每个特征 i){ 9 更新w权值 10 wi+=dealta_w[i] 11 } 12 }
shortage:
只能解决线性可分问题。
questions:
1.迭代的停止条件是什么?
答:自己定。。。可以是某个验证集取得理想结果的时候,或是像上述例子,单纯改变循环次数。
2.当训练时候遇到正确样本会发生什么?
答:什么也不发生,当预测结果正确时,就假定是最好感知器。
3.每次迭代调整w或是所有样本迭代完全后调整w(上例)有区别么?
答:区别不大,也许w权值会有所变化,但实际效果没多大区别。
4.某轮迭代后结果一定变好么?
答:不一定,但总体趋势是变好的!
5.a的作用和取值问题
答:作用是控制学习速率,一般选0-1之间,过大不能学习到最优值,过小没有什么变化~~
下面给出具体的C语言实现代码:
#include<iostream> #include <stdio.h> using namespace std; double hypothose(double w[],int feature_num,double* training_set){ double sum=0; for(int i=0;i<feature_num;i++){ sum+=w[i]*training_set[i]; } if (sum>0) return 1; else return 0; } //以下函数为感知器算法真正函数,参数分别是特征个数,训练样本数,学习速率,迭代次数,训练样本,初始w数组 void perception(int feature_num,int training_num,double a,int times,double** training_set,double w[]){ int dimentions=feature_num+1; while(times--){ double* delta_w=new double[feature_num]; for(int i=0;i<feature_num;i++){ delta_w[i]=0; } for(int i=0;i<training_num;i++){ for(int j=0;j<feature_num;j++){ delta_w[j]+=(training_set[i][feature_num]-hypothose(w,feature_num,training_set[i]))*training_set[i][j]*a; } } for(int i=0;i<feature_num;i++){ w[i]+=delta_w[i]; } delete[] delta_w; } } int main(){ int feature_num,training_num,times; double a; freopen("in.txt","r",stdin); while(cin>>feature_num>>training_num>>a>>times){ double** training_set=new double*[ training_num]; for(int i=0;i<training_num;i++){ training_set[i]=new double[training_num+2]; } double* w=new double[feature_num+1]; for(int i=0;i<training_num;i++){ training_set[i][0]=1; } for(int i=0;i<training_num;i++){ for(int j=1;j<=feature_num+1;j++){ cin>>training_set[i][j]; } } for(int i=0;i<=feature_num;i++){ cin>>w[i]; } perception(feature_num+1,training_num,a,times,training_set,w); for(int i=0;i<feature_num;i++){ cout<<w[i]<<' '; } cout<<w[feature_num]<<endl; delete[] w; for(int i=0;i<training_num;i++){ delete[] training_set[i]; } delete[] training_set; } return 0; }
文件输入格式如下:
2 4 0.25 5
0 0 0
0 1 1
1 0 1
1 1 1
0.06230 0.01123 -0.07335
运行结果:(我的编译环境是vs2013)