Ausgabe der Lernrate und des Netzfehlers im Trace Fenster

Dieses Forum beschäftigt sich mit allen Fragen, Kommentaren und Anregungen zu MemBrain Skripten. Auch der Austausch von Skripten zwischen MemBrain Benutzern soll hiermit gefördert werden.
Wenn Sie ein interessantes Skript haben, das Sie anderen MemBrain Benutzern zur Verfügung stellen wollen, dann Erstellen Sie dafür jeweils bitte ein neues Thema in diesem Forum. Der Titel des Themas sollte es anderen Benutzern erlauben möglichst schnell zu erfassen, wozu Ihr Skript dient.
Post Reply
Gruschel
Posts: 3
Joined: Tue 29. Oct 2013, 11:36

Ausgabe der Lernrate und des Netzfehlers im Trace Fenster

Post by Gruschel »

Hallo,

ich arbeite mich seit einer Weile in Membrain ein und versuche gerade, ein vorhandenes Skript etwas zu modifizieren.

Dabei versuche ich, das Skript dazu zu bringen, wenn ein gewisser Wert beim Netzfehler unterschritten wird, dass die Lernrate schrittweise kleiner wird.
(das "Mutterskript" ist das Basisscript, welches Trainingsdaten nimmt, dann validiert, und diese als .csv rauspeichert)

Um zu sehen, dass die Schleife korrekt durchlaufen wird, möchte ich den Wert der LEARNRATE und des GetNetError() im Trace fortlaufend pro Lesson angezeigt bekommen. Der Teachermanager zeigt mir den niedrigten Wert der LEARNRATE an nachdem es fertig durchgelaufen ist, aber ich würde die Schrittlängenänderung gerne sehen im Trace um sicherzugehen bzw. es später in einem File aufzeichnen.

Und irgendwie scheitere ich gerade an dem Punkt. Ich vermute, dass ich den Wert vom GetNetError() und der LEARNRATE in einen string umleiten muss, und dass dieser string in Trace reingehört :oops:

Wenn ich mein Testnetz richtig interpretiere, funktioniert das soweit, dass er die LEARNRATE reduziert wenn der NetError sinkt.

Code: Select all

double TAR_ERR_CHECK; // target net error

double LEA_RAT_START = 0.1;   // The learning rate - start value, 0,01 bs 0,9 akzeptable Werte

double TAR_ERR_M1 = 0.1;   // The target net error - step value - if Target Error goes below 0.1, the Learning Rate will be slower
double LEA_RAT_M1 = 0.05;   // The learning rate - final value, 0,01 bs 0,9 akzeptable Werte

double TAR_ERR_M2 = 0.05;   // The target net error - step value - if Target Error goes below 0.1, the Learning Rate will be slower
double LEA_RAT_M2 = 0.025;   // The learning rate - final value, 0,01 bs 0,9 akzeptable Werte

double TAR_ERR_M3 = 0.03;   // The target net error - step value - if Target Error goes below 0.1, the Learning Rate will be slower
double LEA_RAT_M3 = 0.011;   // The learning rate - final value, 0,01 bs 0,9 akzeptable Werte

double TAR_ERR_FIN = 0.01;   // The target net error - final value

string Lern_Rate = Double.toString(LEARNRATE);
string Netz_Fehler = Double.toString(TAR_ERR_CHECK);
weiter hinten steht dann

Code: Select all


StartTeaching();					// Start teaching and wait for stop (target error reached)
	TAR_ERR_CHECK = GetNetError();

	
	if (TAR_ERR_M1 > TAR_ERR_CHECK)
		{
		TAR_ERR_CHECK_M1 = GetNetError();
		TeacherSetting(LEARNRATE, LEA_RAT_M1);
		
		
		if (TAR_ERR_M2 > TAR_ERR_CHECK)
			{
			TAR_ERR_CHECK_M2 = GetNetError();
			TeacherSetting(LEARNRATE, LEA_RAT_M2);
			
			if (TAR_ERR_M3 > TAR_ERR_CHECK)
				{
				TAR_ERR_CHECK_M3 = GetNetError();
				TeacherSetting(LEARNRATE, LEA_RAT_M3);
				} 
				
			}
		}
		
	

	SleepExec();
