c++版本java
#include <stdio.h> #include <stdlib.h> #include <time.h> int M[10] = {0}; //权值 int X[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; //输入向量 int Y[10] = {1, 0, 1, 0, 1, 0, 1, 0, 1, 0}; //理想输出向量 注:1 表示奇数; 0 表示偶数 int O[10] = {0}; //保存输出向量 int ST = 52; //阈值,默认值:52 //初始化权值 void initM() { srand((unsigned int)time(0)); for (int x=0; x<10; ++x) { //初始化权值所使用的随机数在 0 - 99 之间 M[x] = rand()%100; } } //激活函数 int active(int m, int x) { int o = m * x; if (o > ST) { return 0; } else { return 1; } } //计算输出向量 void calcY() { for (int x=0; x<10; ++x) { O[x] = active(M[x], X[x]); } } //根据实际输出向量和理想输出向量调整权向量,返回实际输出和理想输出不匹配的数目 int adjustM() { int err = 0; for (int x=0; x<10; ++x) { if (O[x] != Y[x]) { err++; if (1 == O[x]) { M[x] += X[x]; } else { M[x] -= X[x]; } } } return err; } //打印权向量 void printM() { printf("\n最终训练结果:\n"); for (int x=0; x<10; ++x) { printf("M[%i] = %i\n", x, M[x]); } } //测试已经训练好的ANN void test(int input) { if ( 0==active(M[input], X[input]) ) { printf("%d 是 偶数 ", input+1); } else { printf("%d 是 奇数 ", input+1); } printf("\n\n"); } //主函数入口 int main() { printf("请输入阈值:"); scanf("%d", &ST); printf("\n"); initM(); int n = 0; //一直训练直到可以100%正确为止 while (1) { n++; calcY(); int err = adjustM(); if (0 >=err) { //可以100%正确地回答问题了,结束训练 break; } printf("第%0.2d次训练后的结果中存在的错误数 %d\n", n,err); } printM(); printf("\n阈值=%d 训练次数=%d\n\n", ST, n); while (true) { int a = 0; printf("请输入范围为1~10的数字:"); scanf("%d", &a); if (1 > a || 10 < a) { break; } test(a-1); } return 0; }
java版本c++
import java.util.Arrays; import java.util.Random; public class BpDeep{ public double[][] layer;//神经网络各层节点 public double[][] layerErr;//神经网络各节点偏差 public double[][][] layer_weight;//各层节点权重 public double[][][] layer_weight_delta;//各层节点权重动量 public double mobp;//动量系数 public double rate;//学习系数 public BpDeep(int[] layernum, double rate, double mobp){ this.mobp = mobp; this.rate = rate; layer = new double[layernum.length][]; layerErr = new double[layernum.length][]; layer_weight = new double[layernum.length][][]; layer_weight_delta = new double[layernum.length][][]; Random random = new Random(); for(int l=0;l<layernum.length;l++){ layer[l]=new double[layernum[l]]; layerErr[l]=new double[layernum[l]]; if(l+1<layernum.length){ layer_weight[l]=new double[layernum[l]+1][layernum[l+1]]; layer_weight_delta[l]=new double[layernum[l]+1][layernum[l+1]]; for(int j=0;j<layernum[l]+1;j++) for(int i=0;i<layernum[l+1];i++) layer_weight[l][j][i]=random.nextDouble();//随机初始化权重 } } } //逐层向前计算输出 public double[] computeOut(double[] in){ for(int l=1;l<layer.length;l++){ for(int j=0;j<layer[l].length;j++){ double z=layer_weight[l-1][layer[l-1].length][j]; for(int i=0;i<layer[l-1].length;i++){ layer[l-1][i]=l==1?in[i]:layer[l-1][i]; z+=layer_weight[l-1][i][j]*layer[l-1][i]; } layer[l][j]=1/(1+Math.exp(-z)); } } return layer[layer.length-1]; } //逐层反向计算偏差并修改权重 public void updateWeight(double[] tar){ int l=layer.length-1; for(int j=0;j<layerErr[l].length;j++) layerErr[l][j]=layer[l][j]*(1-layer[l][j])*(tar[j]-layer[l][j]); while(l-->0){ for(int j=0;j<layerErr[l].length;j++){ double z = 0.0; for(int i=0;i<layerErr[l+1].length;i++){ z=z+l>0?layerErr[l+1][i]*layer_weight[l][j][i]:0; layer_weight_delta[l][j][i]= mobp*layer_weight_delta[l][j][i]+rate*layerErr[l+1][i]*layer[l][j];//隐含层动量调整 layer_weight[l][j][i]+=layer_weight_delta[l][j][i];//隐含层权重调整 if(j==layerErr[l].length-1){ layer_weight_delta[l][j+1][i]= mobp*layer_weight_delta[l][j+1][i]+rate*layerErr[l+1][i];//截距动量调整 layer_weight[l][j+1][i]+=layer_weight_delta[l][j+1][i];//截距权重调整 } } layerErr[l][j]=z*layer[l][j]*(1-layer[l][j]);//记录偏差 } } } public void train(double[] in, double[] tar){ double[] out = computeOut(in); updateWeight(tar); } public static void main(String[] args){ //初始化神经网络的基本配置 //第一个参数是一个整型数组,表示神经网络的层数和每层节点数,好比{3,10,10,10,10,2}表示输入层是3个节点,输出层是2个节点,中间有4层隐含层,每层10个节点 //第二个参数是学习步长,第三个参数是动量系数 BpDeep bp = new BpDeep(new int[]{2,10,2}, 0.15, 0.8); //设置样本数据,对应上面的4个二维坐标数据 double[][] data = new double[][]{{1,2},{2,2},{1,1},{2,1}}; //设置目标数据,对应4个坐标数据的分类 double[][] target = new double[][]{{1,0},{0,1},{0,1},{1,0}}; //迭代训练5000次 for(int n=0;n<5000;n++) for(int i=0;i<data.length;i++) bp.train(data[i], target[i]); //根据训练结果来检验样本数据 for(int j=0;j<data.length;j++){ double[] result = bp.computeOut(data[j]); System.out.println(Arrays.toString(data[j])+":"+ Arrays.toString(result)); } //根据训练结果来预测一条新数据的分类 double[] x = new double[]{3,1}; double[] result = bp.computeOut(x); System.out.println(Arrays.toString(x)+":"+Arrays.toString(result)); } }