Introduction to Neural Networks for C#, Session 14
| Course Name | Introduction to Neural Networks for C# |
| Instructor | jeffheaton |
| Session Title | Review Program 2 |
| Session Number | 14 |
Session Material
I present here my solution for program 2. You can use the link below to download an Visual Studio project for my solution.
Analyze.cs Calculate the min/max for the inputs.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HeatonResearchNeural.Util;
namespace Program2
{
public class Analyze
{
public static String[] COVER_TYPES = {
"Spruce/Fir", // 1
"Lodgepole Pine", // 2
"Ponderosa Pine", // 3
"Cottonwood/Willow", // 4
"Aspen", // 5
"Douglas-fir", // 6
"Krummholz" // 7
};
private double maxElevation;
private double minElevation;
private double maxAspect;
private double minAspect;
private double maxSlope;
private double minSlope;
private double maxHWater;
private double minHWater;
private double maxVWater;
private double minVWater;
private double maxRoad;
private double minRoad;
private double maxShade9;
private double minShade9;
private double maxShade12;
private double minShade12;
private double maxShade3;
private double minShade3;
private int[] coverCount;
private int count;
public void analyze(String filename)
{
this.count = 0;
this.maxElevation = Double.MinValue;
this.minElevation = Double.MaxValue;
this.maxAspect = Double.MinValue;
this.minAspect = Double.MaxValue;
this.maxSlope = Double.MinValue;
this.minSlope = Double.MaxValue;
this.maxHWater = Double.MinValue;
this.minHWater = Double.MaxValue;
; this.maxVWater = -1000;//Double.MIN_VALUE;
this.minVWater = Double.MaxValue;
this.maxShade9 = Double.MinValue;
this.minShade9 = Double.MaxValue;
this.maxShade12 = Double.MinValue;
this.minShade12 = Double.MaxValue;
this.maxShade3 = Double.MinValue;
this.minShade3 = Double.MaxValue;
this.maxRoad = Double.MinValue;
this.minRoad = Double.MaxValue;
this.coverCount = new int[Analyze.COVER_TYPES.Length];
Console.WriteLine("Please wait, performing initial analysis of data.");
ReadCSV csv = new ReadCSV(filename, false);
while (csv.Next())
{
double elevation = Double.Parse(csv.Get(0));
double aspect = Double.Parse(csv.Get(1));
double slope = Double.Parse(csv.Get(2));
double hWater = Double.Parse(csv.Get(3));
double vWater = Double.Parse(csv.Get(4));
double road = Double.Parse(csv.Get(5));
double shade9 = Double.Parse(csv.Get(6));
double shade12 = Double.Parse(csv.Get(7));
double shade3 = Double.Parse(csv.Get(8));
int cover = int.Parse(csv.Get(54));
maxElevation = Math.Max(maxElevation, elevation);
minElevation = Math.Min(minElevation, elevation);
maxAspect = Math.Max(maxAspect, aspect);
minAspect = Math.Min(minAspect, aspect);
maxSlope = Math.Max(maxSlope, slope);
minSlope = Math.Min(minSlope, slope);
maxHWater = Math.Max(maxHWater, hWater);
minHWater = Math.Min(minHWater, hWater);
maxVWater = Math.Max(maxVWater, vWater);
minVWater = Math.Min(minVWater, vWater);
maxRoad = Math.Max(maxRoad, road);
minRoad = Math.Min(minRoad, road);
maxShade9 = Math.Max(maxShade9, shade9);
minShade9 = Math.Min(minShade9, shade9);
maxShade12 = Math.Max(maxShade12, shade12);
minShade12 = Math.Min(minShade12, shade12);
maxShade3 = Math.Max(maxShade3, shade3);
minShade3 = Math.Min(minShade3, shade3);
this.coverCount[cover - 1]++;
count++;
}
Console.WriteLine("Record count: " + count);
Console.WriteLine("Elevation, Max: " + maxElevation);
Console.WriteLine("Elevation, Min: " + minElevation);
Console.WriteLine("Aspect, Max: " + maxAspect);
Console.WriteLine("Aspect, Min: " + minAspect);
Console.WriteLine("Slope, Max: " + maxSlope);
Console.WriteLine("Slope, Min: " + minSlope);
Console.WriteLine("H. Water, Max: " + maxHWater);
Console.WriteLine("H. Water, Min: " + minHWater);
Console.WriteLine("V. Water, Max: " + maxVWater);
Console.WriteLine("V. Water, Min: " + minVWater);
Console.WriteLine("Cover breakdown:");
for (int i = 0; i < Analyze.COVER_TYPES.Length; i++)
{
Console.WriteLine(Analyze.COVER_TYPES[i] + ": " + this.coverCount[i]);
}
}
public double getMaxElevation()
{
return maxElevation;
}
public double getMinElevation()
{
return minElevation;
}
public double getMaxAspect()
{
return maxAspect;
}
public double getMinAspect()
{
return minAspect;
}
public double getMaxSlope()
{
return maxSlope;
}
public double getMinSlope()
{
return minSlope;
}
public int[] getCoverCount()
{
return coverCount;
}
public int getCount()
{
return count;
}
public double getMaxHWater()
{
return maxHWater;
}
public double getMinHWater()
{
return minHWater;
}
public double getMaxVWater()
{
return maxVWater;
}
public double getMinVWater()
{
return minVWater;
}
public double getMaxRoad()
{
return maxRoad;
}
public double getMaxShade9()
{
return maxShade9;
}
public double getMaxShade12()
{
return maxShade12;
}
public double getMaxShade3()
{
return maxShade3;
}
public double getMinRoad()
{
return minRoad;
}
public double getMinShade9()
{
return minShade9;
}
public double getMinShade12()
{
return minShade12;
}
public double getMinShade3()
{
return minShade3;
}
}
}
Config.cs Config information for this program.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Program2
{
public class Config
{
public const String FILENAME = "c:\\data\\covtype.data";
public const int TRAINING_SIZE = 1000;
public const int MAX_HIDDEN_LAYER_1 = 20;
public const int MAX_HIDDEN_LAYER_2 = 20;
public const double LEARNING_RATE = 0.001;
public const double LEARNING_MOMENTUM = 0.3;
public const double TRUE = 1.0;
public const double FALSE = 0.0;
public const int EPOCHS = 500;
public const int COVER_SAMPLES = 2000;
}
}
Convert.cs Convert the data to be fed into the neural network.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HeatonResearchNeural.Util;
namespace Program2
{
public class Convert
{
public static double percent(double value, double max, double min)
{
return (value - min) / (max - min);
}
public static void convert(Analyze analyze, ReadCSV line, double[] input, double[] ideal)
{
double elevation = Double.Parse(line.Get(0));
double aspect = Double.Parse(line.Get(1));
double slope = Double.Parse(line.Get(2));
double hWater = Double.Parse(line.Get(3));
double vWater = Double.Parse(line.Get(4));
double road = Double.Parse(line.Get(5));
double shade9 = Double.Parse(line.Get(6));
double shade12 = Double.Parse(line.Get(7));
double shade3 = Double.Parse(line.Get(8));
int cover = int.Parse(line.Get(54));
// now build a training input
input[0] = percent(elevation, analyze.getMaxElevation(), analyze.getMinElevation());
input[1] = percent(aspect, analyze.getMaxAspect(), analyze.getMinAspect());
input[2] = percent(slope, analyze.getMaxSlope(), analyze.getMinSlope());
input[3] = percent(hWater, analyze.getMaxHWater(), analyze.getMinHWater());
input[4] = percent(vWater, analyze.getMaxVWater(), analyze.getMinVWater());
input[5] = percent(road, analyze.getMaxRoad(), analyze.getMinRoad());
input[6] = percent(shade9, analyze.getMaxShade9(), analyze.getMinShade9());
input[7] = percent(shade12, analyze.getMaxShade12(), analyze.getMinShade12());
input[8] = percent(shade3, analyze.getMaxShade3(), analyze.getMinShade3());
if (ideal != null)
{
for (int i = 0; i < Analyze.COVER_TYPES.Length; i++)
ideal[i] = Config.FALSE;
ideal[cover - 1] = Config.TRUE;
}
}
}
}
Optimize.cs Perform an incremental prune. Try to figure out an optimal number of hidden layers and neurons.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HeatonResearchNeural.Feedforward;
namespace Program2
{
public class Optimize
{
private Analyze analyze;
private Train train;
public FeedforwardNetwork create(int hidden1, int hidden2)
{
int input = this.train.getTraining()[0].Length;
int output = this.train.getIdeal()[0].Length;
FeedforwardNetwork network = new FeedforwardNetwork();
network.AddLayer(new FeedforwardLayer(input));
if( hidden1>0 )
network.AddLayer(new FeedforwardLayer(hidden1));
if( hidden2>0 )
network.AddLayer(new FeedforwardLayer(hidden2));
network.AddLayer(new FeedforwardLayer(output));
return network;
}
public FeedforwardNetwork optimize(Analyze analyze, Train train)
{
FeedforwardNetwork bestNetwork = null;
double bestError = Double.MaxValue;
this.analyze = analyze;
this.train = train;
Console.WriteLine("Searching for best hidden layer setup.");
for(int hidden1=1;hidden1<Config.MAX_HIDDEN_LAYER_1;hidden1++)
{
for(int hidden2=1;hidden2<Config.MAX_HIDDEN_LAYER_2;hidden2++)
{
Console.WriteLine("Trying: hidden1=" + hidden1 + ",hidden2=" + hidden2);
FeedforwardNetwork trial = create(hidden1,hidden2);
double error = train.train(trial);
if( error<bestError)
{
bestNetwork = trial;
bestError = error;
Console.WriteLine("New best network found: hidden1=" + hidden1
+ ", hidden2="+ hidden2 + ", error=" + bestError);
}
}
}
return bestNetwork;
}
}
}
Program2.cs Main entry point for the program.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HeatonResearchNeural.Feedforward;
namespace Program2
{
class Program2
{
static void Main(string[] args)
{
Analyze analyze = new Analyze();
analyze.analyze(Config.FILENAME);
Train train = new Train();
train.build(Config.FILENAME, analyze);
Optimize optimize = new Optimize();
FeedforwardNetwork network = optimize.optimize(analyze, train);
if( network.Layers.Count==3 )
{
FeedforwardLayer hidden1 = network.Layers[1];
Console.WriteLine("The best network: hidden1 = " + hidden1.NeuronCount);
}
else
{
FeedforwardLayer hidden1 = network.Layers[1];
FeedforwardLayer hidden2 = network.Layers[2];
Console.WriteLine("The best network: hidden1 = " + hidden1.NeuronCount
+",hidden2=" + hidden2.NeuronCount);
}
}
}
}
Train.cs Train the neural network for each pruning cycle.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HeatonResearchNeural.Feedforward;
using HeatonResearchNeural.Util;
using HeatonResearchNeural.Feedforward.Train.Backpropagation;
namespace Program2
{
public class Train
{
private double[][] training;
private double[][] ideal;
private int[] coverCount;
double percent(double value, double max, double min)
{
return (value - min) / (max - min);
}
public void build(String filename, Analyze analyze)
{
int trainingSize = Config.COVER_SAMPLES * Analyze.COVER_TYPES.Length;
this.training = new double[Config.TRAINING_SIZE][];//9
this.ideal = new double[Config.TRAINING_SIZE][];// Analyze.COVER_TYPES.length
this.coverCount = new int[Analyze.COVER_TYPES.Length];
int skip = (analyze.getCount() / Config.TRAINING_SIZE) - 1;
int trainingIndex = 0;
ReadCSV csv = new ReadCSV(filename, false);
Console.WriteLine("Generating training set, skip = " + skip);
while (csv.Next() && (trainingIndex < Config.TRAINING_SIZE))
{
int cover = int.Parse(csv.Get(54)) - 1;
if (coverCount[cover] < Config.COVER_SAMPLES)
{
training[trainingIndex] = new double[9];
ideal[trainingIndex] = new double[Analyze.COVER_TYPES.Length];
Convert.convert(analyze, csv, training[trainingIndex],
ideal[trainingIndex]);
coverCount[cover]++;
trainingIndex++;
}
}
}
public double train(FeedforwardNetwork network)
{
// train the neural network
Backpropagation train = new Backpropagation(network,
this.training, this.ideal, Config.LEARNING_RATE,
Config.LEARNING_MOMENTUM);
int epoch = 1;
do
{
train.Iteration();
epoch++;
} while (epoch < Config.EPOCHS);
return train.Error;
}
public double[][] getTraining()
{
return training;
}
public double[][] getIdeal()
{
return ideal;
}
}
}
Videos for this Session
| Video | Title |
|---|---|
![]() | Introduction to Neural Networks for C#(Class 14) |
