Hello all,
I am in the middle of making a most simplest generic algorithm for the multiple input and multiple output for training ANN using Backpropagation - but I have some non-converging error problem. Could someone go over my code and see what I did wrong?
FYI - I am not using the momentum method. i.e, I set that to 1.
And, the network is 3-6-2 (input-hidden_node-output)
Thanks
Here is the code,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BackProbagationAlgor
{
class Program
{
static double w = 0.02;
static double Emax = 0.0001;
static double E = 0;
static double zeta = 0.02;
static int numberInputNeuron = 3;
static int numberHiddenNodeInEachLayer = 6;
static int numberOutputNeuron = 2;
static int numberTrainingPatterns = 4;
static double[] errThisPat = new double[numberOutputNeuron];
static int patNum = 0;
static double[] deltaO = new double[numberOutputNeuron];
static double[] deltaH = new double[numberHiddenNodeInEachLayer];
static int epoch = 0;
static void Main(string[] args)
{
try
{
epoch = 0;
initData();
while (errThisPat[0] >= Emax || errThisPat[1] > Emax || epoch < 1)
{
for (int i = 0; i < numberTrainingPatterns; i++)
{
patNum = i;
trainData();
}
epoch++;
}
for (int i = 0; i < numberOutputNeuron; i++)
{
for (int j = 0; j < numberHiddenNodeInEachLayer; j++)
{
Console.WriteLine("Weight" + i + j + " is " + weightHO[i, j]);
}
}
for (int k = 0; k < numberHiddenNodeInEachLayer; k++)
{
for (int l = 0; l < numberInputNeuron; l++)
{
Console.WriteLine("Weight" + k + l + " is " + weightIH[k, l]);
}
}
}
catch
{
Console.WriteLine("Eror at Main");
}
tryOutPut();
Console.Read();
}
static double[,] input = new double[numberTrainingPatterns, numberInputNeuron];
static double[,] output = new double[numberTrainingPatterns, numberOutputNeuron];
static double[,] try_input = new double[4, numberInputNeuron];
static double[,] try_output = new double[4, numberOutputNeuron];
static double[] outputOfEachNuron = new double[numberHiddenNodeInEachLayer];
static double[,] weightIH = new double[numberHiddenNodeInEachLayer, numberInputNeuron];
static double[,] weightHO = new double[numberOutputNeuron, numberHiddenNodeInEachLayer];
static double[,] outputTemp = new double[numberHiddenNodeInEachLayer, numberOutputNeuron];
static Random randNum = new Random();
public static void initData()
{
for (int i = 0; i < numberOutputNeuron; i++)
{
errThisPat[i] = 1;
for (int j = 0; j < numberHiddenNodeInEachLayer; j++)
{
weightHO[i, j] = randNum.NextDouble();
}
}
for (int k = 0; k < numberHiddenNodeInEachLayer; k++)
{
for (int l = 0; l < numberInputNeuron; l++)
{
weightIH[k, l] = randNum.NextDouble();
}
}
input[0, 0] = 1;
input[0, 1] = -1;
input[0, 2] = 1;
output[0, 0] = 1;
output[0, 1] = 1;
input[1, 0] = -1;
input[1, 1] = 1;
input[1, 2] = 1;
output[1, 0] = 1;
output[1, 1] = 1;
input[2, 0] = 1;
input[2, 1] = 1;
input[2, 2] = 1;
output[2, 0] = -1;
output[2, 1] = -1;
input[3, 0] = -1;
input[3, 1] = -1;
input[3, 2] = 1;
output[3, 0] = -1;
output[3, 1] = -1;
}
static int flag = 0;
public static void trainData()
{
try
{
for (int i = 0; i < numberHiddenNodeInEachLayer; i++)
{
outputOfEachNuron[i] = 0;
for (int j = 0; j < numberInputNeuron; j++)
{
outputOfEachNuron[i] = outputOfEachNuron[i] + (input[patNum, j] * weightIH[i, j]);
}
outputOfEachNuron[i] = Math.Tanh(outputOfEachNuron[i]);
}
for (int i = 0; i < numberOutputNeuron; i++)
{
flag = i;
double outputTempHolder = 0;
for (int j = 0; j < numberHiddenNodeInEachLayer; j++)
{
outputTempHolder = outputTempHolder + outputOfEachNuron[j] * weightHO[i, j];
}
errThisPat[i] = 0.5 * Math.Pow(output[patNum, i] - outputTempHolder, 2) + E;
Console.WriteLine("Epoch = " + epoch + " EMS" + i + " = " + errThisPat[i]);
deltaO[i] = (1 + outputTempHolder) * (1 - outputTempHolder);
updateWeightHO(deltaO[i], i);
}
updateWeightIH();
}
catch
{
Console.WriteLine("error");
}
}
public static void updateWeightHO(double _delta, int n)
{
try
{
for (int j = 0; j < numberHiddenNodeInEachLayer; j++)
{
double weightChangeHO = zeta * _delta * outputOfEachNuron[j];
weightHO[n, j] = weightChangeHO + weightHO[n, j];
}
}
catch { Console.WriteLine("Eror updateWeightHO"); }
}
public static void updateWeightIH()
{
try
{
for (int i = 0; i < numberHiddenNodeInEachLayer; i++)
{
double temp = (1 + outputOfEachNuron[i]) * (1 - outputOfEachNuron[i]);
deltaH[i] = 0;
for (int j = 0; j < numberOutputNeuron; j++)
{
deltaH[i] += weightHO[j, i] * deltaO[j];
}
deltaH[i] = deltaH[i] * temp;
}
for (int k = 0; k < numberInputNeuron; k++)
{
for (int l = 0; l < numberHiddenNodeInEachLayer; l++)
{
weightIH[l, k] = (zeta * deltaH[l] * input[patNum, k]) + weightIH[l, k];
}
}
}
catch { Console.WriteLine("Eror updateWeightIH"); }
}
static double[,] tryouput = new double[4, numberOutputNeuron];
public static void tryOutPut()
{
try_input[0, 0] = 1;
try_input[0, 1] = -1;
try_input[0, 2] = 1;
try_output[0, 0] = 1;
try_output[0, 1] = 1;
try_input[1, 0] = -1;
try_input[1, 1] = 1;
try_input[1, 2] = 1;
try_output[1, 0] = 1;
try_output[1, 1] = 1;
try_input[2, 0] = 1;
try_input[2, 1] = 1;
try_input[2, 2] = 1;
try_output[2, 0] = -1;
try_output[2, 1] = -1;
try_input[3, 0] = -1;
try_input[3, 1] = -1;
try_input[3, 2] = 1;
try_output[3, 0] = -1;
try_output[3, 1] = -1;
int tryoutputPat = 4;
for (int x = 0; x < tryoutputPat; x++)
{
for (int i = 0; i < numberHiddenNodeInEachLayer; i++)
{
outputOfEachNuron[i] = 0;
for (int j = 0; j < numberInputNeuron; j++)
{
outputOfEachNuron[i] = outputOfEachNuron[i] + (input[x, j] * weightIH[i, j]);
}
outputOfEachNuron[i] = Math.Tanh(outputOfEachNuron[i]);
}
for (int i = 0; i < numberOutputNeuron; i++)
{
flag = i;
double outputTempHolder = 0;
for (int j = 0; j < numberHiddenNodeInEachLayer; j++)
{
outputTempHolder = outputTempHolder + outputOfEachNuron[j] * weightHO[i, j];
Console.WriteLine("");
}
tryouput[x, i] = outputTempHolder;
Console.WriteLine(" Set " + x + ": Target " + i + " is: " + try_output[x, i] + " ANN is " + tryouput[x, i]);
}
}
}
}
}