最近在看BP神经网络 ,也在看MFC,于是想到,如果做一个bp神经网络的界面 ,怎么做呢?代码如下 5
include<iostream>#include<fstream>#include<math.h>#include<ctime>usingnamespacestd;co...
include <iostream>
#include <fstream>
#include <math.h>
#include <ctime>
using namespace std;
const int N = 6; //样本数
const int NI = 2; //输入层节点数
const int NH = 2; //隐层节点数
const int NO = 1; //输出层节点数
const double T = 0.01; //误差最小值
const double ETA = 0.5; //学习效率
double w[NI][NH]; //输入层到隐层的权值
double ww[NH][NO]; //隐层到输出层的权值
double deltaO[NO]; //输出节点的局部梯度
double deltaH[NH]; //隐层节点的局部梯度
double vH[NH],vO[NO]; //各层节点的输出
double uH[NH],uO[NO]; //各层节点的输入
double yuH[NH], yuO[NO]; //隐层和输出层的阈值
//样本数据
double X[N][NI]={{1,1}, {2,2}, {-1,-1}, {1,-1}, {-1,1},{-2,2}};
double Y[N][NO]={0,0,0,1,1,1};
//Sigmoid函数
double f(double x){
return 1/(1+exp(-x));
}
//Sigmoid函数的一阶导数
double ft(double x){
return exp(-x)/((1+exp(-x))*(1+exp(-x)));
}
//初始化网络权值
void initital(){
srand((unsigned int)time(NULL));
int i,j,flag =1.5;
for(j=0;j<NH;j++){
yuH[j] = (double)(((double)rand()/RAND_MAX)*2-1); //-1~1之间的随机数
for( i=0;i<NI;i++)
w[i][j] = (double)(((double)rand()/RAND_MAX)*2-1);
}
for(j=0;j<NO;j++){
yuO[j] = (double)(((double)rand()/RAND_MAX)*2-1);
for( i=0;i<NH;i++)
ww[i][j] = (double)(((double)rand()/RAND_MAX)*2-1);
}
}
int main(){
initital();
int i,j,k;
int t = 5000; //最大学习次数
while(t--){
double E = 0;
for(int p=0;p<N;p++){ //枚举全部样本
memset(deltaO,0,sizeof(deltaO));
memset(deltaH,0,sizeof(deltaH));
memset(uH,0,sizeof(uH));
memset(uO,0,sizeof(uO));
//前向计算
for(j=0;j<NH;j++){ //隐层
for(i=0;i<NI;i++)
uH[j] += w[i][j]*X[p][i];
uH[j] += yuH[j];
vH[j] = f(uH[j]);
}
for(j=0;j<NO;j++){ //输出层
for(i=0;i<NH;i++)
uO[j] += ww[i][j]*vH[i];
uO[j] += yuO[j];
vO[j] = f(uO[j]);
E += 0.5*pow(fabs(vO[j] - Y[p][j]),2);
}
//反向计算局部梯度
for(i=0;i<NO;i++) //输出节点
deltaO[i] = -(vO[i] - Y[p][i])*ft(uO[i]); //局部梯度
for(i=0;i<NH;i++){ //隐层节点
for(j=0;j<NO;j++)
deltaH[i] += deltaO[j]*ww[i][j]*ft(uH[i]); //局部梯度
}
//更新网络权重及阈值
for(j=0;j<NH;j++){
for(i=0;i<NI;i++)
w[i][j] += ETA*deltaH[j]*X[p][i];
yuH[j] += ETA*deltaH[j];
}
for(j=0;j<NO;j++){
for(i=0;i<NH;i++)
ww[i][j] += ETA*deltaO[j]*vH[i];
yuO[j] += ETA*deltaO[j];
}
}
//输出结果
if(E<T){
cout<<"ok"<<endl;
cout<<"输入层到隐层的权值如下:"<<endl;
for(i=0;i<NI;i++){
for(j=0;j<NH;j++)
cout<<w[i][j]<<endl;
}
cout<<"隐层到输出层的权值如下:"<<endl;
for(i=0;i<NH;i++){
for(j=0;j<NO;j++)
cout<<ww[i][j]<<endl;
}
cout<<"隐层的阈值如下:"<<endl;
for(i=0;i<NH;i++)
cout<<yuH[i]<<endl;
cout<<"输出层的阈值如下:"<<endl;
for(i=0;i<NO;i++)
cout<<yuO[i]<<endl;
return 0;
}
}
cout<<"failed"<<endl;
return 0;
}
对于上述代码,如果做界面的话,就是做对话框,一个输入的编辑框,然后一个按钮,另外还有4个输出的编辑框 展开
#include <fstream>
#include <math.h>
#include <ctime>
using namespace std;
const int N = 6; //样本数
const int NI = 2; //输入层节点数
const int NH = 2; //隐层节点数
const int NO = 1; //输出层节点数
const double T = 0.01; //误差最小值
const double ETA = 0.5; //学习效率
double w[NI][NH]; //输入层到隐层的权值
double ww[NH][NO]; //隐层到输出层的权值
double deltaO[NO]; //输出节点的局部梯度
double deltaH[NH]; //隐层节点的局部梯度
double vH[NH],vO[NO]; //各层节点的输出
double uH[NH],uO[NO]; //各层节点的输入
double yuH[NH], yuO[NO]; //隐层和输出层的阈值
//样本数据
double X[N][NI]={{1,1}, {2,2}, {-1,-1}, {1,-1}, {-1,1},{-2,2}};
double Y[N][NO]={0,0,0,1,1,1};
//Sigmoid函数
double f(double x){
return 1/(1+exp(-x));
}
//Sigmoid函数的一阶导数
double ft(double x){
return exp(-x)/((1+exp(-x))*(1+exp(-x)));
}
//初始化网络权值
void initital(){
srand((unsigned int)time(NULL));
int i,j,flag =1.5;
for(j=0;j<NH;j++){
yuH[j] = (double)(((double)rand()/RAND_MAX)*2-1); //-1~1之间的随机数
for( i=0;i<NI;i++)
w[i][j] = (double)(((double)rand()/RAND_MAX)*2-1);
}
for(j=0;j<NO;j++){
yuO[j] = (double)(((double)rand()/RAND_MAX)*2-1);
for( i=0;i<NH;i++)
ww[i][j] = (double)(((double)rand()/RAND_MAX)*2-1);
}
}
int main(){
initital();
int i,j,k;
int t = 5000; //最大学习次数
while(t--){
double E = 0;
for(int p=0;p<N;p++){ //枚举全部样本
memset(deltaO,0,sizeof(deltaO));
memset(deltaH,0,sizeof(deltaH));
memset(uH,0,sizeof(uH));
memset(uO,0,sizeof(uO));
//前向计算
for(j=0;j<NH;j++){ //隐层
for(i=0;i<NI;i++)
uH[j] += w[i][j]*X[p][i];
uH[j] += yuH[j];
vH[j] = f(uH[j]);
}
for(j=0;j<NO;j++){ //输出层
for(i=0;i<NH;i++)
uO[j] += ww[i][j]*vH[i];
uO[j] += yuO[j];
vO[j] = f(uO[j]);
E += 0.5*pow(fabs(vO[j] - Y[p][j]),2);
}
//反向计算局部梯度
for(i=0;i<NO;i++) //输出节点
deltaO[i] = -(vO[i] - Y[p][i])*ft(uO[i]); //局部梯度
for(i=0;i<NH;i++){ //隐层节点
for(j=0;j<NO;j++)
deltaH[i] += deltaO[j]*ww[i][j]*ft(uH[i]); //局部梯度
}
//更新网络权重及阈值
for(j=0;j<NH;j++){
for(i=0;i<NI;i++)
w[i][j] += ETA*deltaH[j]*X[p][i];
yuH[j] += ETA*deltaH[j];
}
for(j=0;j<NO;j++){
for(i=0;i<NH;i++)
ww[i][j] += ETA*deltaO[j]*vH[i];
yuO[j] += ETA*deltaO[j];
}
}
//输出结果
if(E<T){
cout<<"ok"<<endl;
cout<<"输入层到隐层的权值如下:"<<endl;
for(i=0;i<NI;i++){
for(j=0;j<NH;j++)
cout<<w[i][j]<<endl;
}
cout<<"隐层到输出层的权值如下:"<<endl;
for(i=0;i<NH;i++){
for(j=0;j<NO;j++)
cout<<ww[i][j]<<endl;
}
cout<<"隐层的阈值如下:"<<endl;
for(i=0;i<NH;i++)
cout<<yuH[i]<<endl;
cout<<"输出层的阈值如下:"<<endl;
for(i=0;i<NO;i++)
cout<<yuO[i]<<endl;
return 0;
}
}
cout<<"failed"<<endl;
return 0;
}
对于上述代码,如果做界面的话,就是做对话框,一个输入的编辑框,然后一个按钮,另外还有4个输出的编辑框 展开
1个回答
展开全部
可以创建基于对话框的应用程序,对话框的控件,建议如下:
1. 你的样本数据输入输出已经确定了,输入编辑框用来输入什么?如果准备用来输入样本数据,用一个输入框,会让程序很复杂,不如多做几个;
2. 按钮的响应函数,可以把main()中的大部分内容贴过来
3. 输出部分,因为节点数不多,可以使用CStatic,静态框,如果将来节点数很多,可以考虑使用列表框
4. 由于现在的学习次数不多,可以一次执行结束,将来如果执行次数很多,应该考虑能够在中间暂停,并把中间结果保存下来,下次继续运行。否则调试效率会非常低的。
1. 你的样本数据输入输出已经确定了,输入编辑框用来输入什么?如果准备用来输入样本数据,用一个输入框,会让程序很复杂,不如多做几个;
2. 按钮的响应函数,可以把main()中的大部分内容贴过来
3. 输出部分,因为节点数不多,可以使用CStatic,静态框,如果将来节点数很多,可以考虑使用列表框
4. 由于现在的学习次数不多,可以一次执行结束,将来如果执行次数很多,应该考虑能够在中间暂停,并把中间结果保存下来,下次继续运行。否则调试效率会非常低的。
追问
嗯 如果你设计一个界面 你怎么设计?
追答
由于你模型的节点数很少,为所有的权值、输入、输出、梯度、阈值,设置对应的静态框CStatic,总共是十几个框框,在对话框上排列不成问题。
界面上再设置一个按钮,“计算”,响应函数就是 main中的内容。
界面基本上就这样了。
如果需要记录中间的计算过程,可以打开文件,把数据写入文件,事后仔细查阅,但不适合把中间结果显示在界面上。
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询