1、你好,想跟你要一下神经网络的代码,看到你之前解答过问题,谢谢了
// BP.cpp : Defines the entry point for the console application.
//该程序实现神经网络的BP算法,输入节点数,输出节点数,隐层数,隐层节点数任意,由用户决定。
//其中隐层数指的是总共层数包含输出层,比如说异或算法为2层,第一层节点数为2,第二层也即输出层节点数为1,输入点数为2 。
//但是该程序对异或算法实现并不理想,对多层多节点的神经网络有较好的结果
#include "stdafx.h"
#include "iostream.h"
#include <time.h>
#include <stdlib.h>
#include <fstream>
#include <math.h>
#include "stdio.h "
#define MAXCOUNT 1e5 //迭代训练次数上限 1的10的正5次幂
//精度0.001的随机浮点数,范围在-0.5——0.5
//rand()取0到32767,最大为2147483647. %模运算表示余数为0到1000之间,所以乘上浮点数0。001f就是0-1之间的数,再减去0.5,就是-0.5到+0.5
float randf()
{
return (float)((rand() % 1001) * 0.001f-0.5);
}
//高斯随机数产生函数
//这样生成的高斯分布随机数序列的期望为0.0,方差为1.0。若指定期望为E,方差为V,则只需增加:X = X * V + E;
double gaussrand()
{
static double V1, V2, S;
static int phase = 0;
double X;
if(phase == 0) {
do {
double U1 = (double)rand() / RAND_MAX;
double U2 = (double)rand() / RAND_MAX;
V1 = 2 * U1 - 1;
V2 = 2 * U2 - 1;
S = V1 * V1 + V2 * V2;
} while(S >= 1 || S == 0);
X = V1 * sqrt(-2 * log(S) / S);
} else
X = V2 * sqrt(-2 * log(S) / S );
phase = 1 - phase;
return X;
}
//定义一个多层前向BP网络
class BP
{
public:
double ***p;//记录所有的权值
double ***ddp;//记录所有的权值增量
int *pnode;//记录每一层的节点数
double **pnodey;//记录每组每一层的节点的输出值
double **ddlj;//记录每组每一层的节点的ddlj
double **pX; //记录输入样本
double **pY; //记录输入理想输出值
int Sidenum; //隐层数目
int Inputnodenum;
int outputnodenum;
int yangbenzushu;
BP()
{
Sidenum=0;
Inputnodenum=0;
outputnodenum=0;
yangbenzushu=0;
}
~BP()
{
for(int m=0;m<Sidenum;m++)
{
for(int n=0;n<pnode[m+1];n++)
{
delete[] p[m][n];
delete[] ddp[m][n];
}
delete[] p[m];
delete[] ddp[m];
}
delete[] p;
delete[] ddp;
p=NULL;
ddp=NULL;
if(p==NULL)
delete [] pnode;
for(int M=0;M<Sidenum;M++)
{
delete[] pnodey[M];
delete[] ddlj[M];
}
delete[] pnodey;
delete[] ddlj;
pnodey=NULL;
ddlj=NULL;
}
//完成所有权值的初始化
void getW(int sidenum,int inputnodenum,int outputnodenum1,int yangbenzu)
{
Sidenum=sidenum;
yangbenzushu= yangbenzu;//样本组数目
Inputnodenum=inputnodenum;
outputnodenum=outputnodenum1;
p=new double **[sidenum];//记录所有权值
ddp=new double **[sidenum];//权值增量
pnode=new int [sidenum+1];//包含输入层,输出层每一层的节点数.
for(int i=0;i<sidenum+1;i++)
{
int data=0;
cout<<"请输入第"<<i<<"层节点数"<<endl;
cin>>data;
pnode[i]=data;
}
for (int j=0;j<sidenum;j++) // 初始化权值, 不包含输入层,但是包含输出层.第0层表示第一个隐层
{
p[j]=new double* [pnode[j+1]]; //首先P[j]层有多少个节点,就有多少个指针,每个指针指向一个权值数组.因为p[j]是二级指针,存放的是某指针的地址,某指针可以指向一维数组.
ddp[j]=new double*[pnode[j+1]];//同上
for (int k=0;k<pnode[j+1];k++)
{
ddp[j][k]=new double[pnode[j]+1];//表示第j层的第k个节点指向的是一个数组,这个数组里存的是这个节点的权值.
p[j][k]=new double[pnode[j]+1];
for (int t=0;t<pnode[j]+1;t++) //pnode[j]+1 表示第j层的输入点个数.
{
ddp[j][k][t]=0;//每一层的权值初始化为0 表示的是第j层的第k个节点,第t个输入的输入权值.
if(t==0)p[j][k][t]=-fabs(randf());//每一层的阀值初始化 第0个元素.
else p[j][k][t]=randf();//每一层的权值初始化
}
}
}
//为记录每一层的节点的输出值和ddlj的指针开辟内存
pnodey=new double *[Sidenum]; //一共有Sidenum层.
ddlj=new double *[Sidenum];
for(int p=0;p<Sidenum;p++)
{
pnodey[p] = new double [pnode[p+1]+1];//每层一共有节点数+1个输出
ddlj[p]=new double [pnode[p+1]];// 这个是做什么的??
pnodey[p][0]=1;//每组每层的首值为1,这个值是为了与阈值相乘,这也是为什么会有上面+1个输出
}
}
/**********************/
//每个节点输出函数
double fas(double s)
{
double t;
t=1.0/(exp(-s)+1);
return t;
}
/************************************************/
//该函数用来记录样本值和理想输出值
void INPUT(int yangbenzushu1 )
{
pY=new double*[yangbenzushu1];//yangbenzushu1数量个理想输出
pX=new double*[yangbenzushu1];//yangbenzushu1数量个样本
for(int yu=0;yu<yangbenzushu1;yu++)
{
pX[yu]=new double[Inputnodenum+1];//每个样本的维数是输入点个数+1
pY[yu]=new double[outputnodenum+1];//输出的维数也是输出点个数+1
}
//每组样本的首值赋为1, 这样就可以使下标对应的比较好
for(int yu1=0;yu1<yangbenzushu1;yu1++)
{
pX[yu1][0]=1;
pY[yu1][0]=1;
}
cout<<"请输入样本输入值"<<endl;
for(int yuy=0;yuy<yangbenzushu1;yuy++)
for(int yy=1;yy<=Inputnodenum;yy++)
{
if(yy==Inputnodenum) cout<<endl;
cout<<"X["<<yuy<<"]"<<"["<<yy<<"]="<<' ';
cin>>pX[yuy][yy];
}
cout<<"请输入样本理想输出值"<<endl;
for(int yuy1=0;yuy1<yangbenzushu1;yuy1++)
for(int yy1=1;yy1<=outputnodenum;yy1++)
{ //if(yy==Inputnodenum) cout<<endl;
cout<<"Y["<<yuy1<<"]"<<"["<<yy1<<"]="<<' ';
cin>>pY[yuy1][yy1];
}
}
/****************************************************************************/
//计算每个节点的输出值
double computeYl(int KK)//KK代表第几组组号
{
double sum1=0;
//把所有的层的每一个节点的输出值算出来并记录在pnodey里,不包含输入点值
for(int y=0;y<Sidenum;y++)//层数
{
for(int r=1;r<pnode[y+1]+1;r++)//本节点数,加1是为了下标好看
{
double sum=0;
for(int z=0;z<pnode[y]+1;z++)//前一层的节点数
{
if(y==0)sum+= pX[KK][z]*p[y][r-1][z];
else
sum+=pnodey[y-1][z]*p[y][r-1][z];
}
pnodey[y][r]=fas(sum);
}
}
for(int j=1;j<=outputnodenum;j++)
sum1+=pow(pY[KK][j]-pnodey[Sidenum-1][j],2);
return sum1;
}
/**********************************************************/
//Compute Back-Propagation-Errors
void ComputeBackPropagationErrors(int gf)//gf代表组号
{//计算所有的ddlj[][]
//for(int gf=0;gf<yangbenzushu;gf++)//组数
for(int q=Sidenum-1;q>=0;q--)//从最后一层开始
{
if(q==Sidenum-1)//如果是最外一层的话
{
for(int rt=0;rt<pnode[q+1];rt++)//每层的节点数
ddlj[q][rt]=pnodey[q][rt+1]*(1-pnodey[q][rt+1])*(pY[gf][rt+1]-pnodey[q][rt+1]) ;
}
else
{
for(int ry=0;ry<pnode[q+1];ry++)
{
double sumtemp=0;
for(int fg=0;fg<pnode[q+2];fg++)
sumtemp+=ddlj[q+1][fg]*p[q+1][fg][ry+1];
ddlj[q][ry] = pnodey[q][ry+1]*(1-pnodey[q][ry+1])* sumtemp;
}
}
}
//计算所有的ddp[][]
//for(int gf1=0;gf1<yangbenzushu;gf1++)//组数
for(int l=0;l<Sidenum;l++)//层数
for(int JJ=0;JJ<pnode[l+1];JJ++)//每一层的节点数
for(int i=0;i<pnode[l]+1;i++)//前一层的节点数
{
if(l==0)//如果是第一层的话,y值为输入的X值
ddp[l][JJ][i]=ddlj[l][JJ]*pX[gf][i];
else
ddp[l][JJ][i]=ddlj[l][JJ]*pnodey[l-1][i];
}
}
/*************************************************************************/
void UpdatetheWeightsusingBPAlgorithm()
{
for(int cent=0;cent<Sidenum;cent++)//层数
for(int J=0;J<pnode[cent+1];J++)//每一层的节点数
for(int i=0;i<pnode[cent]+1;i++)//前一层的节点数
p[cent][J][i]+=0.2*ddp[cent][J][i];
}
/***************************************************************************/
double xunlianErrors()//定义训练误差函数
{
double error=0;
double sum=0;
double temp=0;
double temp1=0;
for(int gf1=0;gf1<yangbenzushu;gf1++)//组数
{
temp= computeYl(gf1);
//temp1=zhengquelv(gf1);
//sum+=temp1;
for(int jj=1;jj<=outputnodenum;jj++)
cout<<pnodey[Sidenum-1][jj];
error+=temp;
}
// sum=sum/yangbenzushu;
cout<<"用训练集所得到的正确率:"<<sum<<endl;
return error/yangbenzushu;
}
/****************************************************************************/
double jiaoyanErrors(int yangbenzushu1 )//定义校验误差函数
{
double error=0;
double sum=0;
double temp=0;
double temp1=0;
for(int gf1=0;gf1<yangbenzushu1;gf1++)//组数
{
temp= computeYl(gf1);
for(int jj=1;jj<=outputnodenum;jj++)
cout<<pnodey[Sidenum-1][jj];
//temp1=zhengquelv(gf1);
//sum+=temp1;
error+=temp;
}
//sum=sum/yangbenzushu1;
//cout<<"用校验集所得到的正确率:"<<sum<<endl;
return error/yangbenzushu1;
}
/********************************************************************/
double zhengquelv(int KK)
{
int count=0;
double av=0;
//for(int gf1=0;gf1<yangbenzushu;gf1++)//组数
for(int jj=1;jj<=outputnodenum;jj++)
{
if (pnodey[Sidenum-1][jj]>0) pnodey[Sidenum-1][jj]=1;
else pnodey[Sidenum-1][jj]=0;
if(pY[KK][jj]==pnodey[Sidenum-1][jj])count++;
}
av=(double)count/outputnodenum;
return av;
}
/***********************************************************************/
void freeINput()
{
if(pX!=NULL)
{
for(int u=0;u<yangbenzushu;u++)
delete []pX[u];
delete []pX;
pX=NULL;
}
if(pY!=NULL)
{
for(int u1=0;u1<yangbenzushu;u1++)
delete []pY[u1];
delete []pY;
pY=NULL;
}
}
/***************************************************************/
//输出所有的权值
void wputout()
{
for (int j=0;j<Sidenum;j++)
{
cout<<"第["<<j+1<<"]层权值为:"<<endl;
for (int k=0;k<pnode[j+1];k++)
{
//if(k==pnode[j+1]-1) cout<<endl;
for (int t=0;t<pnode[j]+1;t++)
{
cout<<p[j][k][t]<<' ';
if(t==pnode[j]) cout<<endl;
}
}
}
}
/**********************************************************/
};
void main()
{
BP bp;
int count=0;//用来统计所用的迭代次数
//FILE *fp;
int inputnodenum,outnodenum,sidenum,yangbenzunum;
double error;
cout<<"请输入:输入点数,输出点数,隐层数"<<endl;
cin>>inputnodenum>>outnodenum>>sidenum;
cout<<"请输入样本组数"<<endl;
cin>>yangbenzunum;
//第一步初始化所有的权值
bp.getW(sidenum,inputnodenum,outnodenum,yangbenzunum);
//第二步输入样本组
bp.INPUT(yangbenzunum);
for(;;count++)
{
double sum=0;
double temp=0;
for(int fuzu=0;fuzu<yangbenzunum;fuzu++)
{
//第三步计算所有y值
temp=bp.computeYl(fuzu);
//第四步Compute Back-Propagation-Errors
bp.ComputeBackPropagationErrors(fuzu);
//第五步Update the Weights using BP Algorithm
bp.UpdatetheWeightsusingBPAlgorithm();
sum+=temp;
}
//第六步判断是否收敛
error=sum/2*yangbenzunum;
//freopen("debug\\out.txt","w",stdout);
//fp=freopen( "out.txt", "w", stdout) ;
// cout<<count<<' '<<error<<endl;
// fclose(stdout);//关闭文件
/*if(count==1000)cout<<error<<endl;
if(count==1500)cout<<error<<endl;
if(count==1600)cout<<error<<endl;*/
//if(count==10000)cout<<error<<endl;
if(error<1.02)
{
cout<<"循环收敛"<<"迭代次数为:"<<count<<endl;
//bp.freeINput();//释放X Y空间
break;
}
}
cout<<"权值为:"<<endl;
bp.wputout();
double XUNLIANER=bp.xunlianErrors();
//cout<<"训练误差为:"<<XUNLIANER<<endl;
bp.freeINput();//释放X Y空间
/*
cout<<"请输入校验样本: "<<endl;
int jiaoyannum=0;
cin>>jiaoyannum;
bp.INPUT(jiaoyannum);
double jiaoyanER=bp.jiaoyanErrors(jiaoyannum);
cout<<"校验误差为:"<<jiaoyanER<<endl;
//fclose( stdout ) ;*/
}
谷歌人工智能写作项目:小发猫
2、qnn是什么意思网络用语
神经网络(QNN)的方法,在运行时具有极低精度(例如1bit)权重和激活的神经网络参考:一个技术宅的学习笔记。在训练时期,量化的权重和激活值被用于计算参数梯度。在前向传递期间,QNN大大减少了内存大小和访问,并用按位运算代替了大多数算术运算。结果,预期功耗将大大降低。我们通过MNIST,CIFAR-10,SVHN和ImageNet数据集训练了QNN。由此产生的QNN可以达到与32-bit同类网络相当的预测精度。例如,我们的AlexNet量化版本具有1-bit权重和2-bit激活,可实现51%的top-1准确性。此外,我们还将参数梯度量化为6-bit,这使得仅使用按位运算就可以进行梯度计算。在Penn Treebank数据集上对量化的递归神经网络进行了测试,并仅使用4-bit就获得了与32-bit相当的准确性。最后但并非最不重要的一点是,我们对二进制矩阵乘法GPU内核进行了编程,与未优化的GPU内核相比,使用它可以使MNIST QNN的运行速度快7倍,而不会降低分类精度。 QNN代码已开源。
3、求一段神经网络MATLAB代码 50
function [presim ss net] = simnonlin( y,d,n )
% y-- 时间序列数据,列向量
% d-- 时间延迟参数,正整数
% n--用于训练的点的个数,正整数
trainset = gettrain(y,d);
inputs = trainset(:,1:end-1)';
targets = trainset(:,end)';
net = feedforwardnet(20,'trainscg');
% net = newff(inputs,targets,40);
% net = train(net,inputs,targets);
net=train(net,inputs,targets);
presim(1:d)=y(end-d+1:end);
for i = d+1:d + n
presim(i) = sim(net,presim(i-d:i-1)');
end
ss = presim(d+1:end)';
end
调用示例:
t=[1:100]';
y = exp(-0.1*t).*sin(t);
d=10;
n=80;
sim = simnonlin( y,d,n );
4、BP神经网络预测代码 15
你这是在做时间序列呢。
你可以去《神经网络之家》nnetinfo----》学习教程二--->神经网络在时间序列上的应用
上面有讲解。我把代码摘抄给你
% time series:神经网络在时间序列上的应用
% 本代码出自《神经网络之家》
timeList = 0 :0.01 : 2*pi; %生成时间点
X = sin(timeList); %生成时间序列信号
%利用x(t-5),x(t-4),x(t-3),x(t-2),x(t-1)作为输入预测x(t),将x(t)作为输出数据
inputData = [X(1:end-5);X(2:end-4);X(3:end-3);X(4:end-2);X(5:end-1)];
outputData = X(6:end);
%使用用输入输出数据(inputData、outputData)建立网络,
%隐节点个数设为3.其中隐层、输出层的传递函数分别为tansig和purelin,使用trainlm方法训练。
net = newff(inputData,outputData,3,{'tansig','purelin'},'trainlm');
%设置一些常用参数
net.trainparam.goal = 0.0001; %训练目标:均方误差低于0.0001
net.trainparam.show = 400; %每训练400次展示一次结果
net.trainparam.epochs = 1500; %最大训练次数:15000.
[net,tr] = train(net,inputData,outputData);%调用matlab神经网络工具箱自带的train函数训练网络
simout = sim(net,inputData); %调用matlab神经网络工具箱自带的sim函数得到网络的预测值
figure; %新建画图窗口窗口
t=1:length(simout);
plot(t,outputData,t,simout,'r')%画图,对比原来的输出和网络预测的输出
%------------------附加:抽取数学表达式----------------------------top
%希望脱离matlab的sim函数来使用训练好网络的话,可以抽取出数学的表达式,|
%这样在任何软件中,只需要按表达式计算即可。 |
%============抽取数学表达式==================
%抽取出网络的权值和阈值
w12 = net.iw{1,1}; %第1层(输入层)到第2层(隐层)的权值
b2 = net.b{1}; %第2层(隐层)的阈值
w23 = net.lw{2,1}; %第2层(隐层)到第3层(输出层)的权值
b3 = net.b{2}; %第3层(输出层)的阈值
%由于有归一化,必须先将归一化信息抓取出来
iMax = max(inputData,[],2);
iMin = min(inputData,[],2);
oMax = max(outputData,[],2);
oMin = min(outputData,[],2);
%方法1:归一化--->计算输出--->反归一化
normInputData=2*(inputData -repmat(iMin,1,size(inputData,2)))./repmat(iMax-iMin,1,size(inputData,2)) -1;
tmp = w23*tansig( w12 *normInputData + repmat(b2,1,size(normInputData,2))) + repmat(b3,1,size(normInputData,2));
myY = (tmp+1).*repmat(oMax-oMin,1,size(outputData,2))./2 + repmat(oMin,1,size(outputData,2));
%方法2:用真正的权值和阈值进行计算
%公式请参考《提取对应原始数据的权重和阈值》
W12 = w12 * 2 ./repmat(iMax' -iMin',size(w12,1),1);
B2 = -w12* (2*iMin ./(iMax - iMin) + 1) + b2;
W23 = w23 .*repmat((oMax -oMin),1,size(w23,2))/2;
B3 = (oMax -oMin) .*b3 /2 + (oMax -oMin)/2 + oMin;
%最终的数学表达式:
myY2 = W23 *tansig( W12 *inputData + repmat(B2,1,size(inputData,2))) + repmat(B3,1,size(inputData,2));