Danke im Voraus für deine Hilfe :)
User avatar
TJetter
Posts: 346
Joined: Sat 13. Oct 2012, 12:04

Re: Ausgabe der Lernrate und des Netzfehlers im Trace Fenste

Post by TJetter »

Hallo,

zum Beispiel so:

Code: Select all

double netError = GetNetError();
string netErrStr = "Net Err = " + netError;
Trace(netErrStr + "\r");
oder auch in einer Zeile:

Code: Select all

Trace("Net Err = " + netError + "\r");
das '\r' fürgt einen 'Wagenrücklauf' ein, so dass die Zeilen untereinander ausgegeben werden.

Viele Grüße und viel Erfolg
Thomas Jetter
Gruschel
Posts: 3
Joined: Tue 29. Oct 2013, 11:36

Re: Ausgabe der Lernrate und des Netzfehlers im Trace Fenste

Post by Gruschel »

Hallo,

danke dir vielmals, hat wunderbar funktioniert und ich konnte so auch mehrere Fehlerquellen finden, dank sichtbarer Ausgabe.

Witzigerweise scheint mein script zu funktionieren, wenn auch mit Einschränkungen.
Aber ich habe neue Unklarheiten.

Folgendes:

Ich starte Membrain, Lasse das Script laufen, das liest beim Start NetError = -1, läuft 1mal ohne durch in die Schleife zu gehen und gibt einen ersten NetError aus.
Output = 0,1734 (Bsp)

Ich starte das script erneut, er liest den NetError Output von vorhin ein und beginnt damit.
die while Routine funktioniert und er ändert auch die Lernrate wenn er NetError kleiner wird. Das sehe ich nur an der Ausgabe der Lernrate, die Ausgabe des NetErrors ändert sich nicht, obgleich ich versucht habe, mit EvaluateNetError() den NetError immer wieder neu einzulesen.
Im Trace Fenster sieht man wunderschön, wie er durch die Anweisungen durchhüpft. Zu beginn nur die erste if Anweisung, dann immer tiefer.

Frage :?

Kann ich den NetError am Anfang irgendwie festlegen, dass einfach standardmäßig ein hoher Wert ist damit er losrennt?
Ich hatte versucht, am Anfang einfach "double netError = 0.5;" zu schreiben, aber das war wohl zu einfach gedacht.

der Wert netError wird anscheinend nicht laufend angepasst, und evaluateNetError() ist zwar offensichtlich im Hintergrund wichtig, weil sonst läuft das script nicht richtig, aber an der Anzeige ändert es nichts. Wo liegt die mein Fehler?

Angehängt der komplette Code vom Script (bis auf den erklärenden Text am Anfang)

Sorry wenn es offensichtlich sein sollte, ich bin Neuling was angelscript angeht.

Jedenfalls Danke für deine gestrige Hilfe, ich bin zwar immer noch verwirrt, aber auf einer höheren Ebene :D

Code: Select all

double LEA_RAT_START = 0.1;   // The learning rate - start value, 0,01 bs 0,9 akzeptable Werte

double TAR_ERR_M1 = 0.1;   // The target net error - step value - if Target Error goes below 0.1, the Learning Rate will be slower
double LEA_RAT_M1 = 0.05;   // The learning rate - final value, 0,01 bs 0,9 akzeptable Werte

double TAR_ERR_M2 = 0.05;   // The target net error - step value - if Target Error goes below 0.1, the Learning Rate will be slower
double LEA_RAT_M2 = 0.025;   // The learning rate - final value, 0,01 bs 0,9 akzeptable Werte

