Ogni neurone controlla lo stato di uno dei due motori del robot (uno per la ruona sx e uno per la ruota dx).
Fare riferimento a percettrone per un piccolo cenno di teoria.
unit IA1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons, Grids;
{
-----------------------------------
Esercizio personale
-----------------------------------
ROBOTICA MOBILE
-----------------------------------
Università Degli Studi di Palermo
Ingegneria Informatica
William Pristia
-----------------------------------
Addenstramento di un percettrone per la navigazione di un robot munito di due sensori a baffo.
E' stato scelto un campione di 3 vettori di input con tre diverse risposte della rete
Un valore di soglia di -0.001
un tasso di apprendimento di 0.3
}
Type
TWeight = Real;
TWeightsVector = Array Of TWeight;
TInputsVector = TWeightsVector;
TThreshold = Real;
TPerceptron = Class;
TOnStepEvent = Procedure (Sender : TPerceptron;
Const Step : Integer;
Const WeightsVector : TWeightsVector;
Const OutPutValue : TThreshold) Of Object;
TQueryInputsVectorEvent = Procedure (Sender : TPerceptron;
Var Vector : TInputsVector) Of Object;
TQueryOutputValueEvent = Procedure (Sender : TPerceptron; Var
Output : TThreshold) Of Object;
TQueryCoefficientOfLearning = Procedure (Sender : TPerceptron;
Var Coefficient : TThreshold) Of Object;
TPerceptron = Class
Private
fCurrentStep : Integer;
fInitialWeightsVector,
fPredWeightsVector : TWeightsVector;
fVectorSize: Integer;
fActive: Boolean;
fThreshold,
fInitialCoefficientOfLearning: TThreshold;
fCoefficientOfLearning: TThreshold;
fSteps: Integer;
fOnQueryInputsVector: TQueryInputsVectorEvent;
fOnQueryOutputValue: TQueryOutputValueEvent;
fOnQueryCoefficientOfLearning: TQueryCoefficientOfLearning;
fOnStep: TOnStepEvent; // coefficiente di apprendimento
Procedure ClearVectors;
procedure SetVectorSize(const Value: Integer);
Protected
// Funzione di eccitazione.
// la classe base implementa il percettrone classico con la funzione uguale a Sgn(X)
Function ExcitationFunction(Value : Real) : Real; Virtual;
// Funzione di aggiornamento costante di apprendimento
Procedure UpdateCoefficientOfLearning; Virtual;
Procedure UpdateInputsVector; Virtual;
Procedure UpdateOutputValue; Virtual;
Procedure InitWeightsVector; Dynamic;
Procedure BeginTraining; Dynamic;
Procedure StopTraining; Dynamic;
Public
InputsVector : TInputsVector; // vettore di ingresso
WeightsVector : TWeightsVector; // Vettore dei pesi
OutPutValue : TThreshold; // valore atteso di uscita (ecco perchè con apprendimento supervisionato)
Class Function ScalarProduct(aReal : TThreshold;
aVector : TInputsVector) : Real;
Class Function WeightedSum(aWeightsVector : TWeightsVector;
aInputsVector : TInputsVector) : Real;
Constructor Create; Virtual;
Destructor Destroy; Override;
Procedure TrainsThisStep; Virtual;
Procedure RunTraining;
Property Active : Boolean
Read fActive;
Property Steps : Integer
Read fSteps
Write fSteps;
Property VectorSize : Integer
Read fVectorSize
Write SetVectorSize; // Numero componenti dei vettori
Property CoefficientOfLearning : TThreshold
Read fCoefficientOfLearning
Write fCoefficientOfLearning;
Property Threshold : TThreshold
Read fThreshold
Write fThreshold; // Valore di soglia
Property CurrentStep : Integer
Read fCurrentStep;
Property InitialWeightsVector : TWeightsVector
Read fInitialWeightsVector;
Property InitialCoefficientOfLearning : TThreshold
Read fInitialCoefficientOfLearning
Write fInitialCoefficientOfLearning;
// Eventi associati alla richiesta dei vettori di input e del valore di output
Property OnQueryInputsVector : TQueryInputsVectorEvent
Read fOnQueryInputsVector
Write fOnQueryInputsVector;
Property OnQueryOutputValue : TQueryOutputValueEvent
Read fOnQueryOutputValue
Write fOnQueryOutputValue;
// Eventi associati alla richiesta di aggiornamento della costante di apprendimento
Property OnQueryCoefficientOfLearning : TQueryCoefficientOfLearning
Read fOnQueryCoefficientOfLearning
Write fOnQueryCoefficientOfLearning;
// Eventi associati alla computazione di un passo di apprendimento
Property OnStep : TOnStepEvent
Read fOnStep
Write fOnStep;
End;
TEngine = Class(TPerceptron)
Public
Constructor Create; Override;
Procedure UpdateInputsVector; Override;
End;
TForm3 = class(TForm)
BitBtn1: TBitBtn;
sg: TStringGrid;
procedure BitBtn1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
Procedure UpdateLeftEngineOutputValue(Sender : TPerceptron;
Var Output : TThreshold);
Procedure UpdateRightEngineOutputValue(Sender : TPerceptron;
Var Output : TThreshold);
Procedure Step(Sender : TPerceptron;
Const Step : Integer;
Const WeightsVector : TWeightsVector;
Const OutPutValue : TThreshold);
end;
Procedure MakeRandomInput(Var Vector : TInputsVector);
var
Form3: TForm3;
implementation
Uses
Math;
{$R *.dfm}
Procedure MakeRandomInput(Var Vector : TInputsVector);
Var
I : Integer;
Begin
for I:=Low(Vector) to High(Vector) Do
Begin
Randomize;
// Inizializzazione normalizzata a 1 :
//
// / x \ (y)
// | ------- | * (-1)
// \ 1000 /
//
// con x e y casuali
Vector[I]:=((Random(1000)+1)/1000) * (Power(-1,Random(1000)));
End;
End;
{ TPerceptron }
procedure TPerceptron.BeginTraining;
begin
fActive:=True;
fCurrentStep:=0;
InitWeightsVector;
fCoefficientOfLearning:=fInitialCoefficientOfLearning;
end;
procedure TPerceptron.ClearVectors;
Var
I : Integer;
begin
For I:=0 To Pred(fVectorSize) Do
Begin
fInitialWeightsVector[I]:=0;
fPredWeightsVector[I]:=0;
WeightsVector[I]:=0;
End;
end;
constructor TPerceptron.Create;
begin
fActive:=False;
fSteps:=5;
fVectorSize:=0;
ClearVectors;
SetLength(InputsVector,fVectorSize);
FillChar(InputsVector,Length(InputsVector),0);
fThreshold:=0;
fInitialCoefficientOfLearning:=0; // un valore classico
end;
destructor TPerceptron.Destroy;
begin
SetLength(fPredWeightsVector,0);
fPredWeightsVector:=Nil;
SetLength(WeightsVector,0);
WeightsVector:=Nil;
inherited;
end;
function TPerceptron.ExcitationFunction(Value: Real): Real;
begin
If (Value-fThreshold)>0 Then
Result:=1
Else
Result:=0;
end;
procedure TPerceptron.InitWeightsVector;
Var
I : Integer;
begin
If fVectorSize>0 Then
Begin
ClearVectors;
For I:=0 To Pred(fVectorSize) Do
Begin
Randomize;
// Inizializzazione normalizzata a 1 :
//
// / x \ (y)
// | ------- | * (-1)
// \ 1000 /
//
// con x e y casuali
fInitialWeightsVector[I] :=((Random(1000)+1)/1000) * (Power(-1,Random(1000)));
WeightsVector[I]:=fInitialWeightsVector[I];
End;
End;
end;
procedure TPerceptron.RunTraining;
Var
I : Integer;
begin
BeginTraining;
For I:=1 To fSteps Do
Begin
fCurrentStep:=I;
UpdateInputsVector;
UpdateOutputValue;
TrainsThisStep;
If I
UpdateCoefficientOfLearning;
End;
StopTraining;
end;
class function TPerceptron.ScalarProduct(aReal: TThreshold;
aVector: TInputsVector): Real;
Var
I : Integer;
begin
// prodotto scalare per reale dell'errore per il vettore di input
Result:=0;
For I:=Low(aVector) To high(aVector) Do
Result:=Result+(aReal*aVector[I]);
end;
procedure TPerceptron.SetVectorSize(const Value: Integer);
begin
fVectorSize := Value;
SetLength(fPredWeightsVector,Value);
SetLength(fInitialWeightsVector,Value);
SetLength(WeightsVector,Value);
SetLength(InputsVector,Value);
end;
procedure TPerceptron.StopTraining;
begin
fActive:=False;
end;
procedure TPerceptron.TrainsThisStep;
Var
I : Integer;
lScalar, // prodotto scalare del vettore degli input per l'errore
lError, // errore (valore atteso - valore reale)
lSum : TThreshold; // somma pesata
lResult : Real; // valore reale
begin
// Calcolo dell'input netto (somma pesata)
lSum:=WeightedSum(WeightsVector,InputsVector);
// si sottopone l'input netto o potenziale (a meno della soglia)
// alla funzione di attivazione (uscita del neurone)
lResult:=ExcitationFunction(lSum);
//Aggiornamento vettore pesi
For I:=0 To Pred(fVectorSize) Do
Begin
// Calcolo dell'errore
lError:=OutPutValue - lResult;
// prodotto scalare per reale dell'errore per il vettore di input
lScalar:=ScalarProduct(lError,InputsVector);
// Aggiornamento del vettore dei pesi
WeightsVector[I]:=fPredWeightsVector[I] + (fCoefficientOfLearning * lScalar);
fPredWeightsVector[I]:=WeightsVector[I];
If Assigned(fOnStep) Then fOnStep(Self,fCurrentStep,WeightsVector,OutputValue);
End;
end;
procedure TPerceptron.UpdateCoefficientOfLearning;
begin
If Assigned(fOnQueryCoefficientOfLearning) Then
fOnQueryCoefficientOfLearning(Self,fCoefficientOfLearning);
end;
procedure TPerceptron.UpdateInputsVector;
begin
If Assigned(fOnQueryInputsVector) Then
fOnQueryInputsVector(Self,InputsVector);
end;
procedure TPerceptron.UpdateOutputValue;
begin
If Assigned(fOnQueryOutputValue) Then
fOnQueryOutputValue(Self,OutputValue);
end;
class function TPerceptron.WeightedSum(aWeightsVector: TWeightsVector;
aInputsVector: TInputsVector): Real;
Var
I : Integer;
begin
Result:=0;
If Length(aWeightsVector)=Length(aWeightsVector) Then
For I:=Low(aWeightsVector) To High(aWeightsVector) Do
Result:=Result+(aWeightsVector[I] * aInputsVector[I]);
end;
{ TEngine }
constructor TEngine.Create;
begin
inherited;
Steps:=3;
VectorSize:=2;
Threshold:=-0.001;
InitialCoefficientOfLearning:=0.3;
end;
procedure TEngine.UpdateInputsVector;
begin
Case CurrentStep Of
1 : Begin
InputsVector[0]:=0;
InputsVector[1]:=0;
End;
2 : Begin
InputsVector[0]:=0;
InputsVector[1]:=1;
End;
3 : Begin
InputsVector[0]:=1;
InputsVector[1]:=0;
End;
End;
end;
{TForm3}
procedure TForm3.Step(Sender: TPerceptron;
Const Step : Integer;
const WeightsVector: TWeightsVector;
const OutPutValue: TThreshold);
Var
I : Integer;
begin
For I:=0 To Pred(Sender.VectorSize) Do
Begin
sg.Cells[I,Step-1]:=FloatToStr(Sender.WeightsVector[I]);
End;
end;
procedure TForm3.UpdateLeftEngineOutputValue;
begin
Case Sender.CurrentStep Of
1 : Output:=1;
2 : Output:=1;
3 : Output:=-1;
End;
end;
procedure TForm3.UpdateRightEngineOutputValue;
begin
Case Sender.CurrentStep Of
1 : Output:=1;
2 : Output:=-1;
3 : Output:=1;
End;
end;
procedure TForm3.BitBtn1Click(Sender: TObject);
Var
A : TEngine;
I : Integer;
begin
sg.rowCount:=3;
sg.ColCount:=2;
A:=TEngine.Create;
A.OnQueryOutputValue:=UpdateLeftEngineOutputValue;
A.OnStep:=Step;
A.RunTraining;
{ For I:=0 To Pred(A.VectorSize) Do
Begin
sg.Cells[I,0]:=FloatToStr(A.InitialWeightsVector[I]);
sg.Cells[I,1]:=FloatToStr(A.WeightsVector[I]);
End;}
A.Free;
end;
end.
Nessun commento:
Posta un commento