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)); } }