🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
``` // bp21xor210202.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 // #define _CRT_SECURE_NO_WARNINGS #include <iostream> /******************************************** ** ** 神经网络实现异或操作 ** terry 41313989@qq.com ** 2013.01.18 ** ****************************************************/ #include <stdio.h> #include <stdlib.h> #include <time.h> #include <math.h> #define Ni 2 // 输入层神经元的个数 #define Nm 2 // 隐含层神经元的个数 #define No 1 // 输出层神经元的个数 #define Enom 0.02 // 误差下限,达到这个误差以内即可认为训练成功 #define MAXSAMPLE 1000 // 样本的最大个数 #define BP_LEARNING (float)(0.5) // 学习系数 // 输入层神经元只有传递的功能 float HWeight[Ni + 1][Nm]; // 隐含层神经元的输入权值 float OWeight[Nm + 1][No]; // 输出层神经元的输出权值 float inputValue[Ni]; float destValue[No]; float E; // 每轮的误差 // 训练的过程 int train(float in[Ni], float d[No]); // 神经网络初始化 void init(); // 测试的过程 int processTest(float in[Ni]); //Sigmoid函数 float Sigmoid(float num); int main() { float input[MAXSAMPLE][Ni]; // 输入 float dest[MAXSAMPLE][No]; // 目标输出 float test[Ni]; // 测试输入 int num; int i, j; long count = 0; // 输入相关的测试 printf("Please input the number of sample:"); // scanf("%d", &num); num = 4; for (i = 0; i < num; i++) { for (j = 0; j < Ni; j++) // scanf("%f", &input[i][j]); input[0][0] = 0; input[0][1] = 0; input[1][0] = 0; input[1][1] = 1; input[2][0] = 1; input[2][1] = 0; input[3][0] = 1; input[3][1] = 1; for (j = 0; j < No; j++) // scanf("%f", &dest[i][j]); dest[0][0] = 0; dest[1][0] = 1; dest[2][0] = 1; dest[3][0] = 0; } init(); while (1) { E = 0; for (i = 0; i < num; i++) { train(input[i], dest[i]); } if (E < Enom) break; if (count % 20000 == 0) printf("第%d迭代的误差为 %f \n", count, E); count++; } // 训练好的神经网络测试 while (1) { printf("Please input the test data:"); for (i = 0; i < Ni; i++) scanf("%f", &test[i]); processTest(test); } return 1; } // 测试的过程 int processTest(float in[Ni]) { int i, j; float net[Nm], iin[Nm], out[No]; // 计算隐含层的神经元值 for (i = 0; i < Nm; i++) { net[i] = 1 * HWeight[0][i]; for (j = 1; j < Ni + 1; j++) net[i] += HWeight[j][i] * in[j - 1]; } // 使用S函数 for (i = 0; i < Nm; i++) iin[i] = Sigmoid(net[i]); // 计算输出层的值 for (i = 0; i < No; i++) { net[i] = 1 * OWeight[0][i]; for (j = 1; j < Nm + 1; j++) net[i] += OWeight[j][i] * iin[j - 1]; } for (i = 0; i < No; i++) { out[i] = Sigmoid(net[i]); printf("%f ", out[i]); } printf("\n"); return 1; } // 训练的过程 int train(float in[Ni], float d[No]) { int i, j; float net[Nm], iin[Nm], out[No]; float deltaO[No + 1], deltaM[Nm + 1]; // delta值 float temp; // 计算隐含层的神经元值 for (i = 0; i < Nm; i++) { net[i] = 1 * HWeight[0][i]; for (j = 1; j < Ni + 1; j++) net[i] += HWeight[j][i] * in[j - 1]; } // 使用S函数 for (i = 0; i < Nm; i++) iin[i] = Sigmoid(net[i]); // 计算输出层的值 for (i = 0; i < No; i++) { net[i] = 1 * OWeight[0][i]; for (j = 1; j < Nm + 1; j++) net[i] += OWeight[j][i] * iin[j - 1]; } for (i = 0; i < No; i++) out[i] = Sigmoid(net[i]); for (i = 0; i < No; i++) E += (float)fabs(out[i] - d[i]); // 计算误差,反向传播 for (i = 0; i < No; i++) { deltaO[i] = out[i] * (1 - out[i])*(d[i] - out[i]); } for (i = 0; i < Nm; i++) { temp = 0; for (j = 0; j < No; j++) { temp += deltaO[j] * OWeight[i + 1][j]; } deltaM[i] = iin[i] * (1 - iin[i])*temp; } // 调整权值 // 输出层 for (i = 0; i < No; i++) { OWeight[0][i] += BP_LEARNING * 1 * deltaO[i]; for (j = 1; j < Nm + 1; j++) OWeight[j][i] += BP_LEARNING * iin[j - 1] * deltaO[i]; } for (i = 0; i < Nm; i++) { HWeight[0][i] += BP_LEARNING * 1 * deltaM[i]; for (j = 1; j < Nm + 1; j++) HWeight[j][i] += BP_LEARNING * in[j - 1] * deltaM[i]; } return 1; } // 神经网络初始化 void init() { int i, j; int random; double x; int stime; long ltime; ltime = time(NULL); stime = (unsigned)ltime / 2; srand(stime); for (i = 0; i < Ni + 1; i++) for (j = 0; j < Nm; j++) { // 设定网络连接的初值取值范围为(-0.5,0.5) random = rand() % 100 - 50; x = random; x = x / 100; HWeight[i][j] = (float)x; } for (i = 0; i < Nm + 1; i++) for (j = 0; j < No; j++) { random = rand() % 100 - 50; x = random; x = x / 100; OWeight[i][j] = (float)x; } } //Sigmoid函数 float Sigmoid(float num) { return (float)(1 / (1 + exp(-num))); } //int main() //{ // std::cout << "Hello World!\n"; //} ```