using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Threading.Tasks;
using UPImage;
using UPImage.Data;
using ANN.Perceptron;
using ANN.Perceptron.Layers;
using NNControl.Common;
using System.IO;
using System.Drawing.Imaging;
using ANN.Perceptron.ArchiveSerialization;
using ANN.Perceptron.Common;
using ANN.Perceptron.Network;
namespace NNControl.NNTraining
{
public partial class UP_NNTrainingControl : Common.UPTemplateControl
{
bool isDatabaseReady;
bool isTrainingRuning;
bool isCancel;
UPImage.Data.UPDataProvider dataProvider;
bool preview;
NetworkParameters nnParameters;
ConvolutionNetwork network;
CancellationTokenSource tokenSource;
CancellationToken token;
String nntfile;
private List<Char> Letters2 = new List<Char>(36) { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
private List<Char> Letters = new List<Char>(62) { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
private List<Char> Letters1 = new List<Char>(10) { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
private List<Char> Letters3 = new List<Char>(26) { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
's', 't', 'u', 'v', 'w', 'x', 'y', 'z' };
private List<Char> Letters4 = new List<Char>(26) { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };
Task maintask;
public UP_NNTrainingControl()
: base()
{
InitializeComponent();
preview = true;
nnParameters = new NetworkParameters();
network = null;
maintask = null;
Initialization();
}
private void Initialization()
{
isDatabaseReady = false;
isTrainingRuning = false;
isCancel = false;
dataProvider = new UPImage.Data.UPDataProvider();
tokenSource = new CancellationTokenSource();
token = tokenSource.Token;
network = null;
nntfile = null;
}
protected override void AddObject(int iCondition, object value)
{
switch (iCondition)
{
case 0:
//show getting image data commments
this.btnOpen.Image = global::NNControl.Properties.Resources.script__stop_;
btTrain.Enabled = false;
lbCommend.Items.Add((String)value);
toolStripProgressBar1.Visible = true;
if (stopwatch.IsRunning)
{
// Stop the timer; show the start and reset buttons.
stopwatch.Stop();
}
else
{
// Start the timer; show the stop and lap buttons.
stopwatch.Reset();
stopwatch.Start();
}
break;
case 1:
//loading image data successfully
this.btnOpen.Image = global::NNControl.Properties.Resources.btnOpen;
btTrain.Enabled = true;
lbCommend.Items.Add((String)value);
isDatabaseReady = true;
toolStripProgressBar1.Visible = false;
if (stopwatch.IsRunning)
{
// Stop the timer; show the start and reset buttons.
stopwatch.Stop();
}
break;
case 2:
// backpropagation process...
lbCommend.Items.Add((String)value);
break;
case 3:
//Caculation of Hessian
int vl = (int)value;
lbCompleteRatio.Text = String.Format("{0} %", vl);
progressBar.Value = (int)value;
break;
case 4:
// backpropagation completed...
lbCommend.Items.Add((String)value);
BackPropagationThreadsFinished();
break;
case 98:
//cancel loading image data
this.btnOpen.Image = global::NNControl.Properties.Resources.btnOpen;
lbCommend.Items.Add((String)value);
isDatabaseReady = false;
dataProvider.Dispose();
dataProvider = new UPDataProvider();
toolStripProgressBar1.Visible = false;
if (stopwatch.IsRunning)
{
// Stop the timer; show the start and reset buttons.
stopwatch.Stop();
}
break;
case 99:
//loading image data
toolStripProgressBar1.Value = (int)value;
break;
}
}
protected override void AddObjects(int iCondition, object[] values)
{
String comment = "";
int ratio = 0;
switch (iCondition)
{
case 0:
comment = (String)values[0];
lbCommend.Items.Add(comment);
break;
case 98:
TrainingResult result = (TrainingResult)values[0];
ListViewItem item1 = new ListViewItem();
item1.Text = result.Epoch.ToString();
item1.SubItems.Add(new ListViewItem.ListViewSubItem(item1, result.CurrentMSE.ToString()));
item1.SubItems.Add(new ListViewItem.ListViewSubItem(item1, result.MisPattern.ToString()));
item1.SubItems.Add(new ListViewItem.ListViewSubItem(item1, result.Duration.ToString()));
item1.SubItems.Add(new ListViewItem.ListViewSubItem(item1, result.Ratio.ToString()));
item1.SubItems.Add(new ListViewItem.ListViewSubItem(item1, result.EtaLearningRate.ToString()));
item1.SubItems.Add(new ListViewItem.ListViewSubItem(item1, result.Distored.ToString()));
lvResult.Items.Add(item1);
String st = (String)values[1];
lbCommend.Items.Add(st);
//save nnt file
if (nntfile != null)
{
var fsIn = File.OpenWrite(nntfile);
var arIn = new Archive(fsIn, ArchiveOp.store);
network.Serialize(arIn);
fsIn.Close();
}
break;
case 99:
ratio = (int)values[0];
progressBar.Value = ratio;
int pattern = (int)values[1];
lbPatternNo.Text = pattern.ToString();
uint misCount = (uint)values[2];
labelMisCount.Text = misCount.ToString();
double dMSE = (double)values[3];
labelMSE.Text = dMSE.ToString();
int pt = (int)values[5];
lbCompleteRatio.Text = String.Format("{0} %", ratio);
lbAccurate.Text = String.Format("{0} %", (double)(pattern - misCount) * 100 / pattern);
if (pattern % 20 == 0)
{
char label = (char)values[4];
labelChar.Text = label.ToString();
byte[] data = dataProvider.ByteImagePatterns[pt].Image;
Bitmap bmp = CopyDataToBitmap(data, new Size(29, 29));
pictureBox1.Image = (Image)bmp;
}
break;
}
}
private void btnPreview_Click(object sender, EventArgs e)
{
if (preview)
{
spcMain.Panel2Collapsed = true;
preview = false;
}
else
{
spcMain.Panel2Collapsed = false;
preview = true;
}
}
private void btnOpen_Click(object sender, EventArgs e)
{
if (dataProvider.IsDataStop == true)
{
try
{
FolderBrowserDialog fbd = new FolderBrowserDialog();
// Show the FolderBrowserDialog.
DialogResult result = fbd.ShowDialog();
if (result == DialogResult.OK)
{
bool fn = false;
string folderName = fbd.SelectedPath;
Task[] tasks = new Task[2];
isCancel = false;
dataProvider = new UPImage.Data.UPDataProvider();
tasks[0] = Task.Factory.StartNew(() =>
{
dataProvider.IsDataStop = false;
this.Invoke(DelegateAddObject, new object[] { 0, "Getting image training data, please be patient...." });
dataProvider.GetPatternsFromFiles(folderName); //get patterns with default parameters
dataProvider.IsDataStop = true;
if (!isCancel)
{
this.Invoke(DelegateAddObject, new object[] { 1, "Congatulation! Image training data loaded succesfully!" });
dataProvider.Folder.Dispose();
isDatabaseReady = true;
}
else
{
this.Invoke(DelegateAddObject, new object[] { 98, "Sorry! Image training data loaded fail!" });
}
fn = true;
});
tasks[1] = Task.Factory.StartNew(() =>
{
int i = 0;
while (!fn)
{
Thread.Sleep(100);
this.Invoke(DelegateAddObject, new object[] { 99, i });
i++;
if (i >= 100)
i = 0;
}
});
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
else
{
DialogResult result = MessageBox.Show("Do you really want to cancel this process?", "Cancel loadding Images", MessageBoxButtons.YesNo);
if (result == DialogResult.Yes)
{
dataProvider.IsDataStop = true;
isCancel = true;
}
}
}
void CreateNetwork()
{
network = new ConvolutionNetwork();
//layer 0: inputlayer
network.Layers = new CommonLayer[5];
network.LayerCount = 5;
InputLayer inputlayer = new InputLayer("00-Layer Input", new Size(29, 29));
network.InputDesignedPatternSize = new Size(29, 29);
inputlayer.Initialize();
network.Layers[0] = inputlayer;
ConvolutionSupSamplingLayer convlayer = new ConvolutionSupSamplingLayer("01-Layer ConvolutionalSubsampling", inputlayer, new Size(13, 13), 6, 5);
convlayer.Initialize();
network.Layers[1] = convlayer;
convlayer = new ConvolutionSupSamplingLayer("02-Layer ConvolutionalSubsampling", convlayer, new Size(5, 5), 60, 5);
convlayer.Initialize();
network.Layers[2] = convlayer;
FullConnectedLayer fulllayer = new FullConnectedLayer("03-Layer FullConnected", convlayer, 100);
fulllayer.Initialize();
network.Layers[3] = fulllayer;
OutputLayer outputlayer = new OutputLayer("04-Layer Output", fulllayer, Letters1.Count, true);
outputlayer.Initialize();
network.Layers[4] = outputlayer;
network.TagetOutputs = Letters1;
}
void CreateNetwork1()
{
network = new ConvolutionNetwork();
//layer 0: inputlayer
network.Layers = new CommonLayer[8];
network.LayerCount = 8;
InputLayer inputlayer = new InputLayer("00-Layer Input", new Size(32, 32));
network.InputDesignedPatternSize = new Size(32, 32);
inputlayer.Initialize();
network.Layers[0] = inputlayer;
ConvolutionLayer convlayer = new ConvolutionLayer("01-Layer Convolutional", inputlayer, 10, 5);
convlayer.Initialize();
network.Layers[1] = convlayer;
SamplingLayer samplinglayer = new SamplingLayer("02-Layer Sampling", convlayer);
samplinglayer.Initialize();
network.Layers[2] = samplinglayer;
convlayer = new ConvolutionLayer("03-Layer Convolutional", samplinglayer, 50, 5);
convlayer.Initialize();
network.Layers[3] = convlayer;
samplinglayer = new SamplingLayer("04-Layer Sampling", convlayer);
samplinglayer.Initialize();
network.Layers[4] = samplinglayer;
FullConnectedLayer fulllayer = new FullConnectedLayer("05-Layer FullConnected", samplinglayer, 200);
fulllayer.Initialize();
network.Layers[5] = fulllayer;
fulllayer = new FullConnectedLayer("06-Layer FullConnected", fulllayer, 100);
fulllayer.Initialize();
network.Layers[6] = fulllayer;
OutputLayer outputlayer = new OutputLayer("05-Layer Output", fulllayer, Letters3.Count, true);
outputlayer.Initialize();
network.Layers[7] = outputlayer;
network.TagetOutputs = Letters3;
network.UnknownOuput = '?';
}
private void btTrain_Click(object sender, EventArgs e)
{
if (isDatabaseReady && !isTrainingRuning)
{
TrainingParametersForm form = new TrainingParametersForm();
form.Parameters = nnParameters;
DialogResult result = form.ShowDialog();
if (result == DialogResult.OK)
{
nnParameters = form.Parameters;
ByteImageData[] dt = new ByteImageData[dataProvider.ByteImagePatterns.Count];
dataProvider.ByteImagePatterns.CopyTo(dt);
nnParameters.RealPatternSize = dataProvider.PatternSize;
if (network == null)
{
CreateNetwork(); //create network for training
NetworkInformation();
}
var ntraining = new PatternTraining(network, dt, nnParameters, true, this);
tokenSource = new CancellationTokenSource();
token = tokenSource.Token;
this.btTrain.Image = global::NNControl.Properties.Resources.Stop_sign;
this.btLoad.Enabled = false;
this.btnOpen.Enabled = false;
this.btCreateNetwork.Enabled = false;
maintask = Task.Factory.StartNew(() =>
{
if (stopwatch.IsRunning)
{
// Stop the timer; show the start and reset buttons.
stopwatch.Stop();
}
else
{
// Start the timer; show the stop and lap buttons.
stopwatch.Reset();
stopwatch.Start();
}
isTrainingRuning = true;
ntraining.BackpropagationThread(token);
if (token.IsCancellationRequested)
{
String s = String.Format("BackPropagation is canceled");
this.Invoke(this.DelegateAddObject, new Object[] { 4, s });
token.ThrowIfCancellationRequested();
}
}, token);
}
}
else
{
tokenSource.Cancel();
}
}
void BackPropagationThreadsFinished()
{
if (isTrainingRuning)
{
var msResult = MessageBox.Show("Do you want to save Neural Network data ?", "Save Neural Network Data", MessageBoxButtons.OKCancel);
if (msResult == DialogResult.OK)
{
using (var saveFileDialog1 = new System.Windows.Forms.SaveFileDialog { Filter = "Neural network parameters file (*.nnt)|*.nnt", Title = "Save Neural network File" })
{
var rs = saveFileDialog1.ShowDialog();
if (rs == DialogResult.OK)
{
var fsIn = saveFileDialog1.OpenFile();
var arIn = new Archive(fsIn, ArchiveOp.store);
network.Serialize(arIn);
fsIn.Close();
}
}
}
isTrainingRuning = false;
this.btTrain.Image = global::NNControl.Properties.Resources.btnNext;
this.btLoad.Enabled = true;
this.btnOpen.Enabled = true;
this.btCreateNetwork.Enabled = true;
if (stopwatch.IsRunning)
{
// Stop the timer; show the start and reset buttons.
stopwatch.Stop();
}
}
return;
}
private void btLoad_Click(object sender, EventArgs e)
{
using (var OpenFileDialog1 = new System.Windows.Forms.OpenFileDialog { Filter = "Neural network parameters file (*.nnt)|*.nnt", Title = "Load Neural network File" })
{
if (OpenFileDialog1.ShowDialog() == DialogResult.OK)
{
if (network != null)
{
network = null;
}
network = new ConvolutionNetwork();
nntfile = OpenFileDialog1.FileName;
var fsIn = OpenFileDialog1.OpenFile();
var arIn = new Archive(fsIn, ArchiveOp.load);
network.Serialize(arIn);
fsIn.Close();
//UpdateNetworkInfor(network);
NetworkInformation();
}
}
}
void UpdateNetworkInfor(ConvolutionNetwork nw)
{
if (nw.LayerCount == 6)
{
nw.Layers[0].LayerType = LayerTypes.Input;
nw.Layers[1].LayerType = LayerTypes.ConvolutionalSubsampling;
nw.Layers[2].LayerType = LayerTypes.ConvolutionalSubsampling;
nw.Layers[3].LayerType = LayerTypes.FullyConnected;
nw.Layers[4].LayerType = LayerTypes.FullyConnected;
nw.Layers[5].LayerType = LayerTypes.Output;
}
}
public Bitmap CopyDataToBitmap(byte[] data, Size size)
{
//Here create the Bitmap to the know height, width and format
Bitmap bmp = new Bitmap(size.Width, size.Height, PixelFormat.Format8bppIndexed);
ColorPalette ncp = bmp.Palette;
for (int i = 0; i < 256; i++)
ncp.Entries[i] = Color.FromArgb(255, i, i, i);
bmp.Palette = ncp;
//Create a BitmapData and Lock all pixels to be written
BitmapData bmpData = bmp.LockBits(
new Rectangle(0, 0, bmp.Width, bmp.Height),
ImageLockMode.WriteOnly, bmp.PixelFormat);
int bytes = Math.Abs(bmpData.Stride) * bmp.Height;
byte[] rgbValues = new byte[bytes];
for (int i = 0; i < bytes; i++ )
{
rgbValues[i] = 255;
}
int bmpWidth = bmp.Width;
int bmpHeight = bmp.Height;
//
/*TODO: Check potentially-changing upper bound expression "gsBitmap.Height" which is now called only *once*,
to ensure the new Parallel.For call matches behavior in the original for-loop
(where this upper bound expression had previously been evaluated at the start of *every* loop iteration).*/
Parallel.For(0, bmpHeight, (h, loopstate) =>
{
for (int w = 0; w < bmpWidth; w++)
{
rgbValues[h * bmpData.Stride + w] = data[h * bmpWidth + w];
}
});
//Copy the data from the byte array into BitmapData.Scan0
System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, bmpData.Scan0, rgbValues.Length);
//Unlock the pixels
bmp.UnlockBits(bmpData);
//Return the bitmap
return bmp;
}
private void NetworkInformation()
{
lvNetwork.Items.Clear();
lvNetwork.Groups.Clear();
foreach (var layer in network.Layers)
{
String label = layer.Label;
ListViewGroup lvgroup = new ListViewGroup(label);
lvNetwork.Groups.Add(lvgroup);
String[] itemTexts = new String[6];
int neurons = layer.NeuronCount;
itemTexts[0] = neurons.ToString();
itemTexts[1] = layer.FeatureMapSize.ToString();
itemTexts[2] = layer.FeatureMapCount.ToString();
itemTexts[3] = layer.WeightCount.ToString();
itemTexts[4] = (layer.NeuronCount * layer.Neurons[0].ConnectionCount).ToString();
switch (layer.LayerType)
{
case LayerTypes.Input:
itemTexts[5] = "Input Layer";
break;
case LayerTypes.ConvolutionalSubsampling:
itemTexts[5] = "Conv Layer";
break;
case LayerTypes.FullyConnected:
itemTexts[5] = "Full Connected Layer";
break;
case LayerTypes.Output:
itemTexts[5] = "Output Layer";
break;
}
ListViewItem item = new ListViewItem(itemTexts);
lvNetwork.Items.Add(item);
item.Group = lvgroup;
}
}
private void timerMain_Tick(object sender, EventArgs e)
{
if (stopwatch.IsRunning)
{
// Get the elapsed time as a TimeSpan value.
TimeSpan ts = stopwatch.Elapsed;
// Format and display the TimeSpan value.
toolStripStatusLabel1.Text = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
ts.Hours, ts.Minutes, ts.Seconds,
ts.Milliseconds / 10);
// If the user has just clicked the "Lap" button,
// then capture the current time for the lap time.
}
}
private void btClear_Click(object sender, EventArgs e)
{
lvNetwork.Items.Clear();
lbCommend.Items.Clear();
}
private void btCreateNetwork_Click(object sender, EventArgs e)
{
CreateNetworkForm mForm = new CreateNetworkForm();
DialogResult result = mForm.ShowDialog();
if (result == DialogResult.OK)
{
network = mForm.Network;
NetworkInformation();
}
}
}
}