BP神经网络

BP神经网络是一种多层前馈神经网络,该网络的主要特点是前向预测和反向传播。

前向预测:

这里写图片描述

以上图为例,输入层有N_{i}个结点,隐含层有N_{h}个结点,输出层有N_{j}个结点。

输入层第i个结点到隐含层第h个结点的权值为W_{ih}

隐含层第h个结点到输出层第j个结点的权值为W_{hj}

输出层结点代表类别,输出层某结点的输出值最大则代表输入的数据被判定为该类别。

反向传播:

反向传播将误差沿原来的连接返回,修改各结点间的权值。


激活函数:

由于隐含层通常不止一层,因此采用非线性激活函数防止多层隐含层与一层隐含层等价。

常用的激活函数有sigmoid函数:

f(x)=\frac{1}{1+e^{-x}}

sigmoid函数会把输入的x值映射到0-1的空间内。 输入的x值越大,值越近似于1。

算法步骤:

1.初始化权值。
2.前向预测,计算输出层结点的输出值。
3.反向传播,计算各个结点的误差并调整权值。


代码中的 layerNumNodes 表示网络基本结构。

如: [3, 4, 6, 2] 表示:

输入层结点有 3 个,即数据有 3 个条件属性。
输出层结点有 2 个,即数据的决策类别数为 2。如果是分类问题, 输出值最大的结点表示数据是此类别。
隐含层有两层,分别有 4 个结点和 6 个结点。


layerNodeValues 表示各网络结点的值。

如上例, 网络基本结构有 4 层,即 layerNodeValues.length 为 4

总结点数为 3 + 4 + 6 + 2 = 15个

layerNodeValues[0].length = 3(输入层结点个数)

layerNodeValues[1].length = 4(第一层隐含层结点个数)

layerNodeValues[2].length = 6(第二层隐含层结点个数)

layerNodeValues[3].length = 2(输出层结点个数)

输入:iris数据集。

输出:分类正确个数以及分类正确率。

优化目标:可能没有优化目标。

代码:

package knn5;

public class SimpleAnn extends GeneralAnn{

	public double[][] layerNodeValues;

	public double[][] layerNodeErrors;

	public double[][][] edgeWeights;

	public double[][][] edgeWeightsDelta;

	public SimpleAnn(String paraFilename, int[] paraLayerNumNodes, double paraLearningRate,
			double paraMobp) {
		super(paraFilename, paraLayerNumNodes, paraLearningRate, paraMobp);

		layerNodeValues = new double[numLayers][];
		layerNodeErrors = new double[numLayers][];
		edgeWeights = new double[numLayers - 1][][];
		edgeWeightsDelta = new double[numLayers - 1][][];

		for (int l = 0; l < numLayers; l++) {
			layerNodeValues[l] = new double[layerNumNodes[l]];
			layerNodeErrors[l] = new double[layerNumNodes[l]];

			if (l + 1 == numLayers) {
				break;
			} // of if

			edgeWeights[l] = new double[layerNumNodes[l] + 1][layerNumNodes[l + 1]];
			edgeWeightsDelta[l] = new double[layerNumNodes[l] + 1][layerNumNodes[l + 1]];
			for (int j = 0; j < layerNumNodes[l] + 1; j++) {
				for (int i = 0; i < layerNumNodes[l + 1]; i++) {
					edgeWeights[l][j][i] = random.nextDouble();
				} // Of for i
			} // Of for j
		} // Of for l
	}// Of the constructor

	
	public double[] forward(double[] paraInput) {
		for (int i = 0; i < layerNodeValues[0].length; i++) {
			layerNodeValues[0][i] = paraInput[i];
		} // Of for i

		double z;
		for (int l = 1; l < numLayers; l++) {
			for (int j = 0; j < layerNodeValues[l].length; j++) {
				z = edgeWeights[l - 1][layerNodeValues[l - 1].length][j];
				for (int i = 0; i < layerNodeValues[l - 1].length; i++) {
					z += edgeWeights[l - 1][i][j] * layerNodeValues[l - 1][i];
				} // Of for i

				layerNodeValues[l][j] = 1 / (1 + Math.exp(-z));
			} // Of for j
		} // Of for l

		return layerNodeValues[numLayers - 1];
	}// Of forward

	
	public void backPropagation(double[] paraTarget) {
		int l = numLayers - 1;
		for (int j = 0; j < layerNodeErrors[l].length; j++) {
			layerNodeErrors[l][j] = layerNodeValues[l][j] * (1 - layerNodeValues[l][j])
					* (paraTarget[j] - layerNodeValues[l][j]);
		} // Of for j

		while (l > 0) {
			l--;
			for (int j = 0; j < layerNumNodes[l]; j++) {
				double z = 0.0;
				for (int i = 0; i < layerNumNodes[l + 1]; i++) {
					if (l > 0) {
						z += layerNodeErrors[l + 1][i] * edgeWeights[l][j][i];
					} // Of if

					edgeWeightsDelta[l][j][i] = mobp * edgeWeightsDelta[l][j][i]
							+ learningRate * layerNodeErrors[l + 1][i] * layerNodeValues[l][j];
					edgeWeights[l][j][i] += edgeWeightsDelta[l][j][i];
					if (j == layerNumNodes[l] - 1) {
						// Weight adjusting for the offset part.
						edgeWeightsDelta[l][j + 1][i] = mobp * edgeWeightsDelta[l][j + 1][i]
								+ learningRate * layerNodeErrors[l + 1][i];
						edgeWeights[l][j + 1][i] += edgeWeightsDelta[l][j + 1][i];
					} // Of if
				} // Of for i

				
				layerNodeErrors[l][j] = layerNodeValues[l][j] * (1 - layerNodeValues[l][j]) * z;
			} // Of for j
		} // Of while
	}// Of backPropagation

	public static void main(String[] args) {
		int[] tempLayerNodes = { 4, 8, 8, 3 };
		SimpleAnn tempNetwork = new SimpleAnn("C:\\\\Users\\\\ASUS\\\\Desktop\\\\文件\\\\iris.arff", tempLayerNodes, 0.01,
				0.6);

		for (int round = 0; round < 5000; round++) {
			tempNetwork.train();
		} // Of for n

		double tempAccuracy = tempNetwork.test();
		System.out.println("The accuracy is: " + tempAccuracy);
	}// Of main
}// Of class SimpleAnn

运行截图:

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