Kristanto, A. 2004.Jaringan Syaraf Tiruan. Gaya Media. Yogyakarta
Siang, J.J. Andri. 2005.Jaringan Syaraf Tiruan Dan Pemrogramannya Mengunakan Matlab. Andi. Yogyakarta.
Kusumadewi, S. 2006.Membangun Jaringan Syaraf Tiruan Menggunakan Matlab & Excellink.Graha Ilmu, Yogyakarta.
Silvia, E. 2007. Disain Jaringan Syaraf Tiruan Untuk Prediksi Kualitas Gula Kristal Putih. Tesis Sekolah Pascasarjana Institut Pertanian Bogor.
Agustinus, N. 1997. Pengolahan Gambar Secara Digital. Elex Media Komputindo. Jakarta.
Aryanto, M. 2010. IP Camera dan Aplikasinya. Penerbit Elexmedia Komputindo. Jakarta.
Azikin, A. 2005. Kamera Pengawas Berbasis Open Source, Penerbit Elexmedia Komputindo, Jakarta.
Luthfie, S.N. 2010. Implementasi Jaringan Saraf Tiruan Backpropagation Pada Aplikasi Pengenalan Wajah Dengan Jarak Yang Berbeda Menggunakan MATLAB 7.0, Jurnal Teknik Informatika. Gunadarma. Jakarta 2010.
Yuniarti, A., Aufa, N., & Amaliah, B. 2011. Pengenalan Merek Mobil Berbasis Deteksi Plat Dan Logo Menggunakan Jaringan Syaraf Probabilistik. Konferensi Nasional Sistem dan Informatika 2011; Bali, November 12, 2011.
Fitriawan, H., Pucu, O. & Baptista Y. 2012. Identifikasi Plat Nomor Kendaraan Secara Off-Line Berbasis Pengolahan Citra Dan Jaringan Syaraf Tiruan. Jurnal Rekayasa dan Teknologi Elektro Volume: 6, No.2 Mei 2012.
1. Menu Utama using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace LicensePlateRecognition {
public partial class Menu : Form
{
private ToolStripMenuItem pengenalanToolStripMenuItem;
private ToolStripMenuItem helpToolStripMenuItem;
private ToolStripMenuItem aboutToolStripMenuItem;
private ToolStripMenuItem exitToolStripMenuItem;
private PictureBox pictureBox1;
private ToolStripMenuItem algoritmaBackpropagationToolStripMenuItem;
private ToolStripMenuItem algoritmaLVQToolStripMenuItem;
private MenuStrip menuStrip1;
public Menu() {
InitializeComponent(); }
private void InitializeComponent() {
System.ComponentModel.ComponentResourceManager resources = new
System.ComponentModel.ComponentResourceManager(typeof(Menu));
this.menuStrip1 = new System.Windows.Forms.MenuStrip();
this.pengenalanToolStripMenuItem = new
System.Windows.Forms.ToolStripMenuItem();
this.algoritmaBackpropagationToolStripMenuItem = new
System.Windows.Forms.ToolStripMenuItem();
this.algoritmaLVQToolStripMenuItem = new
System.Windows.Forms.ToolStripMenuItem();
this.helpToolStripMenuItem = new
System.Windows.Forms.ToolStripMenuItem();
this.aboutToolStripMenuItem = new
System.Windows.Forms.ToolStripMenuItem();
this.exitToolStripMenuItem = new
System.Windows.Forms.ToolStripMenuItem();
this.pictureBox1 = new System.Windows.Forms.PictureBox();
this.menuStrip1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
this.SuspendLayout();
this.menuStrip1.Items.AddRange(new
System.Windows.Forms.ToolStripItem[] {
this.pengenalanToolStripMenuItem,
this.helpToolStripMenuItem,
this.aboutToolStripMenuItem,
this.exitToolStripMenuItem});
this.menuStrip1.Name = "menuStrip1";
this.menuStrip1.Size = new System.Drawing.Size(750, 24);
this.menuStrip1.TabIndex = 0;
this.menuStrip1.Text = "menuStrip1";
this.menuStrip1.ItemClicked += new
System.Windows.Forms.ToolStripItemClickedEventHandler(this.menuStrip1_ItemClicked) ;
this.pengenalanToolStripMenuItem.DropDownItems.AddRange(new
System.Windows.Forms.ToolStripItem[] {
this.algoritmaBackpropagationToolStripMenuItem,
this.algoritmaLVQToolStripMenuItem});
this.pengenalanToolStripMenuItem.Name = "pengenalanToolStripMenuItem";
this.pengenalanToolStripMenuItem.Size = new System.Drawing.Size(81, 20);
this.pengenalanToolStripMenuItem.Text = "Pengenalan";
this.pengenalanToolStripMenuItem.Click += new
System.EventHandler(this.pengenalanToolStripMenuItem_Click);
this.algoritmaBackpropagationToolStripMenuItem.Name =
"algoritmaBackpropagationToolStripMenuItem";
this.algoritmaBackpropagationToolStripMenuItem.Size = new
System.Drawing.Size(220, 22);
this.algoritmaBackpropagationToolStripMenuItem.Text = "Algoritma Backpropagation";
this.algoritmaBackpropagationToolStripMenuItem.Click += new
System.EventHandler(this.algoritmaBackpropagationToolStripMenuItem_Click);
this.algoritmaLVQToolStripMenuItem.Name =
"algoritmaLVQToolStripMenuItem";
this.algoritmaLVQToolStripMenuItem.Size = new System.Drawing.Size(220, 22);
this.algoritmaLVQToolStripMenuItem.Text = "Algoritma LVQ";
this.algoritmaLVQToolStripMenuItem.Click += new
System.EventHandler(this.algoritmaLVQToolStripMenuItem_Click);
this.helpToolStripMenuItem.Name = "helpToolStripMenuItem";
this.helpToolStripMenuItem.Size = new System.Drawing.Size(44, 20);
this.helpToolStripMenuItem.Text = "Help";
this.helpToolStripMenuItem.Click += new
System.EventHandler(this.helpToolStripMenuItem_Click);
this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem";
this.aboutToolStripMenuItem.Size = new System.Drawing.Size(52, 20);
this.aboutToolStripMenuItem.Text = "About";
this.aboutToolStripMenuItem.Click += new
System.EventHandler(this.aboutToolStripMenuItem_Click);
this.exitToolStripMenuItem.Name = "exitToolStripMenuItem";
this.exitToolStripMenuItem.Size = new System.Drawing.Size(37, 20);
this.exitToolStripMenuItem.Text = "Exit";
this.exitToolStripMenuItem.Click += new
System.EventHandler(this.exitToolStripMenuItem_Click);
this.pictureBox1.Image =
((System.Drawing.Image)(resources.GetObject("pictureBox1.Image")));
this.pictureBox1.Location = new System.Drawing.Point(12, 27);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(738, 430);
this.pictureBox1.TabIndex = 1;
this.pictureBox1.TabStop = false;
this.ClientSize = new System.Drawing.Size(750, 455);
this.Controls.Add(this.pictureBox1);
this.Controls.Add(this.menuStrip1);
this.MainMenuStrip = this.menuStrip1;
this.Name = "Menu";
this.StartPosition =
System.Windows.Forms.FormStartPosition.CenterScreen;
this.PerformLayout(); }
private void exitToolStripMenuItem_Click(object sender, EventArgs e) {
Dispose(); }
private void pengenalanToolStripMenuItem_Click(object sender, EventArgs e) {
}
private void aboutToolStripMenuItem_Click(object sender, EventArgs e) {
About f1 = new About(); f1.ShowDialog();
f1.Focus(); }
private void helpToolStripMenuItem_Click(object sender, EventArgs e) {
frmHelp f1 = new frmHelp(); f1.ShowDialog();
f1.Focus(); }
private void algoritmaBackpropagationToolStripMenuItem_Click(object
sender, EventArgs e) {
PengenalanPlat f1 = new PengenalanPlat(); f1.ShowDialog();
f1.Focus(); }
private void algoritmaLVQToolStripMenuItem_Click(object sender, EventArgs
e)
{
PengenalanPlatLVQ f1 = new PengenalanPlatLVQ(); f1.ShowDialog();
f1.Focus(); }
private void menuStrip1_ItemClicked(object sender,
ToolStripItemClickedEventArgs e) {
} } }
2. Algoritma LVQ using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using Emgu.CV; using Emgu.CV.Structure; using Emgu.CV.UI; using System.Diagnostics; using Emgu.CV.CvEnum; using System.IO; using System.Linq; using tesseract; namespace LicensePlateRecognition {
public partial class PengenalanPlatLVQ : Form
{
double[] bobot1 = new double[6];
double[] bobot2 = new double[6];
double[,] data = new double[8, 6];
int[] target = new int[8];
double alpha = 0.05;
Int16 maxEpoh = 10;
#region LVQQ
List<Image<Bgr, Byte>> PlateImagesList = new List<Image<Bgr, byte>>();
List<string> PlateTextList = new List<string>();
List<string> lstlicenses = new List<string>();
private List<string> lstimages = new List<string>();
int position = 0;
private TesseractProcessor m_tesseract = null;
private string m_path = Application.StartupPath + @"\data\";
private const string m_lang = "eng";
#endregion #region FormInt public PengenalanPlatLVQ() { InitializeComponent(); } #endregion
private string Ocr(Bitmap image) { m_tesseract.Clear(); m_tesseract.ClearAdaptiveClassifier(); return m_tesseract.Apply(image); } #region button1_Click
private void button1_Click(object sender, EventArgs e) {
lstimages.Clear(); timer1.Enabled = false;
string startupPath = Application.StartupPath;
if (dialog.ShowDialog() == DialogResult.OK) {
string folder = dialog.SelectedPath;
foreach (string fileName in Directory.GetFiles(folder, "*.bmp",
SearchOption.TopDirectoryOnly)) {
lstimages.Add(Path.GetFullPath(fileName)); }
if (lstimages.Count == 0) {
foreach (string fileName in Directory.GetFiles(folder,
"*.jpg", SearchOption.TopDirectoryOnly)) {
lstimages.Add(Path.GetFullPath(fileName)); } } if (lstimages.Count != 0) timer1.Enabled = true; } } } #endregion #region FormLoad
private void LicensePlateRecognitionForm_Load(object sender, EventArgs e) {
lblCount.Text = ""; lblTime.Text = "";
m_tesseract = new TesseractProcessor();
bool succeed = m_tesseract.Init(m_path, m_lang, 3);
if (!succeed) {
MessageBox.Show("Inisialisasi LVQ Gagal");
Application.Exit(); }
m_tesseract.SetVariable("tessedit_char_whitelist", "ABCDEFHKLMNPQRSTUVXYZ-.1234567890").ToString();
System.Environment.CurrentDirectory = System.IO.Path.GetFullPath(m_path); }
#endregion
#region timer1_Tick
private void timer1_Tick(object sender, EventArgs e) { if (position < lstimages.Count) { ProcessImage(lstimages[position]); position++; } else position = 0; } #endregion
{
Image<Bgr, byte> frame = new Image<Bgr, byte>(image); }
#region ProcessImage
public void ProcessImage(string urlImage) {
PlateImagesList.Clear(); lstlicenses.Clear(); PlateTextList.Clear();
Stopwatch watch = Stopwatch.StartNew();
Bitmap img = new Bitmap(urlImage); FindLicensePlate(img);
panel1.Controls.Clear();
if (PlateImagesList.Count > 0) {
Point startPoint = new Point(10, 10);
for (int i = 0; i < PlateImagesList.Count; i++) {
AddLabelAndImage(ref startPoint, "No Plat: " + PlateTextList[i], PlateImagesList[i]);
lblHasil.Text = "No Plat: " + PlateTextList[i]; }
}
watch.Stop(); //stop the timer
lblTime.Text = String.Format("Lama: {0} detik", watch.Elapsed.TotalSeconds);
lblCount.Text = "Data ke :" + position.ToString() + " dari " + lstimages.Count.ToString();
}
private void AddLabelAndImage(ref Point startPoint, String labelText, IImage
image) {
Label label = new Label(); panel1.Controls.Add(label); label.Text = labelText; label.Width = 600; label.Height = 50; label.Location = startPoint; startPoint.Y += label.Height;
ImageBox box = new ImageBox(); panel1.Controls.Add(box); box.ClientSize = image.Size; box.Image = image; box.Location = startPoint; startPoint.Y += box.Height + 10; } #endregion #region LicensePlateRecognition
public void FindLicensePlate(Bitmap image) {
Image<Bgr, byte> frame = new Image<Bgr, byte>(image);
using (Image<Gray, byte> grayframe = new Image<Gray,byte>(image)) {
var faces =
)[0];
foreach (var face in faces) {
Image<Bgr, Byte> tmp = frame.Copy(); tmp.ROI = face.rect;
frame.Draw(face.rect, new Bgr(Color.Blue), 2); PlateImagesList.Add(tmp.Resize(260, 100, Emgu.CV.CvEnum.INTER.CV_INTER_CUBIC, true));
string pl = this.Ocr(tmp.ToBitmap()); PlateTextList.Add(pl);
}
Image<Bgr, Byte> showimg = new Image<Bgr, Byte>(image.Size); showimg = frame.Resize(imageBox1.Width, imageBox1.Height, 0); imageBox1.Image = showimg;
} }
#endregion
private void btnKeluar_Click(object sender, EventArgs e) {
Dispose(); }
private void btnStop_Click(object sender, EventArgs e) {
timer1.Enabled = false; }
private void btnLanjut_Click(object sender, EventArgs e) {
timer1.Enabled = true; }
private void splitContainer1_Panel2_Paint(object sender, PaintEventArgs e) {
}
private double[] updateBobot(double[] bobot, double[] data, double alpha, int
statusTarget) {
double[] temp = new double[bobot.Length];
//status target ==1 sama dengan menambah
if (statusTarget == 1) {
for (int i = 0; i < bobot.Length; i++) {
temp[i] = bobot[i] + (alpha * (data[i] - bobot[i])); }
}
else
{
for (int i = 0; i < bobot.Length; i++) {
temp[i] = bobot[i] - (alpha * (data[i] - bobot[i])); }
}
return temp; }
private Int16 lvq(double[] bobot1, double[] bobot2, double[] data, int
temTarget) {
double totalBobot1 = 0;
double totalBobot2 = 0;
//calculate bobot 1
for (int i = 0; i < bobot1.Length; i++) {
totalBobot1 = totalBobot1 + Math.Pow((data[i] - bobot1[i]), 2); totalBobot2 = totalBobot2 + Math.Pow((data[i] - bobot2[i]), 2); }
// win kelas satu
if (Math.Pow(totalBobot1, 0.5) <= Math.Pow(totalBobot2, 0.5)) {
if (temTarget == 1) {
return 1; }
else //target sama dengan 2
{
return 3; }
}
else // Win kelas dua
{
//target sama dengan 1
if (temTarget == 2) { return 2; } else { return 4; } } } } } 3. Algoritma backpropagation using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using Emgu.CV; using Emgu.CV.Structure; using Emgu.CV.UI; using System.Diagnostics; using Emgu.CV.CvEnum; using System.IO; using System.Linq; using tesseract;
#region BPP
List<Image<Bgr, Byte>> PlateImagesList = new List<Image<Bgr, byte>>();
List<string> PlateTextList = new List<string>();
List<string> lstlicenses = new List<string>();
private List<string> lstimages = new List<string>();
int position = 0;
private TesseractProcessor m_tesseract = null;
private string m_path = Application.StartupPath + @"\data\";
private const string m_lang = "eng";
#endregion #region FormInt public PengenalanPlat() { InitializeComponent(); } #endregion
private string Ocr(Bitmap image) { m_tesseract.Clear(); m_tesseract.ClearAdaptiveClassifier(); return m_tesseract.Apply(image); } #region button1_Click
private void button1_Click(object sender, EventArgs e) {
lstimages.Clear(); timer1.Enabled = false;
string startupPath = Application.StartupPath;
using (FolderBrowserDialog dialog = new FolderBrowserDialog()) {
dialog.ShowNewFolderButton = false;
dialog.RootFolder = Environment.SpecialFolder.MyComputer;
if (dialog.ShowDialog() == DialogResult.OK) {
string folder = dialog.SelectedPath;
foreach (string fileName in Directory.GetFiles(folder,
"*.bmp", SearchOption.TopDirectoryOnly)) {
lstimages.Add(Path.GetFullPath(fileName)); }
if (lstimages.Count == 0) {
foreach (string fileName in Directory.GetFiles(folder,
"*.jpg", SearchOption.TopDirectoryOnly)) {
lstimages.Add(Path.GetFullPath(fileName)); }
} if (lstimages.Count != 0) timer1.Enabled = true; } } } #endregion #region FormLoad
private void LicensePlateRecognitionForm_Load(object sender, EventArgs e) {
lblCount.Text = ""; lblTime.Text = "";
m_tesseract = new TesseractProcessor();
bool succeed = m_tesseract.Init(m_path, m_lang, 3);
if (!succeed) {
MessageBox.Show("BackPro Gagal proses ...");
Application.Exit(); }
m_tesseract.SetVariable("tessedit_char_whitelist",
"ABCDEFHKLMNPQRSTUVXYZ-.1234567890").ToString(); System.Environment.CurrentDirectory = System.IO.Path.GetFullPath(m_path);
}
#endregion
#region timer1_Tick
private void timer1_Tick(object sender, EventArgs e) { if (position < lstimages.Count) { ProcessImage(lstimages[position]); //BackPro(image); position++; } else position = 0; }
public void BackPro(Bitmap image) {
Image<Bgr, byte> frame = new Image<Bgr, byte>(image); }
#endregion
#region ProcessImage
public void ProcessImage(string urlImage) {
PlateImagesList.Clear(); lstlicenses.Clear(); PlateTextList.Clear();
Stopwatch watch = Stopwatch.StartNew(); // time the detection process
Bitmap img = new Bitmap(urlImage); FindLicensePlate(img);
{
AddLabelAndImage(ref startPoint, "No Plat: " + PlateTextList[i],PlateImagesList[i]);
lblHasil.Text = "No Plat: " + PlateTextList[i]; }
}
watch.Stop(); //stop the timer
lblTime.Text = String.Format("Lama: {0} detik", watch.Elapsed.TotalSeconds);
lblCount.Text = "Data ke :" + position.ToString() + " dari " + lstimages.Count.ToString();
}
private void AddLabelAndImage(ref Point startPoint, String labelText,
IImage image) {
Label label = new Label(); panel1.Controls.Add(label); label.Text = labelText; label.Width = 600; label.Height = 50; label.Location = startPoint; startPoint.Y += label.Height;
ImageBox box = new ImageBox(); panel1.Controls.Add(box); box.ClientSize = image.Size; box.Image = image; box.Location = startPoint; startPoint.Y += box.Height + 10; } #endregion #region LicensePlateRecognition
public void FindLicensePlate(Bitmap image) {
Image<Bgr, byte> frame = new Image<Bgr, byte>(image);
using (Image<Gray, byte> grayframe = new Image<Gray,byte>(image)) {
var faces =
grayframe.DetectHaarCascade(
new HaarCascade(Application.StartupPath +
"\\output-hv-33-x25.xml"), 1.1, 8,
HAAR_DETECTION_TYPE.DO_CANNY_PRUNING,
new Size(0, 0) )[0];
foreach (var face in faces) {
Image<Bgr, Byte> tmp = frame.Copy(); tmp.ROI = face.rect;
frame.Draw(face.rect, new Bgr(Color.Red), 3); PlateImagesList.Add(tmp.Resize(260, 100, Emgu.CV.CvEnum.INTER.CV_INTER_CUBIC, true));
string pl = this.Ocr(tmp.ToBitmap()); PlateTextList.Add(pl);
}
Image<Bgr, Byte> showimg = new Image<Bgr, Byte>(image.Size); showimg = frame.Resize(imageBox1.Width, imageBox1.Height, 0); imageBox1.Image = showimg;
} }
#endregion
private void panel2_Paint(object sender, PaintEventArgs e) {
}
private void openFileDialog1_FileOk(object sender, CancelEventArgs e) {
}
private void btnStop_Click(object sender, EventArgs e) {
timer1.Enabled = false; }
private void btnLanjut_Click(object sender, EventArgs e) {
timer1.Enabled = true; }
private void btnKeluar_Click(object sender, EventArgs e) {
Dispose(); }
private void splitContainer1_Panel2_Paint(object sender, PaintEventArgs e) { } } } 4. Module NeuroNet using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.IO;
{
public class NNForwardPropagation
{
/// <summary> ///
/// </summary> ///
// Main thread sets this event to stop worker thread:
public ManualResetEvent m_EventStop=null;
// Worker thread sets this event when it is stopped:
public ManualResetEvent m_EventStopped=null;
public List<Mutex> m_Mutexs;
public HiPerfTimer m_HiPerfTime;
public uint m_nImages;
public int m_currentPatternIndex;
public Preferences m_Preferences { get; set; }
public bool m_bDistortPatterns;
/// <summary> ///
/// </summary> ///
protected bool _bDataReady;
//backpropagation and training-related members
protected NeuralNetwork _NN;
protected double[] m_DispH; // horiz distortion map array
protected double[] m_DispV; // vert distortion map array
protected int _cCols; // size of the distortion maps
protected int _cRows;
protected int _cCount;
double[,] _GaussianKernel = new double[MyDefinations.GAUSSIAN_FIELD_SIZE,
MyDefinations.GAUSSIAN_FIELD_SIZE];
public NeuralNetwork m_NeuralNetwork { get { return _NN; } set { _NN = value; } } /// <summary> /// /// </summary> public NNForwardPropagation() { m_currentPatternIndex = 0; _bDataReady = false; _NN = null; m_EventStop = null; m_EventStopped = null;
m_Mutexs = new List<Mutex>(4); m_HiPerfTime = new HiPerfTimer(); m_nImages = 0;
// allocate memory to store the distortion maps
_cCols = 29; _cRows = 29;
_cCount = _cCols * _cRows; m_DispH = new double[_cCount]; m_DispV = new double[_cCount];
}
protected void GetGaussianKernel(double _dElasticSigma) {
int iiMid = 21 / 2; // GAUSSIAN_FIELD_SIZE is strictly odd
double twoSigmaSquared = 2.0 * (_dElasticSigma) * (_dElasticSigma); twoSigmaSquared = 1.0 / twoSigmaSquared;
double twoPiSigma = 1.0 / (_dElasticSigma) * Math.Sqrt(2.0 * 3.1415926535897932384626433832795);
for (int col = 0; col < 21; ++col) {
for (int row = 0; row < 21; ++row) {
_GaussianKernel[row, col] = twoPiSigma *
(Math.Exp(-(((row - iiMid) * (row - iiMid) + (col - iiMid) * (col - iiMid)) * twoSigmaSquared)));
} } }
public double GetCurrentEta() { if (_NN != null) { return _NN.m_etaLearningRate; } else return 0.0; }
public double GetPreviousEta() { if (_NN != null) { return _NN.m_etaLearningRatePrevious; } else return 0.0; }
public void CalculateNeuralNet(double[] inputVector, int count,
double[] outputVector /* =NULL */, int oCount
/* =0 */,
NNNeuronOutputsList pNeuronOutputs /* =NULL */,
bool bDistort /* =FALSE */ ) { m_Mutexs[0].WaitOne(); { if (bDistort != false) { GenerateDistortionMap(1.0); ApplyDistortionMap(inputVector); }
}
/// <summary>
/// Distortion Pattern
/// </summary>
/// <param name="inputVector"></param>
protected void ApplyDistortionMap(double[] inputVector) {
List<List<double>> mappedVector = new List<List<double>>(_cRows);
for (int i = 0; i < _cRows; i++) {
List<double> mVector = new List<double>(_cCols);
for (int j = 0; j < _cCols; j++) {
mVector.Add(0.0); }
mappedVector.Add(mVector); }
double sourceRow, sourceCol;
double fracRow, fracCol;
double w1, w2, w3, w4;
double sourceValue;
int row, col;
int sRow, sCol, sRowp1, sColp1;
bool bSkipOutOfBounds;
for (row = 0; row < _cRows; ++row) {
for (col = 0; col < _cCols; ++col) {
sourceRow = (double)row - m_DispV[row * _cCols + col]; sourceCol = (double)col - m_DispH[row * _cCols + col];
// weights for bi-linear interpolation
fracRow = sourceRow - (int)sourceRow; fracCol = sourceCol - (int)sourceCol;
w1 = (1.0 - fracRow) * (1.0 - fracCol); w2 = (1.0 - fracRow) * fracCol;
w3 = fracRow * (1 - fracCol); w4 = fracRow * fracCol; bSkipOutOfBounds = false;
if ((sourceRow + 1.0) >= _cRows) bSkipOutOfBounds = true;
if (sourceRow < 0) bSkipOutOfBounds = true;
if ((sourceCol + 1.0) >= _cCols) bSkipOutOfBounds = true;
if (bSkipOutOfBounds == false) {
sRow = (int)sourceRow; sCol = (int)sourceCol; sRowp1 = sRow + 1; sColp1 = sCol + 1;
while (sRowp1 >= _cRows) sRowp1 -= _cRows;
while (sRowp1 < 0) sRowp1 += _cRows;
while (sColp1 >= _cCols) sColp1 -= _cCols;
while (sColp1 < 0) sColp1 += _cCols;
// perform bi-linear interpolation
sourceValue = w1 * inputVector[sRow * _cCols + sCol] + w2 * w1 * inputVector[sRow * _cCols + sColp1] + w3 * w1 * inputVector[sRowp1 * _cCols + sCol] + w4 * w1 * inputVector[sRowp1 * _cCols + sColp1]; } else { sourceValue = 1.0 } mappedVector[row][col] = 0.5 * (1.0 - sourceValue); // } }
for (row = 0; row < _cRows; ++row) {
for (col = 0; col < _cCols; ++col) {
inputVector[row * _cCols + col] = 1.0 - 2.0 * mappedVector[row][col]; } } } /// <summary> /// /// </summary> /// <param name="severityFactor"></param>
protected void GenerateDistortionMap(double severityFactor /* =1.0 */ ) {
int row, col;
double[] uniformH = new double[_cCount];
double[] uniformV = new double[_cCount];
Random rdm = new Random();
for (col = 0; col < _cCols; ++col) {
for (row = 0; row < _cRows; ++row) {
uniformH[row * _cCols + col] = (double)(2.0 * rdm.NextDouble() - 1.0);
uniformV[row * _cCols + col] = (double)(2.0 * rdm.NextDouble() - 1.0);
double fConvolvedH, fConvolvedV;
double fSampleH, fSampleV;
double elasticScale = severityFactor * m_Preferences.m_dElasticScaling;
int xxx, yyy, xxxDisp, yyyDisp;
int iiMid = 21 / 2; // GAUSSIAN_FIELD_SIZE (21) is strictly odd
for (col = 0; col < _cCols; ++col) {
for (row = 0; row < _cRows; ++row) {
fConvolvedH = 0.0; fConvolvedV = 0.0;
for (xxx = 0; xxx < 21; ++xxx) {
for (yyy = 0; yyy < 21; ++yyy) {
xxxDisp = col - iiMid + xxx; yyyDisp = row - iiMid + yyy;
if (xxxDisp < 0 || xxxDisp >= _cCols || yyyDisp < 0 || yyyDisp >= _cRows) { fSampleH = 0.0; fSampleV = 0.0; } else {
fSampleH = uniformH[yyyDisp * _cCols + xxxDisp]; fSampleV = uniformV[yyyDisp * _cCols + xxxDisp]; }
fConvolvedH += fSampleH * _GaussianKernel[yyy, xxx]; fConvolvedV += fSampleV * _GaussianKernel[yyy, xxx]; }
}
m_DispH[row * _cCols + col] = elasticScale * fConvolvedH; m_DispV[row * _cCols + col] = elasticScale * fConvolvedV; }
}
uniformH = null; uniformV = null;
// next, the scaling of the image by a random scale factor // Horizontal and vertical directions are scaled independently
double dSFHoriz = severityFactor * m_Preferences.m_dMaxScaling / 100.0 * (2.0 * rdm.NextDouble() - 1.0); // m_dMaxScaling is a percentage
double dSFVert = severityFactor * m_Preferences.m_dMaxScaling / 100.0 * (2.0 * rdm.NextDouble() - 1.0); // m_dMaxScaling is a percentage
int iMid = _cRows / 2;
{
for (col = 0; col < _cCols; ++col) {
m_DispH[row * _cCols + col] = m_DispH[row * _cCols + col] + dSFHoriz * (col - iMid);
m_DispV[row * _cCols + col] = m_DispV[row * _cCols + col] -dSFVert * (iMid - row); // negative because of top-down bitmap
} }
double angle = severityFactor * m_Preferences.m_dMaxRotation * (2.0 * rdm.NextDouble() - 1.0);
angle = angle * 3.1415926535897932384626433832795 / 180.0; // convert from degrees to radians
double cosAngle = Math.Cos(angle);
double sinAngle = Math.Sin(angle);
for (row = 0; row < _cRows; ++row) {
for (col = 0; col < _cCols; ++col) {
m_DispH[row * _cCols + col] = m_DispH[row * _cCols + col] + (col - iMid) * (cosAngle - 1) - (iMid - row) * sinAngle;
m_DispV[row * _cCols + col] = m_DispV[row * _cCols + col] -(iMid - row) * (cosAngle - 1) + (col - iMid) * sinAngle; // negative because of top-down bitmap } } } } } 5. Module NeuralNetLayer using System; using System.Collections.Generic; using System.Linq; using System.Text; using ArchiveSerialization; using System.IO; namespace NeuralNetworkLibrary {
// Neural Network class
public class NeuralNetwork : IArchiveSerialization
{
public double m_etaLearningRatePrevious;
public double m_etaLearningRate;
public uint m_cBackprops; // counter used in connection with Weight sanity check
public NNLayerList m_Layers;
public NeuralNetwork() {
m_etaLearningRate = .001; // arbitrary, so that brand-new NNs can be serialized with a non-ridiculous number
m_cBackprops = 0;
m_Layers = new NNLayerList(); }
{
var lit = m_Layers.First();
// first layer is imput layer: directly set outputs of all of its neurons
// to the input vector
if (m_Layers.Count > 1) { int count = 0; if (iCount != lit.m_Neurons.Count) { return; }
foreach (var nit in lit.m_Neurons) { if (count < iCount) { nit.output = inputVector[count]; count++; } } }
for (int i = 1;i<m_Layers.Count; i++) {
m_Layers[i].Calculate(); }
// load up output vector with results
if (outputVector != null) {
lit = m_Layers[m_Layers.Count - 1];
for (int ii = 0; ii < oCount; ii++) { outputVector[ii] = lit.m_Neurons[ii].output; } } if (pNeuronOutputs != null) {
// check for first time use (re-use is expected)
pNeuronOutputs.Clear();
// it's empty, so allocate memory for its use
pNeuronOutputs.Capacity=m_Layers.Count;
foreach (NNLayer nnlit in m_Layers) {
var layerOut = new
NNNeuronOutputs(nnlit.m_Neurons.Count);
for (int ii = 0; ii < nnlit.m_Neurons.Count; ++ii) {
layerOut.Add(nnlit.m_Neurons[ii].output); }
pNeuronOutputs.Add(layerOut); }
} }
public void Backpropagate(double[] actualOutput, double[] desiredOutput, int count, NNNeuronOutputsList pMemorizedNeuronOutputs)
{
if(( m_Layers.Count >= 2 )==false) // there must be at least two layers in the net
{
return; }
if ( ( actualOutput == null ) || ( desiredOutput == null ) || ( count >= 256 ) ) return; m_cBackprops++; if ( (m_cBackprops % 10000) == 0 ) { PeriodicWeightSanityCheck(); }
int iSize = m_Layers.Count;
var dErr_wrt_dXlast = new DErrorsList(m_Layers[m_Layers.Count -1].m_Neurons.Count);
var differentials = new List<DErrorsList>(iSize);
int ii;
for (ii = 0; ii < m_Layers[m_Layers.Count - 1].m_Neurons.Count; ++ii)
{
dErr_wrt_dXlast.Add(actualOutput[ ii ] - desiredOutput[ ii ]);
}
for ( ii=0; ii<iSize-1; ii++ ) {
var m_differential = new
DErrorsList(m_Layers[ii].m_Neurons.Count);
for (int kk = 0; kk < m_Layers[ii].m_Neurons.Count; kk++) {
m_differential.Add(0.0); }
differentials.Add(m_differential); }
differentials.Add(dErr_wrt_dXlast); // last one
bool bMemorized = ( pMemorizedNeuronOutputs != null );
for ( int jj=iSize-1; jj>0;jj--) { if ( bMemorized != false ) { m_Layers[jj].Backpropagate( differentials[ jj ], differentials[ jj - 1 ], pMemorizedNeuronOutputs[jj], pMemorizedNeuronOutputs[ jj - 1 ], m_etaLearningRate ); }
null, null, m_etaLearningRate ); }
}
differentials.Clear(); }
public void EraseHessianInformation() {
foreach (var lit in m_Layers) {
lit.EraseHessianInformation(); }
}
public void DivideHessianInformationBy(double divisor) {
foreach (var lit in m_Layers) {
lit.DivideHessianInformationBy(divisor); }
}
public void BackpropagateSecondDervatives(double[] actualOutputVector,
double[] targetOutputVector, uint count) {
if( m_Layers.Count< 2 ){return;};
if ((actualOutputVector == null) || (targetOutputVector == null) || (count >= 256))
{
return; }
int iSize = m_Layers.Count;
int neuronCount = m_Layers[m_Layers.Count - 1].m_Neurons.Count;
var d2Err_wrt_dXlast = new DErrorsList(neuronCount);
var differentials = new List<DErrorsList>(iSize);
var lit = m_Layers.Last(); // point to last layer
for ( int ii=0; ii<lit.m_Neurons.Count; ii++ ) {
d2Err_wrt_dXlast.Add(1.0); }
for ( int ii=0; ii<iSize-1; ii++ ) {
var m_differential = new
DErrorsList(m_Layers[ii].m_Neurons.Count);
for (int kk = 0; kk < m_Layers[ii].m_Neurons.Count; kk++) {
m_differential.Add(0.0); }
}
differentials.Add(d2Err_wrt_dXlast); // last one
for ( int ii = iSize - 1; ii>0; ii--) { m_Layers[ii].BackpropagateSecondDerivatives( differentials[ ii ], differentials[ ii - 1 ] ); } differentials.Clear(); } void PeriodicWeightSanityCheck() {
foreach (var lit in m_Layers) {
lit.PeriodicWeightSanityCheck(); }
}
virtual public void Serialize(Archive ar) {
if (ar.IsStoring()) {
ar.Write(m_etaLearningRate); ar.Write(m_Layers.Count);
foreach (var lit in m_Layers) { lit.Serialize( ar ); } } else { double eta; ar.Read(out eta);
m_etaLearningRate = eta;
int nLayers;
var pLayer = (NNLayer)null; ar.Read(out nLayers); m_Layers.Clear();
m_Layers = new NNLayerList(nLayers);
for ( int ii=0; ii<nLayers; ii++ ) {
pLayer = new NNLayer( "", pLayer ); m_Layers.Add(pLayer); pLayer.Serialize( ar ); } } } } }