初探神经网络:QT下建立BP网络模型
2012-03-07 17:06
567 查看
初探神经网络:QT下建立BP网络模型
本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明.
环境:
主机:WIN7
开发环境:Qt
实现功能:
建立了细胞类以及BP网络类.BP神经网络为3层结构:输入层,隐藏层,输出层.
说明:
1.细胞模型
![](http://hi.csdn.net/attachment/201203/7/0_1331110777D66N.gif)
2.BP网络模型
![](http://hi.csdn.net/attachment/201203/7/0_1331111814Tr9o.gif)
3.输入层细胞阈值为0,输出层细胞权值为1.
4.隐藏层传递函数为f(x) = 1 / (1 + e(-x))
5.需要载入的权文件名为w.txt,放在运行目录下,格式为每个数字一行.输入顺序为输入层细胞所有权,隐藏层细胞所有权.
6.需要载入的权阈值文件名为threshold.txt,放在运行目录下,格式为每个数字一行.输入顺序为隐藏层细胞所有阈值,输出层细胞所有阈值.
7.供BP网络学习的文件名为study.txt,放在运行目录下,格式为每个数字一行.输入顺序为第1次所有输入层细胞的输入,第1次所有输出层细胞的输出,第2次...
8.权值和阈值可以用提供的随机函数生成,范围是-1至1
源代码:
public.h:细胞及BP网络类头文件
public.c:实现类的各个方法
widget.c:测试程序
本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明.
环境:
主机:WIN7
开发环境:Qt
实现功能:
建立了细胞类以及BP网络类.BP神经网络为3层结构:输入层,隐藏层,输出层.
说明:
1.细胞模型
![](http://hi.csdn.net/attachment/201203/7/0_1331110777D66N.gif)
2.BP网络模型
![](http://hi.csdn.net/attachment/201203/7/0_1331111814Tr9o.gif)
3.输入层细胞阈值为0,输出层细胞权值为1.
4.隐藏层传递函数为f(x) = 1 / (1 + e(-x))
5.需要载入的权文件名为w.txt,放在运行目录下,格式为每个数字一行.输入顺序为输入层细胞所有权,隐藏层细胞所有权.
6.需要载入的权阈值文件名为threshold.txt,放在运行目录下,格式为每个数字一行.输入顺序为隐藏层细胞所有阈值,输出层细胞所有阈值.
7.供BP网络学习的文件名为study.txt,放在运行目录下,格式为每个数字一行.输入顺序为第1次所有输入层细胞的输入,第1次所有输出层细胞的输出,第2次...
8.权值和阈值可以用提供的随机函数生成,范围是-1至1
源代码:
public.h:细胞及BP网络类头文件
#ifndef PUBLIC_H #define PUBLIC_H //头文件 #include <QWidget> #include "qdebug.h" #include "QFile" #include "math.h" #include <time.h> //宏定义 //全局变量 //数据结构 //细胞 class _Cell { private: //输入数 int num_in; //输出数 int num_out; //输入 double *pt_in; //输出 double *pt_out; //输出,不加权 double out_no_w; //权 double *pt_w; //阈值 double threshold; //传递函数类型 int type_fun; //传递函数 double fun(double x); public: //初始化 //num1:输入数 //num2:输出数 _Cell(int num1 = 0,int num2 = 0); //设置输入数 void set_in_num(int num); //设置输出数 void set_out_num(int num); //返回输入数 int return_in_num(); //返回输出数 int return_out_num(); //返回权值 //num:指向的目标细胞 double return_w(int num); //返回当前阈值 double return_threshold(); //返回输入 //num为第num个输入 double return_in(int num); //设置输入 void set_in(double a,int num); //设置阈值 void set_threshold(double a); //设置权 void set_w(double a,int num); //设置传递函数类型 void set_fun(int num); //计算输出 void calc(); //返回输出 double output(int num); //返回输出不加权 double output_no_w(); }; //BP网络 class _BP_Net { private: //输入层细胞数 int num_in_layer; //隐藏层细胞数 int num_hide_layer; //输出层细胞数 int num_out_layer; //输入层细胞指针 _Cell *pt_in_layer_cell; //隐藏层细胞指针 _Cell *pt_hide_layer_cell; //输出层细胞指针 _Cell *pt_out_layer_cell; //学习速率 double g; public: //初始化 _BP_Net(int num_in = 0,int num_hide = 0,int num_out = 0); //设置输入层细胞数 void set_num_in_layer(int num); //设置隐藏层细胞数 void set_num_hide_layer(int num); //设置输出层细胞数 void set_num_out_layer(int num); //返回输入层细胞数 int return_num_in_layer(); //返回隐藏层细胞数 int return_num_hide_layer(); //返回输出层细胞数 int return_num_out_layer(); //返回权值 //i:层号,0输入层,1隐藏层,2输出层 //j:本层细胞号 //k:下一层细胞号 //失败返回-1 double return_w(int i,int j,int k); //返回阈值 //i:层号,0输入层,1隐藏层,2输出层 //j:本层细胞号 //失败返回-1 double return_threshold(int i,int j); //产生随机的权值,-1-1之间 void set_rand_w(); //产生随机的阈值,-1-1之间 void set_rand_threshold(); //设置输入层权值 //a:权值,i:细胞号,j:细胞对应输出 void set_in_layer_w(double a,int i,int j); //设置隐藏层权值 //a:权值,i:细胞号,j:细胞对应输出 void set_hide_layer_w(double a,int i,int j); //设置隐藏层阈值 //a:阈值,num:细胞号 void set_hide_layer_threshold(double a,int num); //设置输出层阈值 //a:阈值,num:细胞号 void set_out_layer_threshold(double a,int num); //设置学习速率 void set_g(double a); //学习 //right为正确的值数组 void study(double *right); //计算输出 void calc(); //返回输出 double output(int num); //设置输入层细胞输入 void set_in(double a,int num); }; //全局函数 //初始化 //归一化函数 //dst:目标数据 //min:最小值 //max:最大值 double mapminmax(double dst,double min,double max); //反归一化 //dst:目标数据 //min:最小值 //max:最大值 double premapminmax(double dst,double min,double max); //加载权值 //dir:目录,bp_net:神经网络 //成功返回1,失败返回-1 int load_w(QString dir,_BP_Net *bp_net); //加载阈值 //dir:目录,bp_net:神经网络 //成功返回1,失败返回-1 int load_threshold(QString dir,_BP_Net *bp_net); //写入权值 //dir:目录,bp_net:神经网络 //成功返回1,失败返回-1 int write_w(QString dir,_BP_Net *bp_net); //写入阈值 //dir:目录,bp_net:神经网络 //成功返回1,失败返回-1 int write_threshold(QString dir,_BP_Net *bp_net); //读取正确的值,并且学习 //dir:目录,bp_net:神经网络 //成功返回1,失败返回-1 int study(QString dir,_BP_Net *bp_net); #endif // PUBLIC_H
public.c:实现类的各个方法
#include "public.h" //全局变量定义 //细胞方法 //初始化 //num1:输入数 //num2:输出数 _Cell::_Cell(int num1,int num2) { num_in = num1; num_out = num2; if (num1 != 0 && num2 != 0) { //开辟空间 pt_in = new double[num_in]; pt_out = new double[num_out]; pt_w = new double[num_out]; } } //设置输入数 void _Cell::set_in_num(int num) { num_in = num; } //设置输出数 void _Cell::set_out_num(int num) { num_out = num; //开辟空间 pt_in = new double[num_in]; pt_out = new double[num_out]; pt_w = new double[num_out]; } //返回输入数 int _Cell::return_in_num() { return num_in; } //返回输出数 int _Cell::return_out_num() { return num_out; } //返回权值 //num:指向的目标细胞 double _Cell::return_w(int num) { return pt_w[num]; } //返回当前阈值 double _Cell::return_threshold() { return threshold; } //返回输入 //num为第num个输入 double _Cell::return_in(int num) { return pt_in[num]; } //传递函数 double _Cell::fun(double x) { //判断传递函数类型 if (type_fun == 0) { //直接传递 return x; } else { //连续曲线 return(1.0 / (1.0 + exp(-1.0 * x))); } } //设置权 void _Cell::set_w(double a,int num) { pt_w[num] = a; } //设置阈值 void _Cell::set_threshold(double a) { threshold = a; } //设置输入 void _Cell::set_in(double a,int num) { pt_in[num] = a; } //设置传递函数类型 void _Cell::set_fun(int num) { if (num != 1) { type_fun = 0; } else { type_fun = 1; } } //返回输出 double _Cell::output(int num) { return pt_out[num]; } //返回输出不加权 double _Cell::output_no_w() { return out_no_w; } //计算输出 void _Cell::calc() { int i = 0; double temp = 0; for (i = 0;i < num_in;i++) { temp += pt_in[i]; } temp -= threshold; out_no_w = fun(temp); //输出加权 for (i = 0;i < num_out;i++) { pt_out[i] = out_no_w * pt_w[i]; } } //BP网络方法 //初始化 _BP_Net::_BP_Net(int num_in,int num_hide,int num_out) { int i = 0; num_in_layer = num_in; num_hide_layer = num_hide; num_out_layer = num_out; //初始化学习速率 g = 0.5; if (num_in_layer != 0 && num_hide_layer != 0 && num_out_layer != 0) { //初始化每层细胞指针 pt_in_layer_cell = new _Cell[num_in]; pt_hide_layer_cell = new _Cell[num_hide]; pt_out_layer_cell = new _Cell[num_out]; //初始化每层细胞的输入,输出,传递函数类型 //初始化输入层 for (i = 0;i < num_in_layer;i++) { pt_in_layer_cell[i].set_in_num(1); pt_in_layer_cell[i].set_out_num(num_hide_layer); pt_in_layer_cell[i].set_fun(0); //初始化输入层阈值0.0 pt_in_layer_cell[i].set_threshold(0.0); } //初始化隐藏层 for (i = 0;i < num_hide_layer;i++) { pt_hide_layer_cell[i].set_in_num(num_in_layer); pt_hide_layer_cell[i].set_out_num(num_out_layer); pt_hide_layer_cell[i].set_fun(1); } //初始化输出层 for (i = 0;i < num_out_layer;i++) { pt_out_layer_cell[i].set_in_num(num_hide_layer); pt_out_layer_cell[i].set_out_num(1); pt_out_layer_cell[i].set_fun(0); //初始化输出层权值1.0 pt_out_layer_cell[i].set_w(1.0,0); } } } //设置输入层细胞数 void _BP_Net::set_num_in_layer(int num) { num_in_layer = num; } //设置隐藏层细胞数 void _BP_Net::set_num_hide_layer(int num) { num_hide_layer = num; } //设置输出层细胞数 void _BP_Net::set_num_out_layer(int num) { int i = 0; num_out_layer = num; //初始化每层细胞指针 pt_in_layer_cell = new _Cell[num_in_layer]; pt_hide_layer_cell = new _Cell[num_hide_layer]; pt_out_layer_cell = new _Cell[num_out_layer]; //初始化每层细胞的输入,输出,传递函数类型 //初始化输入层 for (i = 0;i < num_in_layer;i++) { pt_in_layer_cell[i].set_in_num(1); pt_in_layer_cell[i].set_out_num(num_hide_layer); pt_in_layer_cell[i].set_fun(0); //初始化输入层阈值0.0 pt_in_layer_cell[i].set_threshold(0.0); } //初始化隐藏层 for (i = 0;i < num_hide_layer;i++) { pt_hide_layer_cell[i].set_in_num(num_in_layer); pt_hide_layer_cell[i].set_out_num(num_out_layer); pt_hide_layer_cell[i].set_fun(1); } //初始化输出层 for (i = 0;i < num_out_layer;i++) { pt_out_layer_cell[i].set_in_num(num_hide_layer); pt_out_layer_cell[i].set_out_num(1); pt_out_layer_cell[i].set_fun(0); //初始化输出层权值1.0 pt_out_layer_cell[i].set_w(1.0,0); } } //返回输入层细胞数 int _BP_Net::return_num_in_layer() { return num_in_layer; } //返回隐藏层细胞数 int _BP_Net::return_num_hide_layer() { return num_hide_layer; } //返回输出层细胞数 int _BP_Net::return_num_out_layer() { return num_out_layer; } //返回权值 //i:层号,0输入层,1隐藏层,2输出层 //j:本层细胞号 //k:下一层细胞号 //失败返回-1 double _BP_Net::return_w(int i,int j,int k) { switch (i) { case 0: { //输入层 return pt_in_layer_cell[j].return_w(k); break; } case 1: { //隐藏层 return pt_hide_layer_cell[j].return_w(k); break; } case 2: { //输出层 return pt_out_layer_cell[j].return_w(k); break; } default: { return -1; break; } } } //返回阈值 //i:层号,0输入层,1隐藏层,2输出层 //j:本层细胞号 //失败返回-1 double _BP_Net::return_threshold(int i,int j) { switch (i) { case 0: { //输入层 return pt_in_layer_cell[j].return_threshold(); break; } case 1: { //隐藏层 return pt_hide_layer_cell[j].return_threshold(); break; } case 2: { //输出层 return pt_out_layer_cell[j].return_threshold(); break; } default: { return -1; break; } } } //产生随机的权值,-1-1 void _BP_Net::set_rand_w() { int i = 0; int j = 0; double temp = 0; //获取随机数种子 srand((unsigned)time(NULL)); //初始化输入层权值 for (i = 0;i < num_in_layer;i++) { for (j = 0;j < pt_in_layer_cell[0].return_out_num();j++) { temp = (double)(rand() % 200 - 100) / 100.0; pt_in_layer_cell[i].set_w(temp,j); } } //初始化隐藏层权值 for (i = 0;i < num_hide_layer;i++) { for (j = 0;j < pt_hide_layer_cell[0].return_out_num();j++) { temp = (double)(rand() % 200 - 100) / 100.0; pt_hide_layer_cell[i].set_w(temp,j); } } //初始化输出层权值 //设置权值为1 for (i = 0;i < num_out_layer;i++) { for (j = 0;j < pt_out_layer_cell[0].return_out_num();j++) { //temp = (double)(rand() % 200 - 100) / 100.0; pt_out_layer_cell[i].set_w(1.0,j); } } } //产生随机的阈值,-1-1 void _BP_Net::set_rand_threshold() { int i = 0; double temp = 0; //获取随机数种子 srand((unsigned)time(NULL)); //初始化输入层阈值 //设置为0 for (i = 0;i < num_in_layer;i++) { pt_in_layer_cell[i].set_threshold(0.0); } //初始化隐藏层权值 for (i = 0;i < num_hide_layer;i++) { temp = (double)(rand() % 200 - 100) / 100.0; pt_hide_layer_cell[i].set_threshold(temp); } //初始化输出层权值 //设置权值为1 for (i = 0;i < num_out_layer;i++) { temp = (double)(rand() % 200 - 100) / 100.0; pt_out_layer_cell[i].set_threshold(temp); } } //设置输入层权值 //a:权值,i:细胞号,j:细胞对应输出 void _BP_Net::set_in_layer_w(double a,int i,int j) { pt_in_layer_cell[i].set_w(a,j); } //设置隐藏层权值 //a:权值,i:细胞号,j:细胞对应输出 void _BP_Net::set_hide_layer_w(double a,int i,int j) { pt_hide_layer_cell[i].set_w(a,j); } //设置隐藏层阈值 //a:阈值,num:细胞号 void _BP_Net::set_hide_layer_threshold(double a,int num) { pt_hide_layer_cell[num].set_threshold(a); } //设置输出层阈值 //a:阈值,num:细胞号 void _BP_Net::set_out_layer_threshold(double a,int num) { pt_out_layer_cell[num].set_threshold(a); } //设置学习速率 void _BP_Net::set_g(double a) { g = a; } //学习 //right为正确的值数组 void _BP_Net::study(double *right) { int i = 0; int j = 0; int k = 0; double sum = 0.0; double temp = 0.0; //误差指针 double *pt_e = new double[num_out_layer]; //计算各个误差 for (k = 0;k < num_out_layer;k++) { pt_e[k] = *right - pt_out_layer_cell[k].output_no_w(); right++; //qDebug() << "wucha:" << pt_e[i]; } //阈值更新 //隐藏层阈值更新 for (j = 0;j < num_hide_layer;j++) { sum = 0; //计算输出层节点输出误差和 for (k = 0;k < num_out_layer;k++) { sum += pt_hide_layer_cell[j].return_w(k) * pt_e[k]; } temp = pt_hide_layer_cell[j].return_threshold() + \ g * pt_hide_layer_cell[j].output_no_w() * \ (1 - pt_hide_layer_cell[j].output_no_w()) * sum; //qDebug() << "wucha:" << sum; //qDebug() << "yi qian de yu zhi" << pt_hide_layer_cell[j].return_threshold(); //qDebug() << "xian zai de yu zhi" << temp; //qDebug() << "bu jia quan shu chu" << pt_hide_layer_cell[j].output_no_w(); pt_hide_layer_cell[i].set_threshold(temp); //qDebug() << "hide threshold" << temp; } //输出层阈值更新 for (k = 0;k < num_out_layer;k++) { temp = pt_out_layer_cell[k].return_threshold() + pt_e[k]; pt_out_layer_cell[k].set_threshold(temp); //qDebug() << "out threshold" << temp; } //权值更新 //输入层权值更新 for (i = 0;i < num_in_layer;i++) { for (j = 0;j < num_hide_layer;j++) { sum = 0; //计算输出层节点输出误差和 for (k = 0;k < num_out_layer;k++) { sum += pt_hide_layer_cell[j].return_w(k) * pt_e[k]; } temp = pt_in_layer_cell[i].return_w(j) + \ g * pt_hide_layer_cell[j].output_no_w() * \ (1 - pt_hide_layer_cell[j].output_no_w()) * \ pt_in_layer_cell[i].return_in(0) * sum; //qDebug() << "wucha:" << sum; //qDebug() << "yi qian de quan zhi" << pt_in_layer_cell[i].return_w(j); //qDebug() << "xian zai de quan zhi" << temp; pt_in_layer_cell[i].set_w(temp,j); //qDebug() << "in w" << temp; } } //隐藏层权值更新 for (j = 0;j < num_hide_layer;j++) { for (k = 0;k < num_out_layer;k++) { temp = pt_hide_layer_cell[j].return_w(k) + \ g * pt_hide_layer_cell[j].output_no_w() * pt_e[k]; //qDebug() << "wucha:" << pt_e[j]; //qDebug() << "yi qian de quan zhi" << pt_hide_layer_cell[i].return_w(j); //qDebug() << "xian zai de quan zhi" << temp; pt_hide_layer_cell[j].set_w(temp,k); //qDebug() << "hide w" << temp; } } } //计算输出 void _BP_Net::calc() { int i = 0; int j = 0; int k = 0; //计算输入层细胞输出 for (i = 0;i < num_in_layer;i++) { pt_in_layer_cell[i].calc(); } //设置隐藏层细胞输入,并计算隐藏层细胞输出 for (j = 0;j < num_hide_layer;j++) { for (i = 0;i < num_in_layer;i++) { pt_hide_layer_cell[j].set_in(pt_in_layer_cell[i].output(j),i); } pt_hide_layer_cell[j].calc(); } //设置输出层细胞输入,并计算输出层细胞输出 for (k = 0;k < num_out_layer;k++) { for (j = 0;j < num_hide_layer;j++) { pt_out_layer_cell[k].set_in(pt_hide_layer_cell[j].output(k),j); } pt_out_layer_cell[k].calc(); } } //返回输出 double _BP_Net::output(int num) { double temp = 0.0; temp = pt_out_layer_cell[num].output(0); return temp; } //设置输入层细胞输入 void _BP_Net::set_in(double a,int num) { pt_in_layer_cell[num].set_in(a,0); } //全局函数定义 //归一化函数 //dst:目标数据 //min:最小值 //max:最大值 double mapminmax(double dst,double min,double max) { double temp = 0; temp = (dst - min) / (max - min); return temp; } //反归一化 //dst:目标数据 //min:最小值 //max:最大值 double premapminmax(double dst,double min,double max) { double temp = 0; temp = dst * (max - min) + min; return temp; } //加载权值 //dir:目录,bp_net:神经网络 //成功返回1,失败返回-1 int load_w(QString dir,_BP_Net *bp_net) { QFile file(dir); QByteArray line; bool ok; int i = 0; int j = 0; int k = 0; double temp = 0.0; if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { return -1; } //读到末尾或者已经写完则退出 //i指示层数 i = 0; //j指示细胞号 j = 0; //k指示目标细胞号 k = 0; while (!file.atEnd()) { //如果隐藏层全部赋值则退出 if (i >= 2) { break; } //读取数据 line = file.readLine(); line.chop(1); temp = line.toDouble(&ok); if (ok == false) { return -1; } //赋值给输入层权值 if (i == 0) { bp_net->set_in_layer_w(temp,j,k); k++; //如果超过最大目标细胞号,则开始本层下一个细胞 if (k >= bp_net->return_num_hide_layer()) { k = 0; j++; } //如果超过最大细胞号,则开始下一层 if (j >= bp_net->return_num_in_layer()) { j = 0; i++; } continue; } //赋值给隐藏层权值 if (i == 1) { bp_net->set_hide_layer_w(temp,j,k); k++; //如果超过最大目标细胞号,则开始本层下一个细胞 if (k >= bp_net->return_num_out_layer()) { k = 0; j++; } //如果超过最大细胞号,则开始下一层 if (j >= bp_net->return_num_hide_layer()) { j = 0; i++; } continue; } } file.close(); return 1; } //加载阈值 //dir:目录,bp_net:神经网络 //成功返回1,失败返回-1 int load_threshold(QString dir,_BP_Net *bp_net) { QFile file(dir); QByteArray line; bool ok; int i = 0; int j = 0; double temp = 0.0; if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { return -1; } //读到末尾或者已经写完则退出 //i指示层数 i = 1; //j指示细胞号 j = 0; while (!file.atEnd()) { //如果输出层全部赋值则退出 if (i >= 3) { break; } //读取数据 line = file.readLine(); line.chop(1); temp = line.toDouble(&ok); if (ok == false) { return -1; } //赋值给隐藏层阈值 if (i == 1) { bp_net->set_hide_layer_threshold(temp,j); j++; //如果超过最大细胞号,则开始下一层 if (j >= bp_net->return_num_hide_layer()) { j = 0; i++; } continue; } //赋值给输出层阈值 if (i == 2) { bp_net->set_out_layer_threshold(temp,j); j++; //如果超过最大细胞号,则开始下一层 if (j >= bp_net->return_num_out_layer()) { j = 0; i++; } continue; } } file.close(); return 1; } //写入权值 //dir:目录,bp_net:神经网络 //成功返回1,失败返回-1 int write_w(QString dir,_BP_Net *bp_net) { QFile file(dir); QByteArray line; int i = 0; int j = 0; int k = 0; if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { return -1; } //i指示层数 i = 0; //j指示细胞号 j = 0; //k指示目标细胞号 k = 0; while (1) { //如果隐藏层全部赋值则退出 if (i >= 2) { break; } //读取数据 line = QByteArray::number(bp_net->return_w(i,j,k)); line.append('\n'); //写入 file.write(line); //判断输入层权值是否写完 if (i == 0) { k++; //如果超过下层最大细胞号,则开始本层下一个细胞 if (k >= bp_net->return_num_hide_layer()) { k = 0; j++; } //如果超过本层最大细胞号,则开始下一层 if (j >= bp_net->return_num_in_layer()) { j = 0; i++; } continue; } //判断隐藏层权值是否写完 if (i == 1) { k++; //如果超过最大目标细胞号,则开始本层下一个细胞 if (k >= bp_net->return_num_out_layer()) { k = 0; j++; } //如果超过最大细胞号,则开始下一层 if (j >= bp_net->return_num_hide_layer()) { j = 0; i++; } continue; } } file.close(); return 1; } //写入阈值 //dir:目录,bp_net:神经网络 //成功返回1,失败返回-1 int write_threshold(QString dir,_BP_Net *bp_net) { QFile file(dir); QByteArray line; int i = 0; int j = 0; if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { return -1; } //i指示层数 i = 1; //j指示细胞号 j = 0; while (1) { //如果输出层全部赋值则退出 if (i >= 3) { break; } //读取数据 line = QByteArray::number(bp_net->return_threshold(i,j)); line.append('\n'); //写入 file.write(line); //判断隐藏层权值是否写完 if (i == 1) { j++; //如果超过本层最大细胞号,则开始下一层 if (j >= bp_net->return_num_hide_layer()) { j = 0; i++; } continue; } //判断输出层权值是否写完 if (i == 2) { j++; //如果超过最大细胞号,则开始下一层 if (j >= bp_net->return_num_out_layer()) { j = 0; i++; } continue; } } file.close(); return 1; } //读取正确的值,并且学习 //dir:目录,bp_net:神经网络 //成功返回1,失败返回-1 int study(QString dir,_BP_Net *bp_net) { QFile file(dir); QByteArray line; bool ok; int i = 0; int j = 0; double temp = 0.0; double *pt_in; double *pt_right; //指示输入还是输出,0是输入,1是输出 int flag = 0; if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { return -1; } //设置正确数组 pt_in = new double[bp_net->return_num_in_layer()]; pt_right = new double[bp_net->return_num_out_layer()]; //读到末尾或者已经写完则退出 //i指示细胞号 i = 0; flag = 0; do { //如果到达文件尾,则退出 if (file.atEnd()) { break; } //读取数据 line = file.readLine(); line.chop(1); temp = line.toDouble(&ok); if (ok == false) { return -1; } if (flag == 0) { //输入 pt_in[i++] = temp; //当输入层写完 if (i >= bp_net->return_num_in_layer()) { //开始工作,计算输出 //设置输入 for (j = 0;j < bp_net->return_num_in_layer();j++) { bp_net->set_in(pt_in[j],j); } //计算输出 bp_net->calc(); //输出 qDebug() << "out" << bp_net->output(0); //准备学习 i = 0; flag = 1; continue; } } else { //输出 pt_right[i++] = temp; //当输出层写完 if (i >= bp_net->return_num_out_layer()) { //开始学习 bp_net->study(pt_right); //准备下一轮学习 i = 0; flag = 0; continue; } } }while (1); file.close(); return 1; }
widget.c:测试程序
#include "widget.h" #include "ui_widget.h" Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); int i = 0; //初始化BP网络 _BP_Net bp_net; //设置各层细胞数 bp_net.set_num_in_layer(1); bp_net.set_num_hide_layer(10); bp_net.set_num_out_layer(1); //设置随机权值 //bp_net.set_rand_w(); //设置随机阈值 //bp_net.set_rand_threshold(); //设置阈值和权值 load_w("w.txt",&bp_net); load_threshold("threshold.txt",&bp_net); //开始学习 for (i = 0;i < 1;i++) { study("study.txt",&bp_net); } //学好后,写入新的权值和阈值 write_w("w.txt",&bp_net); write_threshold("threshold.txt",&bp_net); //设置输入 bp_net.set_in(0.3,0); //计算输出 bp_net.calc(); //输出 qDebug() << "out:" << bp_net.output(0); } Widget::~Widget() { delete ui; }
相关文章推荐
- 网易 Andrew Ng DL课程学习记录 -(1)利用python建立神经网络模型-2
- 神经网络模型的建立
- 反向传播BP模型(属于神经网络)
- torch入门笔记10:如何建立torch神经网络模型
- Keras —— 基于Mnist数据集建立神经网络模型
- 自然语言处理的神经网络模型初探
- 谷歌神经网络机器翻译NMT:人人可利用TensorFlow快速建立翻译模型
- 神经网络模型分类
- 神经网络中 BP 算法的原理与 PYTHON 实现源码解析
- 建立神经网络:Part 0
- 资讯精选 | 忽悠神经网络指南:教你如何把深度学习模型骗得七荤八素
- Python 实现感知器模型、两层神经网络
- 神经网络做regression,模型不收敛
- 神经网络模型符号解释!!!蛮重要的,记不住的可以参考下。
- ANN 人工神经前馈网络BP实现
- BP 神经网络入门:从原理到应用
- Little Explanations #1 -神经网络与模型压缩
- CS231n 卷积神经网络与计算机视觉 7 神经网络训练技巧汇总 梯度检验 参数更新 超参数优化 模型融合 等
- [重磅]Deep Forest,非神经网络的深度模型,周志华老师最新之作,三十分钟理解!