深度学习神经网络纯C语言基础版

当今Deep-Learning已经是火到一定境界了,深度学习神经网络(DNN)在计算机视觉领域的表现可谓见效非凡。当然,工程上运用了卷积神经网络来减少计算量而不是全连结的神经网络-这样计算量实在太大了。但是,对于神经网络来说计算量真的不是问题,因为它的结构能够确保它能够并行计算,一旦网络的每一个单元都能够独立的进行计算,每一层再多的连结也是同时进行计算的。期待硬件神经网络的发展。

下面手写了一套任意隐层数神经网络构建的C语言函数,能够方便移植到嵌入式设备中。该程序只是一个基于矩阵全连结形式的基础深度学习网络。运用的学习算法为随机梯度下降法,采用sigmoid函数作为激活函数。在少量样本拟合中表现不错。

/*
	深度学习神经网络V1.0
		made by xyt
		2015/7/23
	   使用语言:C

本程序构建多层矩阵形神经网络多输入单输出
学习策略:随机梯度下降
激活函数:sigmoid
使用前必须用srand((unsigned)time(NULL))取随机映射初始值
*/
#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){  //sigmoid函数,此处不可变
	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;
	}
};
/*  获得前向传播得到的输出值,第一个参数为神经元结构体数组,第二个参数为神经网络
层数。具体排列为:前0~DNN_INUM神经元为第一层,后面每DNN_INUM个神经元为一层,依次
排列,直至最后一个输出神经元为单独一层,如果层数是4,DNN_INUM=5(5输入)则神经元
数量应为(4-1)*5+1=16个。*in参数为输入网络的具有DNN_INUM个数据的数组
*/
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;
}
/*
    对输入矩阵训练,最后得到更新的神经网络,要求每组数据量限定为DNN_INUM数据组数限定为DNN_VEC
输入神经原组为按层排列,除了最后一层的节点数为一其他节点数都限定为输入向量DNN_INUM
deep为网络层数至少2层,算上最后输出层,n为训练次数,expect为期望,返回训练后平均误差
*/
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;
		printf("%lf  %lf  %lf  %d\n",fabs(de[0]),fabs(de[3]),fabs(de[7]),kp);
		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之间

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-25 00:33:10

深度学习神经网络纯C语言基础版的相关文章

Spark MLlib Deep Learning Neural Net(深度学习-神经网络)1.2

Spark MLlib Deep Learning Neural Net(深度学习-神经网络)1.2 http://blog.csdn.net/sunbow0/ 第一章Neural Net(神经网络) 2基础及源码解析 2.1 Neural Net神经网络基础知识 2.1.1 神经网络 基础知识参照: http://deeplearning.stanford.edu/wiki/index.php/%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C 2.1.2 反向传导算法

Spark MLlib Deep Learning Neural Net(深度学习-神经网络)1.3

Spark MLlib Deep Learning Neural Net(深度学习-神经网络)1.3 http://blog.csdn.net/sunbow0/ 第一章Neural Net(神经网络) 3实例 3.1 测试数据 3.1.1 测试函数 采用智能优化算法的经典测试函数,如下: (1)Sphere Model 函数表达式 搜索范围 全局最优值 函数简介:此函数为非线性的对称单峰函数,不同维之间是不可分离的.此函数相对比较简单,大多数算法都能够轻松地达到优化效果,其主要用于测试算法的寻优

Spark MLlib Deep Learning Neural Net(深度学习-神经网络)1.1

Spark MLlib Deep Learning Neural Net(深度学习-神经网络)1.1 http://blog.csdn.net/sunbow0/ Spark MLlib Deep Learning工具箱,是根据现有深度学习教程<UFLDL教程>中的算法,在SparkMLlib中的实现.具体Spark MLlib Deep Learning(深度学习)目录结构: 第一章Neural Net(NN) 1.源码 2.源码解析 3.实例 第二章Deep Belief Nets(DBNs

R语言︱H2o深度学习的一些R语言实践——H2o包

R语言H2o包的几个应用案例 笔者寄语:受启发想了解H2o平台的一些R语言实现,网上已有一篇H2o的demo文件.笔者在这多贴一些案例,并且把自己实践的一些小例子贴出来. 关于H2o平台长啥样,可以看H2o的官网,关于深度学习长啥样,可以看一些教程,比如ParallelR博客之中的解析. 下面主要是贴几个案例,让大家看看. ------------------------------------------------------------ Matt︱R语言调用深度学习架构系列引文 R语言︱H

单片机学习之:C语言基础——宏定义(#define)

例如: #define uint unsigned int //用uint来代替(表示)unsigned int,语句前有#,后面无须加分号“;” uint可为除关键字以外的任意字符,以方便书写.同理:#define uchar unsigned char 单片机学习之:C语言基础--宏定义(#define)

单片机学习之:C语言基础——if 用法

//========if 用法(一)========= //*用法格式: if (表达式)    语句; //if判断语句,若表达式为真,则执行语句,否则不执行.且if仅能控制一条语句. ×××××××××××××××××××××××××××××××××× //==========if 用法(二)=============//用法格式: if (表达式)    {        语句1;        语句2;        语句N;    }  //if判断语句,若表达式为真,则执行大括号内所

单片机学习之:C语言基础——while循环

=======while循环用法======语法格式: while(表达式) { 循环体; } 功能:进入while语句后,反复判断表达式真假,若为真(为假则跳出循环),则执行循环体内语句. 实例: #include<stdio.h>int main(){ int i = 0; while(i < 5) { printf("i = %d\n",i); i++; } return 0;} 在VC++6.0中输出结果为: i = 0i = 1i = 2i = 3i = 4

单片机学习之:C语言基础——for循环及for嵌套

==========for循环及for嵌套=========- for循环语法格式: for(表达式1;表达式2;表达式3) { 循环体; } //功能:进入for语句时,先执行表达式1(只执行一次!),然后对表达式2进行真假判断,若为真(若为假则退出for循环),则执行一次循环体内容,后执行表达式3,表达式3执行完之后,重新对表达式2进行真假判断. 例如: #include<stdio.h>int main(){ int x; for(x=0; x<5; x++) { printf(&

Tensorflow深度学习之十二:基础图像处理之二

Tensorflow深度学习之十二:基础图像处理之二 from:https://blog.csdn.net/davincil/article/details/76598474 首先放出原始图像: 1.图像的翻转 import tensorflow as tf import cv2 # 这里定义一个tensorflow读取的图片格式转换为opencv读取的图片格式的函数 # 请注意: # 在tensorflow中,一个像素点的颜色顺序是R,G,B. # 在opencv中,一个像素点的颜色顺序是B,