double TAR_ERR_M3 = 0.03;   // The target net error - step value - if Target Error goes below 0.1, the Learning Rate will be slower
double LEA_RAT_M3 = 0.011;   // The learning rate - final value, 0,01 bs 0,9 akzeptable Werte

double TAR_ERR_FIN = 0.01;   // The target net error - final value

// Erstellen der Variablen fuer die Trace-Ausgabe

// double TAR_ERR_CHECK; 

double netError = GetNetError();

string netErrStr = "Net Err = " + netError;
string netErrStrNachEv0 = "Net Err nach Eval 0 = " + netError;
string netErrStrNachEv1 = "Net Err nach Eval 1 = " + netError;
string netErrStrFinish = "Net Err nach einem Durchlauf = " + netError;

string netErrStr1 = "Net Err 1 = " + netError;
string netErrStr2 = "Net Err 2 = " + netError;
string netErrStr3 = "Net Err 3 = " + netError;

string leaRatStart = "LEARNRATE START = " + LEA_RAT_START;
string leaRatStart1 = "LEARNRATE M1 = " + LEA_RAT_M1;
string leaRatStart2 = "LEARNRATE M2 = " + LEA_RAT_M2;
string leaRatStart3 = "LEARNRATE M3 = " + LEA_RAT_M3;

