深度学习神经网络纯C语言基础版
来源:互联网 发布:双拼域名交易 编辑:程序博客网 时间:2024/06/01 10:37
本文转载自:http://blog.csdn.net/calcular/article/details/47031417
当今Deep-Learning已经是火到一定境界了,深度学习神经网络(DNN)在计算机视觉领域的表现可谓见效非凡。当然,工程上运用了卷积神经网络来减少计算量而不是全连结的神经网络-这样计算量实在太大了。但是,对于神经网络来说计算量真的不是问题,因为它的结构能够确保它能够并行计算,一旦网络的每一个单元都能够独立的进行计算,每一层再多的连结也是同时进行计算的。期待硬件神经网络的发展。
下面手写了一套任意隐层数神经网络构建的C语言函数,能够方便移植到嵌入式设备中。该程序只是一个基于矩阵全连结形式的基础深度学习网络。运用的学习算法为随机梯度下降法,采用sigmoid函数作为激活函数。在少量样本拟合中表现不错。
-
-
-
-
-
-
-
-
-
-
-
- #ifndef _DNN_H
- #define _DNN_H
- #include<stdio.h>
- #include<math.h>
- #include <stdlib.h>
- #include <time.h>
- #define DNN_VEC 8 //输入训练组组数
- #define DNN_INUM 5 //输入维度
- double dnn_sig(double in){
- return 1.0/(1.0+exp(-1.0*in));
- }
- struct dnn_cell{
- double w[DNN_INUM];
- double wb;
- double in[DNN_INUM];
- double out;
- double error;
- double v;
- void SetCell_Default(){
- int i;
- for(i=0;i<DNN_INUM;i++){
- w[i]=0.000001;
- }
- wb=0.000001;
- v=0.001;
- }
- void SetCell_InitWeight(double Initial){
- int i;
- for(i=0;i<DNN_INUM;i++){
- w[i]=Initial;
- }
- wb=Initial;
- v=0.001;
- }
- void SetCell_InitAll(double Initial,double InV){
- int i;
- for(i=0;i<DNN_INUM;i++){
- w[i]=Initial;
- }
- wb=Initial;
- v=InV;
- }
- void SetCell_Precise(double *InW,double InWb,double InV){
- int i;
- for(i=0;i<DNN_INUM;i++){
- w[i]=InW[i];
- }
- wb=InWb;
- v=InV;
- }
- void SetIn(double *SIn){
- int i;
- for(i=0;i<DNN_INUM;i++){
- in[i]=SIn[i];
- }
- }
- double GetOut(){
- int i;
- double sum=0;
- for(i=0;i<DNN_INUM;i++){
- sum+=w[i]*in[i];
- }
- sum+=wb;
- out=dnn_sig(sum);
- return out;
- }
- void UpdateWeight(){
- int i;
- for(i=0;i<DNN_INUM;i++){
- w[i]-=v*error*out*(1-out)*in[i];
- }
- wb=v*error*out*(1-out);
- }
- void SetError(double InErr){
- error=InErr;
- }
- void SetSpeed(double InV){
- v=InV;
- }
- };
-
-
-
-
-
- double DNN_Cal(dnn_cell *incell,int deep,double *in)
- {
- double out=0;
- int dd=0,i,j,k,count=0;
- double tmp[DNN_INUM];
- for(i=0;i<DNN_INUM;i++) tmp[i]=in[i];
- for(j=0;j<deep-1;j++)
- {
- for(i=j*DNN_INUM;i<(j*DNN_INUM+DNN_INUM);i++)
- {
- incell[i].SetIn(tmp);
- incell[i].GetOut();
- count++;
- }
- k=0;
- for(i=j*DNN_INUM;i<(j*DNN_INUM+DNN_INUM);i++) {tmp[k]=incell[i].out; k++;}
- }
- incell[count].SetIn(tmp);
- out=incell[count].GetOut();
- return out;
- }
-
-
-
-
-
- double DNN_Train(dnn_cell *cell,int deep,double InMat[DNN_VEC][DNN_INUM],double *expect,int n)
- {
- double out,devi,sum;
- double de[DNN_VEC];
- int co=n,kp=-1;
- int i,j,k,tt,l;
- for(i=0;i<DNN_VEC;i++) de[i]=9.9;
- while(co--){
- kp=(int)(rand()*(double)(DNN_VEC)/RAND_MAX);
- out=DNN_Cal(cell,deep,InMat[kp]);
- devi=out-expect[kp];
- de[kp]=devi;
-
- tt=(deep-1)*DNN_INUM;
- cell[tt].error=devi;
- l=0;
- for(i=(deep-2)*DNN_INUM;i<tt;i++) {cell[i].error=cell[tt].error*cell[tt].out*(1-cell[tt].out)*cell[tt].w[l];l++;}
- for(j=deep-2;j>0;j--){
- l=0;
- for(i=(j-1)*DNN_INUM;i<j*DNN_INUM;i++){
- sum=0;
- for(k=j*DNN_INUM;k<(j+1)*DNN_INUM;k++){
- sum+=cell[k].error*cell[k].out*(1-cell[k].out)*cell[k].w[l];
- }
- cell[i].error=sum;
- l++;
- }
- }
- for(i=0;i<=(deep-1)*DNN_INUM;i++){
- cell[i].UpdateWeight();
- }
-
- for(i=0;i<=(deep-1)*DNN_INUM;i++){
- cell[i].SetSpeed(fabs(devi));
- }
-
- }
- sum=0;
- for(i=0;i<DNN_VEC;i++) sum+=fabs(de[i]);
- return sum/DNN_VEC;
- }
- #endif
具体调用示范如下:
- #include<iostream>
- #include"dnn.h"
- using namespace std;
- int main()
- {
- srand( (unsigned)time(NULL) );
- double expect[8]={0.23,0.23,0.23,0.23,0.83,0.83,0.83,0.83};
- double in[8][5]={1,2,3,4,5,
- 1.1,2.1,3,3.9,5,
- 0.8,2.2,3,4.2,5,
- 0.9,2.1,3,4,5,
- 5,4,3,2,1,
- 4.9,4.1,2.9,2,1,
- 5,4,3.1,2,1,
- 5,4,2.9,2.1,1
- };
- dnn_cell a[16];
- int i;
- for(i=0;i<16;i++) a[i].SetCell_InitAll(rand()*2.0/RAND_MAX-1,0.001);
- DNN_Train(a,4,in,expect,100000);
- double pp[5];
- while(1){
- for(i=0;i<5;i++) cin>>pp[i];
- cout<<DNN_Cal(a,4,pp)<<endl;
- }
- }
注意期望必须在0~1之间