using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Threading;
namespace MouseGesture
{
#region HiddenType enum
//L'enumeratore serve per identificare se si vuole creare una rete con un numero
//di default di neuroni o con un numero ben preciso di neuroni
public enum HiddenType
{
Default,
Fixed
}
#endregion
#region NetTrainingForm class
public class NetTrainingForm : System.Windows.Forms.Form
{
#region Visual objects
private System.Windows.Forms.Label LearningRateLabel;
private System.Windows.Forms.Label MaxErrorLabel;
private System.Windows.Forms.Label MomentumLabel;
private System.Windows.Forms.NumericUpDown LerningRateNumber;
private System.Windows.Forms.NumericUpDown MomentumNumber;
private System.Windows.Forms.NumericUpDown MaxErrorNumber;
private System.Windows.Forms.Button Done;
private System.Windows.Forms.Button Cancel;
private System.ComponentModel.Container components = null;
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.RadioButton HiddenFixed;
private System.Windows.Forms.RadioButton HiddenFixedDefault;
private System.Windows.Forms.NumericUpDown HiddenFixedNumber;
private System.Windows.Forms.NumericUpDown EpochsNumber;
private System.Windows.Forms.Label EpochsLabel;
#endregion
#region Private members
private double m_LearningRate;
private double m_Momentum;
private double m_MaxError;
private MainBoard m_MainBoard;
private int m_GestureIndex;
private int m_HiddenNeurons;
private HiddenType m_HiddenType=HiddenType.Default;
private int m_Epochs;
private Pattern[] m_Patterns;
private System.Windows.Forms.CheckBox OnlyUntrainedCheck;
private System.Windows.Forms.CheckBox SaveOnFinishedCheck;
private System.Windows.Forms.CheckBox UseLoadedCheck;
private int[] m_Indexes;
#endregion
#region Events and delegates
//L'evento viene invocato appena viene addestrata una gesture
public delegate void GestureTrainedDelegate();
public event GestureTrainedDelegate GestureTrained;
#endregion
#region Contructor
public NetTrainingForm(MainBoard board, int[] GesturesIndexes)
{
this.m_Indexes=GesturesIndexes; //Vettore degli indici delle gesture con training set
this.m_MainBoard=board;
this.InitializeComponent();
this.LinkHandlers();
}
#endregion
#region Dispose function
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#endregion
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(NetTrainingForm));
this.LearningRateLabel = new System.Windows.Forms.Label();
this.MaxErrorLabel = new System.Windows.Forms.Label();
this.MomentumLabel = new System.Windows.Forms.Label();
this.LerningRateNumber = new System.Windows.Forms.NumericUpDown();
this.MomentumNumber = new System.Windows.Forms.NumericUpDown();
this.MaxErrorNumber = new System.Windows.Forms.NumericUpDown();
this.Done = new System.Windows.Forms.Button();
this.Cancel = new System.Windows.Forms.Button();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.HiddenFixedDefault = new System.Windows.Forms.RadioButton();
this.HiddenFixed = new System.Windows.Forms.RadioButton();
this.HiddenFixedNumber = new System.Windows.Forms.NumericUpDown();
this.EpochsNumber = new System.Windows.Forms.NumericUpDown();
this.EpochsLabel = new System.Windows.Forms.Label();
this.OnlyUntrainedCheck = new System.Windows.Forms.CheckBox();
this.SaveOnFinishedCheck = new System.Windows.Forms.CheckBox();
this.UseLoadedCheck = new System.Windows.Forms.CheckBox();
((System.ComponentModel.ISupportInitialize)(this.LerningRateNumber)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.MomentumNumber)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.MaxErrorNumber)).BeginInit();
this.groupBox1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.HiddenFixedNumber)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.EpochsNumber)).BeginInit();
this.SuspendLayout();
//
// LearningRateLabel
//
this.LearningRateLabel.Location = new System.Drawing.Point(8, 10);
this.LearningRateLabel.Name = "LearningRateLabel";
this.LearningRateLabel.Size = new System.Drawing.Size(80, 17);
this.LearningRateLabel.TabIndex = 0;
this.LearningRateLabel.Text = "Learning rate:";
//
// MaxErrorLabel
//
this.MaxErrorLabel.Location = new System.Drawing.Point(184, 8);
this.MaxErrorLabel.Name = "MaxErrorLabel";
this.MaxErrorLabel.Size = new System.Drawing.Size(56, 17);
this.MaxErrorLabel.TabIndex = 3;
this.MaxErrorLabel.Text = "Max error:";
//
// MomentumLabel
//
this.MomentumLabel.Location = new System.Drawing.Point(8, 42);
this.MomentumLabel.Name = "MomentumLabel";
this.MomentumLabel.Size = new System.Drawing.Size(80, 17);
this.MomentumLabel.TabIndex = 4;
this.MomentumLabel.Text = "Momentum:";
//
// LerningRateNumber
//
this.LerningRateNumber.DecimalPlaces = 4;
this.LerningRateNumber.Increment = new System.Decimal(new int[] {
1,
0,
0,
262144});
this.LerningRateNumber.Location = new System.Drawing.Point(88, 8);
this.LerningRateNumber.Maximum = new System.Decimal(new int[] {
1,
0,
0,
0});
this.LerningRateNumber.Minimum = new System.Decimal(new int[] {
1,
0,
0,
262144});
this.LerningRateNumber.Name = "LerningRateNumber";
this.LerningRateNumber.Size = new System.Drawing.Size(72, 20);
this.LerningRateNumber.TabIndex = 1;
this.LerningRateNumber.Value = new System.Decimal(new int[] {
5,
0,
0,
65536});
//
// MomentumNumber
//
this.MomentumNumber.DecimalPlaces = 4;
this.MomentumNumber.Increment = new System.Decimal(new int[] {
1,
0,
0,
262144});
this.MomentumNumber.Location = new System.Drawing.Point(88, 40);
this.MomentumNumber.Maximum = new System.Decimal(new int[] {
1,
0,
0,
0});
this.MomentumNumber.Minimum = new System.Decimal(new int[] {
1,
0,
0,
262144});
this.MomentumNumber.Name = "MomentumNumber";
this.MomentumNumber.Size = new System.Drawing.Size(72, 20);
this.MomentumNumber.TabIndex = 3;
this.MomentumNumber.Value = new System.Decimal(new int[] {
5000,
0,
0,
262144});
//
// MaxErrorNumber
//
this.MaxErrorNumber.DecimalPlaces = 4;
this.MaxErrorNumber.Increment = new System.Decimal(new int[] {
1,
0,
0,
262144});
this.MaxErrorNumber.Location = new System.Drawing.Point(240, 8);
this.MaxErrorNumber.Maximum = new System.Decimal(new int[] {
1,
0,
0,
0});
this.MaxErrorNumber.Minimum = new System.Decimal(new int[] {
1,
0,
0,
262144});
this.MaxErrorNumber.Name = "MaxErrorNumber";
this.MaxErrorNumber.Size = new System.Drawing.Size(72, 20);
this.MaxErrorNumber.TabIndex = 2;
this.MaxErrorNumber.Value = new System.Decimal(new int[] {
1,
0,
0,
196608});
//
// Done
//
this.Done.Location = new System.Drawing.Point(232, 232);
this.Done.Name = "Done";
this.Done.Size = new System.Drawing.Size(80, 24);
this.Done.TabIndex = 0;
this.Done.Text = "&Train";
//
// Cancel
//
this.Cancel.Location = new System.Drawing.Point(8, 232);
this.Cancel.Name = "Cancel";
this.Cancel.Size = new System.Drawing.Size(80, 24);
this.Cancel.TabIndex = 10;
this.Cancel.Text = "&Cancel";
this.Cancel.Click += new System.EventHandler(this.OnCancel);
//
// groupBox1
//
this.groupBox1.Controls.Add(this.HiddenFixedDefault);
this.groupBox1.Controls.Add(this.HiddenFixed);
this.groupBox1.Controls.Add(this.HiddenFixedNumber);
this.groupBox1.Location = new System.Drawing.Point(8, 72);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(304, 72);
this.groupBox1.TabIndex = 11;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "Hidden neurons:";
//
// HiddenFixedDefault
//
this.HiddenFixedDefault.Checked = true;
this.HiddenFixedDefault.Location = new System.Drawing.Point(16, 16);
this.HiddenFixedDefault.Name = "HiddenFixedDefault";
this.HiddenFixedDefault.Size = new System.Drawing.Size(144, 24);
this.HiddenFixedDefault.TabIndex = 5;
this.HiddenFixedDefault.TabStop = true;
this.HiddenFixedDefault.Text = "Default hidden neurons";
this.HiddenFixedDefault.CheckedChanged += new System.EventHandler(this.OnHiddenFixedDefaultChanged);
//
// HiddenFixed
//
this.HiddenFixed.Location = new System.Drawing.Point(16, 40);
this.HiddenFixed.Name = "HiddenFixed";
this.HiddenFixed.Size = new System.Drawing.Size(136, 24);
this.HiddenFixed.TabIndex = 6;
this.HiddenFixed.Text = "Fixed hidden neurons";
this.HiddenFixed.CheckedChanged += new System.EventHandler(this.OnHiddenFixedChanged);
//
// HiddenFixedNumber
//
this.HiddenFixedNumber.Enabled = false;
this.HiddenFixedNumber.Location = new System.Drawing.Point(160, 40);
this.HiddenFixedNumber.Maximum = new System.Decimal(new int[] {
1000,
0,
0,
0});
this.HiddenFixedNumber.Minimum = new System.Decimal(new int[] {
1,
0,
0,
0});
this.HiddenFixedNumber.Name = "HiddenFixedNumber";
this.HiddenFixedNumber.Size = new System.Drawing.Size(48, 20);
this.HiddenFixedNumber.TabIndex = 7;
this.HiddenFixedNumber.Value = new System.Decimal(new int[] {
1,
0,
0,
0});
//
// EpochsNumber
//
this.EpochsNumber.Location = new System.Drawing.Point(240, 40);
this.EpochsNumber.Maximum = new System.Decimal(new int[] {
100000,
0,
0,
0});
this.EpochsNumber.Minimum = new System.Decimal(new int[] {
1,
0,
0,
0});
this.EpochsNumber.Name = "EpochsNumber";
this.EpochsNumber.Size = new System.Drawing.Size(72, 20);
this.EpochsNumber.TabIndex = 4;
this.EpochsNumber.Value = new System.Decimal(new int[] {
1,
0,
0,
0});
//
// EpochsLabel
//
this.EpochsLabel.Location = new System.Drawing.Point(184, 40);
this.EpochsLabel.Name = "EpochsLabel";
this.EpochsLabel.Size = new System.Drawing.Size(48, 17);
this.EpochsLabel.TabIndex = 12;
this.EpochsLabel.Text = "Epochs:";
//
// OnlyUntrainedCheck
//
this.OnlyUntrainedCheck.Location = new System.Drawing.Point(8, 152);
this.OnlyUntrainedCheck.Name = "OnlyUntrainedCheck";
this.OnlyUntrainedCheck.Size = new System.Drawing.Size(296, 16);
this.OnlyUntrainedCheck.TabIndex = 8;
this.OnlyUntrainedCheck.Text = "Train only untrained gestures";
//
// SaveOnFinishedCheck
//
this.SaveOnFinishedCheck.Location = new System.Drawing.Point(8, 176);
this.SaveOnFinishedCheck.Name = "SaveOnFinishedCheck";
this.SaveOnFinishedCheck.Size = new System.Drawing.Size(296, 16);
this.SaveOnFinishedCheck.TabIndex = 9;
this.SaveOnFinishedCheck.Text = "Save net at the end of the training process";
//
// UseLoadedCheck
//
this.UseLoadedCheck.Location = new System.Drawing.Point(8, 200);
this.UseLoadedCheck.Name = "UseLoadedCheck";
this.UseLoadedCheck.Size = new System.Drawing.Size(296, 16);
this.UseLoadedCheck.TabIndex = 13;
this.UseLoadedCheck.Text = "Use loaded values (if available)";
//
// NetTrainingForm
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(322, 264);
this.Controls.Add(this.UseLoadedCheck);
this.Controls.Add(this.SaveOnFinishedCheck);
this.Controls.Add(this.OnlyUntrainedCheck);
this.Controls.Add(this.EpochsNumber);
this.Controls.Add(this.EpochsLabel);
this.Controls.Add(this.groupBox1);
this.Controls.Add(this.Cancel);
this.Controls.Add(this.Done);
this.Controls.Add(this.MaxErrorNumber);
this.Controls.Add(this.MomentumNumber);
this.Controls.Add(this.LerningRateNumber);
this.Controls.Add(this.MomentumLabel);
this.Controls.Add(this.MaxErrorLabel);
this.Controls.Add(this.LearningRateLabel);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "NetTrainingForm";
this.ShowInTaskbar = false;
this.Text = "Training parameters";
((System.ComponentModel.ISupportInitialize)(this.LerningRateNumber)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.MomentumNumber)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.MaxErrorNumber)).EndInit();
this.groupBox1.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.HiddenFixedNumber)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.EpochsNumber)).EndInit();
this.ResumeLayout(false);
}
#endregion
#region Linking handlers
//La funzione collega gli eventi ai relativi handlers
private void LinkHandlers()
{
this.Done.Click+=new EventHandler(OnDone);
this.GestureTrained+=new GestureTrainedDelegate( this.m_MainBoard.OnGestureTrained);
this.Closed+=new EventHandler(this.OnClose);
}
#endregion
#region Event Handlers
#region OnDone handler
//La funzione da inizio al training della funzione
private void OnDone(object sender, EventArgs e)
{
//Caricogli input impostati dall'utente
this.m_LearningRate=(double)this.LerningRateNumber.Value;
this.m_Momentum=(double)this.MomentumNumber.Value;
this.m_MaxError=(double)this.MaxErrorNumber.Value;
this.m_Epochs=(int)this.EpochsNumber.Value;
if(this.m_HiddenType==HiddenType.Fixed)
this.m_HiddenNeurons=(int)(this.HiddenFixedNumber.Value);
else
this.m_HiddenNeurons=-1;
this.Enabled=false;
this.Visible=false;
//Do inizio al thread di training
Thread TrainTread=new Thread(new ThreadStart(this.StartBatchTraining));
TrainTread.Start();
}
#endregion
#region OnCancel handler
private void OnCancel(object sender, System.EventArgs e)
{
this.Close();
}
#endregion
#region OnHiddenFixedDefaultChanged handler
//La funzione aggiorna la modalit� di generazione dei neuroni in default
private void OnHiddenFixedDefaultChanged(object sender, System.EventArgs e)
{
if(this.HiddenFixedDefault.Checked)
{
this.m_HiddenType=HiddenType.Default;
this.HiddenFixedNumber.Enabled=false;
}
}
#endregion
#region OnHiddenFixedChanged handler
//La funzione aggiorna la modalit� di generazione dei neuroni in fixed
private void OnHiddenFixedChanged(object sender, System.EventArgs e)
{
if(this.HiddenFixed.Checked)
{
this.m_HiddenType=HiddenType.Fixed;
this.HiddenFixedNumber.Enabled=true;
}
}
#endregion
#region OnClose handler
private void OnClose(object obj, EventArgs e)
{
this.m_MainBoard.ShowMessageToBar("Training form: closed",MessageType.Normal);
}
#endregion
#endregion
#region Training functions
#region Batch training start function
//La funzione esegue il training su tutte le gestures con training set
private void StartBatchTraining()
{
int Trained=0;
//Metto la main board in training mode
this.m_MainBoard.StartTrainingMode(this.m_Epochs);
for(int i=0; i<this.m_Indexes.Length; i++)
{
//Addestro tutte le gestures, a meno che non si sia scelto di addestrare solo quelle non addestrate
if(!this.OnlyUntrainedCheck.Checked || !((Gesture)this.m_MainBoard.KnownGestures[this.m_Indexes[i]]).Trained)
{
Trained++;
this.m_GestureIndex=this.m_Indexes[i];
//Inserisco nel RecognizedPanel la gesture di cui sto facendo il training
this.m_MainBoard.InsertRecognizedGesture(((Gesture)this.m_MainBoard.KnownGestures[this.m_GestureIndex]).Points);
//Do inizio al training della rete della gesture
this.StartLearning();
}
if(this.GestureTrained!=null)
this.GestureTrained();
}
if(Trained==0)
MessageBox.Show("Every gesture is already trained.","Info",MessageBoxButtons.OK,MessageBoxIcon.Information);
//Termino la fase di training
this.m_MainBoard.Parent.Enabled=true;
this.m_MainBoard.EndTrainingMode();
this.Close();
}
#endregion
#region Start learning on current gesture
//La funzione esegue effettivamente ilt raining della rete neurale
private void StartLearning()
{
//La variabile conterr� il numero di gestures riconosciute
double Recognized=0d;
//La vriabile conterr� l'ultimo errore prodotto dal training della rete
double LastError=0d;
//La variabile indica il risultato del dialog box alla fine del ciclo while
DialogResult result;
//La variabile si occupa di mantenere lo stato originale della rete, prima di qualunque interventosulla stessa
MultiLayerPerceptron OldNet=((Gesture)this.m_MainBoard.KnownGestures[this.m_GestureIndex]).Net;
do
{
Recognized=0d;
LastError=0d;
//Ripulisco la main board dai grafici precedenti
this.m_MainBoard.ClearError();
//Popolo il vettore del training set definitivo con ilt raining set della gesture (gli esempi)
this.m_Patterns=new Pattern[((Gesture)this.m_MainBoard.KnownGestures[this.m_GestureIndex]).GestureTrainingSet.Length];
((Gesture)this.m_MainBoard.KnownGestures[this.m_GestureIndex]).GestureTrainingSet.CopyTo(this.m_Patterns,0);
//Memorizzo la grandezza del vettore, che � l'inidce del primo non esempio
int NotExampleIndex=this.m_Patterns.Length;
//Genero i non esempi per la gesture corrente
this.GenerateNotExamples();
//Se sto addestrando una rete gi� addestrata, e l'utente ha scelto di addestrare la rete con i valori usati
//in precendeza, non ricreo la rete
if(((Gesture)this.m_MainBoard.KnownGestures[this.m_GestureIndex]).Trained && this.UseLoadedCheck.Checked)
{
this.m_MainBoard.ShowMessageToBar("Training \'"+((Gesture)this.m_MainBoard.KnownGestures[this.m_GestureIndex]).Name+"\' net by current values",MessageType.Info);
}
else
{
//Se la rete non era addestrata, o l'utente ha deciso di uasre i nuovi settaggi, controllo
//se l'utente abbia specificato o meno il numero di neuroni hidden
if(this.m_HiddenType==HiddenType.Default)
((Gesture)this.m_MainBoard.KnownGestures[this.m_GestureIndex]).Net=new MultiLayerPerceptron(MainBoard.MaximumFeatures,1d,this.m_LearningRate,this.m_Momentum,this.m_Epochs,this.m_MaxError);
else
((Gesture)this.m_MainBoard.KnownGestures[this.m_GestureIndex]).Net=new MultiLayerPerceptron(this.m_HiddenNeurons,MainBoard.MaximumFeatures,1d,this.m_LearningRate,this.m_Momentum,this.m_Epochs,this.m_MaxError);
this.m_MainBoard.ShowMessageToBar("Training \'"+((Gesture)this.m_MainBoard.KnownGestures[this.m_GestureIndex]).Name+"\' net by specified values values",MessageType.Info);
}
//Imposto il training set della rete
((Gesture)this.m_MainBoard.KnownGestures[this.m_GestureIndex]).Net.SetTrainingSet(this.m_Patterns,NotExampleIndex);
//Creo il delegate alla funzione e collego l'evento all'handler
MouseGesture.MultiLayerPerceptron.TrainedPatternDelegate Delegate=new MouseGesture.MultiLayerPerceptron.TrainedPatternDelegate(this.m_MainBoard.OnEpochEnded);
((Gesture)this.m_MainBoard.KnownGestures[this.m_GestureIndex]).Net.EpochEnded+=Delegate;
LastError=((Gesture)this.m_MainBoard.KnownGestures[this.m_GestureIndex]).Net.StartTraining(Gesture.ExtractFeatures(((Gesture)this.m_MainBoard.KnownGestures[this.m_GestureIndex]).Points));
double expected=0;
//Dopo aver mandato il pattern, mando l'insieme delle gestures stesse, che rappresenta un
//insieme di features non utilizzate nel training, applico la funzione di soglia e controllo
//la percentuale di gestures che � stato in grado di riconoscere correttamente
for(int g=0; g<this.m_Indexes.Length; g++)
{
expected=(this.m_Indexes[g]==this.m_GestureIndex)?(1d):(0d);
if(Neuron.CheckThreashold(((Gesture)this.m_MainBoard.KnownGestures[this.m_GestureIndex]).Net.Run(((Gesture)this.m_MainBoard.KnownGestures[this.m_Indexes[g]]).ExtractFeatures()))==expected)
Recognized++;
}
//Rimuovo il delegate alla funzione creato in rpecedenza
((Gesture)this.m_MainBoard.KnownGestures[this.m_GestureIndex]).Net.EpochEnded-=Delegate;
//Calcolo al percentuale di riconoscimento
Recognized/=(double)this.m_Indexes.Length;
//Faccio apparire il message box relativo al termine del training, l'utente pu�
//rispondere 'Yes' per accettare il training e salvare la rete, 'No' per ripetere il
//training o 'Cancel' per evitare il salvataggio della rete appena creata (quella
//salvata rester� quella addestrata in precedenza)
result=MessageBox.Show("The gesture \'"+((Gesture)this.m_MainBoard.KnownGestures[this.m_GestureIndex]).Name+"\' has been successfully trained (Recognized gestures: "+((double)(Recognized*100d))+"%, Last training error: "+LastError+").\nDo you want to accept this net?\n(Press \'YES\' to accept, \'NO\' to re-train and \'CANCEL\' to ignore this net)","Accept and save net?",MessageBoxButtons.YesNoCancel,MessageBoxIcon.Question);
}
while(result==DialogResult.No);
//Se il risultato � stato 'Yes' salvo la rete
if(result==DialogResult.Yes)
{
((Gesture)this.m_MainBoard.KnownGestures[this.m_GestureIndex]).Trained=true;
if(this.SaveOnFinishedCheck.Checked)
((Gesture)this.m_MainBoard.KnownGestures[this.m_GestureIndex]).SaveGesture(false,true);
}
else
{
//In caso contrario ripristino lo stato della rete attuale (se era untrained rester� tale)
((Gesture)this.m_MainBoard.KnownGestures[this.m_GestureIndex]).Net=OldNet;
}
}
#endregion
#region Not examples generation
//La funzione si occupa della generazione dei non-esempi
private void GenerateNotExamples()
{
//Il numero di pattern da generare in maniera random � pari alla dimensione del training set di
//esempi della rete
int TotRandom=this.m_Patterns.Length;
//Fisso il numero di pattern da prendere da ogni training set
//delle altre gestures
int HowMany=(int)(TotRandom/this.m_MainBoard.KnownGestures.Count);
HowMany=(HowMany<=0)?(1):(HowMany);
//Inizializzo l'array del training set
ArrayList RealTrainingSet=new ArrayList(this.m_Patterns);
for(int i=0; i<this.m_MainBoard.KnownGestures.Count; i++)
{
if(i!=this.m_GestureIndex && ((Gesture)this.m_MainBoard.KnownGestures[i]).TrainingSetCreated)
{
int TotPerGesture=0;
for(int j=0; j<((Gesture)this.m_MainBoard.KnownGestures[i]).GestureTrainingSet.Length && TotPerGesture<HowMany; j++)
{
RealTrainingSet.Add(((Gesture)this.m_MainBoard.KnownGestures[i]).GestureTrainingSet[j]);
TotPerGesture++;
}
}
}
//Aggiungo tanti contro-esempi random quanti sono i pattern positivi del training set
for(int j=0; j<TotRandom; j++)
RealTrainingSet.Add(this.GenerateRandomPattern());
//Converto il training set finale da dinamico a statico (salvando nella variabile membro apposita)
this.m_Patterns=new Pattern[RealTrainingSet.Count];
RealTrainingSet.CopyTo(this.m_Patterns);
}
#region Random features
//La funzione genera dei pattern con delle features comprese nell'intervallo [-1,1]
//Anche se esiste la possibilit� di creare dei pattern simili a quello
//da riconoscere, il fatto che gli esempi positivi siano pari al training set, rende
//una tale eventualit� (fortuita) piuttosto ininfluente
private Pattern GenerateRandomPattern()
{
Random r=new Random(DateTime.Now.Millisecond);
double[] Features=new double[MainBoard.MaximumFeatures];
for(int i=0; i<MainBoard.MaximumFeatures; i++)
Features[i]=((double)r.Next(-1000,1001))/1000d;
return new Pattern(Features);
}
#endregion
#endregion
#endregion
}
#endregion
}