void main()
{
	// Adjust the view
	ViewSetting(BLACK_BG, true);
	ViewSetting(SHOW_GRID, false);
	ViewSetting(UPDATE_TEACH, true);
	ViewSetting(UPDATE_THINK, true);
	ViewSetting(SHOW_FIRE, false);
	ViewSetting(SHOW_ACT_SPIKES, false);
	ViewSetting(SHOW_LINKS, true);

	OpenNet("V-02_2HL14.mbn"); 		// Open the net to be trained and validated
	RandomizeNet();						// Randomize all link weights and activation thresholds.
	ResetThinkSteps();					// Reset the think step counter
	SetLessonCount(1);					// Delete all lessons except for #1
	/*
	This script uses four lessons in the Lesson Editor (create them now).
	As a net is already loaded the new lessons will be created in sync with the net
	(same I/O names).
	*/
	SetLessonCount(4);
	SelectLesson(1);					// First operate on Lesson #1

	LoadLesson("trainingdataset.mbl");	// Load training lesson
	ShowLessonEditor(false);					// Hide the lesson editor again to fully view the net

	/*
	Set the teacher to be used. This script uses the currently active teacher of MemBrain, thus, the line
	is commented out. Use the name of the teacher you want to set as the active one instead here if you want to
	ensure that a certain teacher is used.
	*/
	//SelectTeacher("Std. BP with Momentum");			// Use the teacher with the name 'BP'
	//Std. BP with Momentum auf Log mit exp log auf 1 umgestellt bei hl
	

	// Adjust the teacher
	
	
	
	
	TeacherSetting(LEARNRATE, LEA_RAT_START);		// The learning rate

	TeacherSetting(TARGET_ERR, TAR_ERR_FIN);	// The final target net error
	


	TeacherSetting(LESSON_REPS, 1);		// Lesson repetitions per teach step,
	TeacherSetting(PATTERN_REPS, 1);	// Pattern repetitions per teach step,
	TeacherSetting(PATTERN_SELECT, RAND_ORDER); // The pattern selection method

	SetTeachSpeed(0);					// Set maximum teach speed

	ShowErrorViewer(true);				// Show the net error viewer and reset it
	ResetErrorViewer();

	EvaluateNetError();
	Trace(netErrStrNachEv0 + "\r");

	
	while (netError > TAR_ERR_FIN)
	{
	
		EvaluateNetError();
		netError = GetNetError();
		Trace(netErrStrNachEv1 + "\r");
			
			StartTeaching();					// Start teaching and wait for stop (target error reached)
			
			netError = GetNetError();
			
			Trace(netErrStr + "\r");
			Trace(leaRatStart + "\r");
			
			if (TAR_ERR_M1 > netError)
				{
				Trace(netErrStr1 + "\r");
				Trace(leaRatStart1 + "\r");
				TeacherSetting(LEARNRATE, LEA_RAT_M1);
				
		//		netError = GetNetError();
				
				if (TAR_ERR_M2 > netError)
					{
					Trace(netErrStr2 + "\r");
					Trace(leaRatStart2 + "\r");
					TeacherSetting(LEARNRATE, LEA_RAT_M2);
					
		//			netError = GetNetError();
					
					if (TAR_ERR_M3 > netError)
						{
						Trace(netErrStr3 + "\r");
						Trace(leaRatStart3 + "\r");
						TeacherSetting(LEARNRATE, LEA_RAT_M3);
						
		//				netError = GetNetError();
							
						} 
						
					}
				}
				

		//	SleepExec();
		StopTeaching();
	
	}

EvaluateNetError();
netError = GetNetError();
Trace(netErrStrFinish + "\r");	

	// ShowErrorViewer(false);			// Hide the error viewer again
	
	ResetThinkSteps();					// Reset think step counter
	
	
	

	// Now prepare lesson #3 to record the output of the net
	SetRecordingType(RT_ACT);			// Record activation values of output neurons
	StartRecording(3);					// Enable recording of data to lesson #3

	ShowLessonEditor(false);			// Hide the lesson editor

	SetThinkSpeed(0);					// 50ms between think steps for animation

	// First record network reaction on training data to lesson #3
	ThinkLesson();						// Think on every pattern in lesson #1 (and record to #3)
	SleepExec();						// Wait until 'Think on Lesson' is finished

	StopRecording();					// Deactivate recording again


	SelectLesson(2);					// Load lesson #2 with the validation data
	// ImportLessonRaw("Decoder4To16_Validate.csv");
	// Could also import a lesson (see line above but the imported file has to use country
	// specific characters for list separation (; or ,) and for decimal point (. or ,)
	
	LoadLesson("testingdataset.mbl");
	EnableLessonOutData(false);			// Don't need any output data, this lesson is input only

	SetRecordingType(RT_ACT);			// Record activation values of output neurons
	StartRecording(4);					// Enable recording of data to lesson #4

	ShowLessonEditor(false);			// Hide the lesson editor

	ThinkLesson();						// Think on every pattern in lesson #2 (and record to #4)
	SleepExec();						// Wait until 'Think on Lesson' is finished

	StopRecording();					// Deactivate recording again

	// Now export lesson #3 and 4 to csv
	SelectLesson(3);
	ExportLessonRaw("TrainResult_StdBPwithMomentum_Schritt_2.csv");
	SelectLesson(4);
	ExportLessonRaw("ValidateResult_StdBPwithMomentum_Schritt_2.csv");

	SaveNet("V-04_2HL14_StdBPwithMomentum.mbn"); 		//  the net trained and validated
		
	// Adjust for maximum speed again
	SetThinkSpeed(0);

	// Uncomment the following line if you want MemBrain to terminate after the script execution
	// ExitMemBrain();
}

User avatar
TJetter
Posts: 346
Joined: Sat 13. Oct 2012, 12:04

Re: Ausgabe der Lernrate und des Netzfehlers im Trace Fenste

Post by TJetter »

Hallo,

zunächst einmal vorweg: Den Aufruf

Code: Select all

EvaluateNetError()
benötigst Du nicht. Dieser erzwingt eine Berechnung des Net Errors. Dieser wird aber ohnehin während des Trainings ständig neu berechnet, kann man sich also sparen, kostet nur Rechenzeit.

Nun zu Deinem Fehler:
Du liest den net error in eine Variable vom Wert double, soweit gut:

Code: Select all

netError = GetNetError();
Dann gibst Du an diversen Stellen einen String aus, z.B.:

Code: Select all

Trace(netErrStrNachEv1 + "\r");
oder auch:

Code: Select all

