This is my simple implementation of BP algorithm for MLP classification.(seems not so exhaustive :D)
(InputUnits:alternative hiddenUnits:alternative outputUnit:1,)
package bpSolve;
import java.util.Random;
import java.io.*;
public class BackPropagaion {
/**
* BP Algorithm Para:InputLayerNo,HiddenLayerNo
*
*
* @Jay
*/
private static int OutputNo = 1;
public static void main(String[] args) throws Throwable, IOException {
// get the HiddenUnits Number
String s1 = "1.Please Input the Number of HiddenLayerUnits:";
String s2 = "2.Please Input the Learning-Rate:";
int inputNo = 2;// by default
int hiddenNo = 0;
double rate = 0;
hiddenNo = Integer.parseInt(readIn(s1));
rate = Double.parseDouble(readIn(s2));
// get the SampleDatas from given file
String s3 = "Please input the SampleData Path:";
String Path = null;
Path = readIn(s3);
// get the sample and Targe
int Groups = 10; // the number of smaple groups
int Dimension = 2; // the number of Dimension
int i = 0;
double[][] sample = new double[Groups][Dimension];
double[] target = new double[Groups];
String Content = null;
FileReader fr = new FileReader(Path);
BufferedReader buffer = new BufferedReader(fr);
while ((Content = buffer.readLine()) != null) {
String[] str = Content.split(",");
int L = str.length;
for (int d = 0; d < L - 1; d++) {
sample[i][d] = Double.parseDouble(str[d]);
}
target[i] = Double.parseDouble(str[L - 1]);
i += 1;
}
// firstly to scale all the sample data
for (int k = 0; k < Dimension; k++) {
double[] array = new double[Groups];
for (int m = 0; m < Groups; m++) {
array[m] = sample[m][k];
}
double[] scale_array = scale(array);
for (int c = 0; c < Groups; c++) {
sample[c][k] = scale_array[c];
}
}
// begin the BackPropagation
BackPropagation(sample, target, rate, inputNo, OutputNo, hiddenNo);
}
// To do backpropagation
public static void BackPropagation(double[][] sample, double[] target,
double rate, int inputNo, int outputNo, int hiddenNo) {
// set the deault error to 0
double Error = 0;
// here we set a value to control the error scope, if the network error
// is larger than it,then run the circle again until it's lower than it.
double E = 0.01;
Error = E + 1;
// ----------------initialization of the weights-------------
// weights of InputLayer
double[] w_input = intial(inputNo);
// weights of HiddenLayer to InputLayer
double[][] w_hidden = intial(inputNo, hiddenNo);
// weights between OutputLayer and HiddenLayer
double[] w_output = intial(hiddenNo);
// network initialization
double[] input_hiddenlayer = new double[hiddenNo];
double[] input_inputlayer = new double[inputNo];
double input_outputlayer;
while (Error > E) {
int K = sample.length;
Error = 0;
// there are together K SampleVectors
for (int p = 0; p < K; p++) {
// p is the Pth Vector
/*-------------------Procedure of ForwardPropagation------------------*/
// calculation of input of the inputlayerUnits
for (int i = 0; i < inputNo; i++) {
input_inputlayer[i] = w_input[i] * sample[p][i];
}
// calculation of input of the hiddenlayerUnits
for (int i = 0; i < hiddenNo; i++) {
double temp = 0;
for (int j = 0; j < inputNo; j++) {
temp = temp + sigmoid(input_inputlayer[j])
* w_hidden[i][j];
}
input_hiddenlayer[i] = temp;
}
// calculation of input of the outputlayerUnits
double sum_hidden = 0;
for (int i = 0; i < hiddenNo; i++) {
sum_hidden = sum_hidden + w_output[i]
* sigmoid(input_hiddenlayer[i]);
}
input_outputlayer = sum_hidden;
/*-------------------Procedure of BackPropagation------------------*/
// calculate the delta of outputlayerUnits
double delta_output;
delta_output = target[p] - sgn(input_outputlayer);
// calculate the error of the networkoutput
double error_K = 0.5 * delta_output * delta_output;
Error = Error + error_K;
// calculate the delta of hiddenlayerUnits
double[] delta_hidden = new double[hiddenNo];
for (int i = 0; i < hiddenNo; i++) {
double derivative_hidden = sigmoid(input_hiddenlayer[i])
* (1 - sigmoid(input_hiddenlayer[i]));
delta_hidden[i] = w_output[i] * delta_output
* derivative_hidden;
}
// calculate the delta of inputlayerUnits
double[] delta_input = new double[inputNo];
for (int i = 0; i < inputNo; i++) {
double temp = 0;
for (int j = 0; j < hiddenNo; j++) {
temp = temp + w_hidden[j][i] * delta_hidden[j];
}
delta_input[i] = sigmoid(input_inputlayer[i])
* (1 - sigmoid(input_inputlayer[i])) * temp;
}
/*-------------------Regulation of the Weights------------------*/
// WeightRegulation of outputlayer
for (int i = 0; i < hiddenNo; i++) {
w_output[i] = w_output[i] + rate * delta_output
* sigmoid(input_hiddenlayer[i]);
}
// WeightRegulation of hiddenlayer
for (int i = 0; i < hiddenNo; i++) {
for (int j = 0; j < inputNo; j++) {
w_hidden[i][j] = w_hidden[i][j] + rate
* delta_hidden[i]
* sigmoid(input_inputlayer[j]);
}
}
// WeightRegulation of inputlayer
for (int i = 0; i < inputNo; i++) {
w_input[i] = w_input[i] + rate * delta_input[i]
* sample[p][i];
}
}
System.out.println(Error);
}
}
// to read Input on the monitor
public static String readIn(String display) throws IOException {
System.out.println(display);
BufferedReader buffer = new BufferedReader(new InputStreamReader(
System.in));
String string = buffer.readLine();
return string;
}
// outputlayer model function
public static double sgn(double x) {
if (x > 0)
return 1;
else
return -1;
}
// hiddenlayer model function
public static double sigmoid(double x) {
double g;
g = 1 / (1 + Math.exp(-x));
return (double) g;
}
// To generate the weights of inputlayer and outputlayer
public static double[] intial(int M) {
Random r = new Random();
double weight[] = new double[M];
for (int i = 0; i < M; i++) {
weight[i] = r.nextDouble() - 0.5;
}
return weight;
}
// to generate the random weights of hiddenlayer between[-0.5,0.5],
// N: number of forwardlayer units, M: number of backwardlayer units.
public static double[][] intial(int M, int N) {
Random r = new Random();
double weight[][] = new double[N][M];
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
weight[i][j] = r.nextDouble() - 0.5;
}
}
return weight;
}
// to get the scaled array between [0.1]
public static double[] scale(double[] original) {
int length = original.length;
double[] scale = new double[length];
for (int i = 0; i < length; i++) {
scale[i] = (original[i] - min(original)
/ (max(original) - min(original)));
}
return scale;
}
// to generate the maximum of the array
private static double max(double[] array) {
double max = array[0];
for (int i = 0; i < array.length - 1; i++) {
if (max <= array[i + 1])
max = array[i + 1];
}
return max;
}
// to generate the minimum of the array
private static double min(double[] array) {
double min = array[0];
for (int i = 0; i < array.length - 1; i++) {
if (min >= array[i + 1])
min = array[i + 1];
}
return min;
}
}
the parameters must be correctly set and the sampledata format must also be right, such as
1.6032,3.2925,-1
2.5699,1.2673,-1
2.156,3.0256,-1
0.72343,2.6734,-1
1.2626,0.66255,1
2.2493,3.0249,-1
3.2421,1.0224,-1
3.2475,1.1921,-1
2.0848,3.6309,-1
1.1158,0.94013,1

没有评论:
发表评论