Trace(netErrStr + "\r");
Trace(leaRatStart + "\r");
Diese Strings baust Du aber nur einmalig oben im Code zusammen, z.B.:

Code: Select all

    double netError = GetNetError();

    string netErrStr = "Net Err = " + netError;
    string netErrStrNachEv0 = "Net Err nach Eval 0 = " + netError;
    string netErrStrNachEv1 = "Net Err nach Eval 1 = " + netError;
Damit gibst Du immer wieder die selben Strings aus, denn die veränderst Du ja nie mehr.
Was Du also tun musst, ist in Deiner Schleife immer wieder Ausgaben wie die folgende einzubauen:

Code: Select all

netError = GetNetError();
Trace(netErrStrPrefix + netErr + "\r");
wobei Dann netErrStrPrefix nur wie folgt definiert sein sollte:

Code: Select all

string netErrStr = "Net Err = ";
Du musst Dir das so vorstellen: Der Ausdruck

Code: Select all

netErrStrPrefix + netErr + "\r"
ist ein zusammengesetzter String aus dem Prefix (dem Inhalt einer string-Variablen), dem net error selbst (automatisch aus der double-Variablen 'netErr' in einen string gewandelt' und der String-Konstanten "\r" (dem Carriage-Return). Dieser zusammengesetzte String wird der Funktion 'Trace' übergeben, die ihn dann in das Trace-Window schreibt.

Noch etwas prinzipielles: Hast Du schon den in MemBrain integrierten Script-Debugger ausprobiert? Kannst Du über das Icon ganz rechts in MemBrain machen. Darin kannst Du dann auch Variablen in ein Watch-Fenster ziehen (Drag & Drop) und schrittweise durch Deinen Code 'steppen'. Die MemBrain Hilfe enthält dazu auch einen Abschnitt. Einzige Sache, die man wissen muss: Wenn der Debugger offen ist und man in MemBrain ein Script startet, dann wird das Script automatisch in den Debugger geladen und dieser hält erst einmal zu Beginn der 'main' Funktion an. Also nicht wundern, wenn sich erst einmal in MemBrain nix tut, da muss man erst im Debugger 'F5' drücken (oder den Play-Button) bzw. mit Step-Kommandos im Code weiterschreiten. Aber vielleicht kennst Du den Debugger ja auch schon, dann tippe ich hier umsonst ;-)

Viele Grüße und viel Erfolg!
Thomas Jetter
Gruschel
Posts: 3
Joined: Tue 29. Oct 2013, 11:36

Re: Ausgabe der Lernrate und des Netzfehlers im Trace Fenste

Post by Gruschel »

Hallo,

nochmal danke für deine Hilfe :D

Jetzt funktioniert alles wie es soll.
Ich musste nur vor dem while-Befehl das EvaluateNetError() drin lassen, weil er sonst einen Startwert von -1 hat als NetError, was nicht so ganz funktioniert.

Mit dem Debugger kämpfe ich noch ein bissel, muss die Hilfe diesbezüglich offensichtlich noch mal lesen.

Bin grad am aufräumen des scripts und wünsch dir ein schönes verlängertes WE, falls du morgen auch frei hast.

LG, Gruschel
User avatar
TJetter
Posts: 346
Joined: Sat 13. Oct 2012, 12:04

Re: Ausgabe der Lernrate und des Netzfehlers im Trace Fenste

Post by TJetter »

Gruschel wrote:Ich musste nur vor dem while-Befehl das EvaluateNetError() drin lassen, weil er sonst einen Startwert von -1 hat als NetError, was nicht so ganz funktioniert.
Wenn der Net Error noch nie berechnet wurde, ist sein Initialwert -1, ja. Damit kann man entweder so umgehen, dass man erst einmal ein 'EvaluateNetError' ausführt, oder in dem man den Fall netError < 0 im Script getrennt behandelt.
Verlängertes Wochenende habe ich leider keines, aber Dir wünsche ich ein schönes solches!

Viele Grüße
Thomas Jetter
Post Reply