Machine Learning mit WEKA

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Syr2
Beiträge: 31
Registriert: 11.03.2020 13:39

Machine Learning mit WEKA

Beitrag von Syr2 »

Weil es in Purebasic manchmal etwas schwierig ist die ganzen MachineLearning Algorithmen zu implementieren (OpenCV und so ist ja nicht ganz einfach) habe ich mal eine kleine Lib geschrieben um das Toolset "WEKA" in Purebasic(z.Z. NUR Windows) zu verwenden.
Bild

Pro:
  • Supportet EXTREM viele verschiedene Algorithmen
  • Arbeitet nach der Initialisierung recht schnell
  • Ist gut parametrisierbar


Cons:
  • Nicht für Echtzeitanwendungen anwendbar, Initialisierung dauert ewig (> 200ms)
  • CLI über eine Java-Funktion die irgendwann gelöscht werden soll
  • Diese Lib geht nur über Windows
  • Diese Lib hat noch fast keine Funktionen und keine Parametrisierung

Code: Alles auswählen

;{ Check correct Setup
;Get Current Weka Version
ProgramfilesPath.s = "C:\Program Files\"
d = ExamineDirectory(#PB_Any,ProgramfilesPath,"*.*")
While NextDirectoryEntry(d)
  name$ = DirectoryEntryName(d)
  If FindString(name$,"Weka")
    WekaVersion$ = name$
    Break
  EndIf
Wend
FinishDirectory(d)

VersionNr$ = RemoveString(ReplaceString(WekaVersion$,"-","."),"Weka.")
If WekaVersion$ = ""
  MessageRequester("Error","No Weka found in Programfiles.")
  End
EndIf

;Is Weka instlaled?
Global WekaJarPath.s = "C:\Program Files\"+WekaVersion$+"\weka.jar"
If FileSize(WekaJarPath) <= 0
  MessageRequester("Error","Cannot load Weka")
  End
EndIf

;Is imageFilers installed?
ImageFiltersPackagePath.s = GetHomeDirectory()+"wekafiles\packages\imageFilters\imageFilters.jar"
If FileSize(ImageFiltersPackagePath) <= 0
  MessageRequester("Error","Cannot find imageFilter plugin")
EndIf

;Where is Javaw.exe?
Procedure.s Recurvsive_search(Path.s,SearchName.s)
  d = ExamineDirectory(#PB_Any,Path,"*.*")
  While NextDirectoryEntry(d)
    name$ = DirectoryEntryName(d)
    
    If name$ = "." Or name$ = ".."
      Continue
    EndIf
    
    If DirectoryEntryType(d) = #PB_DirectoryEntry_Directory
      Result$ = Recurvsive_search(Path+name$+"\",SearchName)
      If Len(Result$) > 0
        FinishDirectory(d)
        ProcedureReturn Result$
      EndIf
    ElseIf DirectoryEntryType(d) = #PB_DirectoryEntry_File
      If FindString(name$,SearchName) Or name$ = SearchName
        FinishDirectory(d)
        ProcedureReturn Path+name$
      EndIf
    EndIf
  Wend
  FinishDirectory(d)
EndProcedure

Global javapath.s = Recurvsive_search(GetPathPart(WekaJarPath),"java.exe")
If Len(javapath) <= 0
  MessageRequester("Error","Could not find javaw.exe in Weka's subdirectories. It should be in C:\Program Files\Weka-3-8-5\jre\zulu11.43.55-ca-fx-jre11.0.9.1-win_x64\bin\java.exe")
  End
EndIf

Structure FileAndType
  Filepath.s
  Class.s ; Only needed for training. For testing, just ignore it.
EndStructure
;}

Procedure.s Weka_Internal_ImageFilter_Extract_Features(ArffFile.s,DatasetPath.s,Filter.s="FCTH") ; TODO: Filter MAGIC HAPPENS HERE!
  FeaturesFile.s = GetTemporaryDirectory()+"features.arff"
  
  Select Filter.s
    Case "PHOG"
      Filter.s = "weka.filters.unsupervised.instance.imagefilter.PHOGFilter"
    Case "FCTH"
      Filter.s = "weka.filters.unsupervised.instance.imagefilter.FCTHFilter"
  EndSelect
  
  ;Extract Features
  RunProgram(javapath," -cp "+Chr(34)+WekaJarPath+Chr(34)+" weka.Run "+Filter+" -i "+ArffFile+" -D "+DatasetPath+" -o "+FeaturesFile,GetCurrentDirectory(),#PB_Program_Open | #PB_Program_Wait | #PB_Program_Hide)
  
  ;Remove first feature-Line 'filename'
  RenameFile(FeaturesFile,GetPathPart(FeaturesFile)+"old.arff")
  Command.s = "weka.filters.unsupervised.attribute.Remove -R 1"
  RunProgram(javapath,"-cp "+Chr(34)+WekaJarPath+Chr(34)+" weka.Run "+command+" -i "+GetPathPart(FeaturesFile)+"old.arff"+" -o "+FeaturesFile,GetCurrentDirectory(),#PB_Program_Open | #PB_Program_Wait | #PB_Program_Hide)
  DeleteFile(GetPathPart(FeaturesFile)+"old.arff")
  
  ProcedureReturn FeaturesFile
  
EndProcedure

Procedure.s Weka_Internal_Create_Imagefilter_Arff(List DataSet.FileAndType())
  InternalArffPath.s = GetTemporaryDirectory()+"Purebasic_Weka.arff"
  
  NewMap Classes.s()
  ForEach DataSet()
    Classes(DataSet()\Class) = ""
  Next
  
  arfffile = CreateFile(#PB_Any,InternalArffPath)
    WriteStringN(arfffile,"@relation Purebasic_Automation")
    WriteStringN(arfffile,"@attribute filename string")
    WriteString(arfffile,"@attribute class {")
    first = 1
    ForEach Classes()
      If first = 0
        WriteString(arfffile,",")
      Else
        first = 0
      EndIf
      WriteString(arfffile,MapKey(Classes()))
    Next
    FreeMap(Classes())
    
    WriteStringN(arfffile,"}")
    WriteStringN(arfffile,"@data")
    ForEach DataSet()
      WriteStringN(arfffile,DataSet()\Filepath+","+DataSet()\Class)
    Next
  CloseFile(arfffile)
  
  ProcedureReturn InternalArffPath    
EndProcedure

Procedure.s Weka_LoadImages(List DataSet.FileAndType(), DatasetPath.s)
  InternalArff$ = Weka_Internal_Create_Imagefilter_Arff(DataSet())
  FeatureArff$  = Weka_Internal_ImageFilter_Extract_Features(InternalArff$,DatasetPath,"FCTH")
  DeleteFile(InternalArff$)
  ProcedureReturn FeatureArff$
EndProcedure

Procedure Weka_LoadText()
EndProcedure

Procedure.s Weka_Train(DatasetArffFile.s, Classifier.s, SaveFileName.s) ; TODO: Training MAGIC HAPPENS HERE!
  Select Classifier
    Case "SupportVectorMachine"
      Command.s = "weka.classifiers.functions.SMO -C 1.0 -L 0.001 -P 1.0E-12 -N 0 -V -1 -W 1 -K "+Chr(34)+"weka.classifiers.functions.supportVector.PolyKernel -E 1.0 -C 250007"+Chr(34)+" -calibrator "+Chr(34)+"weka.classifiers.functions.Logistic -R 1.0E-8 -M -1 -num-decimal-places 4"+Chr(34)
    Case "NeuralNetwork"
      Command.s = "weka.classifiers.functions.MultilayerPerceptron -L 0.3 -M 0.2 -N 500 -V 0 -S 0 -E 20 -H a"
    Case "RandomForest"
      Command.s = "weka.classifiers.trees.RandomForest -P 100 -I 100 -num-slots 1 -K 0 -M 1.0 -V 0.001 -S 1"
  EndSelect
  
  p = RunProgram(javapath," -cp "+Chr(34)+WekaJarPath+Chr(34)+" weka.Run "+Command+" -t "+DatasetArffFile+" -d "+SaveFileName,GetCurrentDirectory(),#PB_Program_Open | #PB_Program_Hide)
  If p
    While ProgramRunning(p)
      If AvailableProgramOutput(p)
        Debug ReadProgramString(p)
      EndIf
    Wend
  EndIf
  ProcedureReturn SaveFileName 
EndProcedure

Procedure.s Weka_Test(TestDataArff.s, Classifier.s, TrainedModelFile.s)
  If FileSize(TrainedModelFile) < 0
    MessageRequester("Error","Applied TrainingModel does not exist")
  EndIf
  
  Select Classifier
    Case "SupportVectorMachine"
      Command.s = "weka.classifiers.functions.SMO"
    Case "NeuralNetwork"
      Command.s = "weka.classifiers.functions.MultilayerPerceptron"
    Case "RandomForest"
      Command.s = "weka.classifiers.trees.RandomForest"
  EndSelect
  
  p= RunProgram(javapath," -cp "+Chr(34)+WekaJarPath+Chr(34)+" weka.Run "+Command+" -T "+TestDataArff+" -l "+TrainedModelFile+" -p 0 ",GetCurrentDirectory(),#PB_Program_Open | #PB_Program_Hide | #PB_Program_Read)
  Output$ = ""
  If p
    While ProgramRunning(p)
      If AvailableProgramOutput(p)
        Output$ + ReadProgramString(p) + Chr(13)
      EndIf
    Wend
  EndIf
    
  ProcedureReturn Output$ 
EndProcedure

NewList Datensatz.FileAndType()
Macro AddDatensatz(ClassName,PathName)
  AddElement(Datensatz()) : Datensatz()\Class = ClassName  : Datensatz()\Filepath = PathName
EndMacro

NewList TestSatz.FileAndType()

CompilerIf Not #PB_Compiler_IsIncludeFile
;Our Data
  DatasetPath.s = "C:\Users\"+username()+"\wekafiles\packages\imageFilters\data\butterfly_vs_owl\"
  
  d = ExamineDirectory(#PB_Any,DatasetPath,"*.jpg")
  While NextDirectoryEntry(d)
    name$ = DirectoryEntryName(d)
    If name$ = "." Or name$ = ".."
      Continue
    EndIf
    If FindString(name$,"mno")
      AddDatensatz("Butterfly",name$)
    ElseIf FindString(name$,"owl")
      AddDatensatz("Owl",name$)
    EndIf
  Wend
  FinishDirectory(d)
  
  ;Split Test-Datensatz away
  OwlCounter = 0
  ButterflyCounter = 0
  ForEach Datensatz()
    If Datensatz()\Class = "Owl" And OwlCounter < 10
      OwlCounter +1
    ElseIf Datensatz()\Class = "Butterfly" And ButterflyCounter < 10
      ButterflyCounter+1
    Else
      Continue
    EndIf
    AddElement(TestSatz()) : TestSatz()\Class = Datensatz()\Class : TestSatz()\Filepath = Datensatz()\Filepath : DeleteElement(Datensatz())
  Next
  
;Start Working
SaveFileName.s      = DatasetPath+"Trained.brain"
ArffFile$           = Weka_LoadImages(Datensatz(),DatasetPath)
TrainedBrainFile.s  = Weka_Train(ArffFile$,"RandomForest",SaveFileName)
DeleteFile(ArffFile$)

TestArffFile$       = Weka_LoadImages(TestSatz(),DatasetPath)
TestResult.s        = Weka_Test(TestArffFile$,"RandomForest",TrainedBrainFile)

DeleteFile(TestArffFile$)

Debug TestResult
CompilerEndIf
Hinweis zur Nutzung:

Installiert WEKA, ich habe hier Version 3.8.5, ist aber auch auf&ab-wärtskompatibel.
Laded imagefilters.zip und extrahiert es nach C:\Users\DEINUSERNAME\wekafiles\packages\
Also so, dass danach alle Daten in C:\Users\User\wekafiles\packages\imageFilters\ liegen.


Wenn das klappt, sollte das o.g. Programm durchstarten.
Hier noch ein paar Hinweise:

Die Lib ist aktuell nur speziell für Bilder da, kann aber problemlos erweitert werden.
Die wichtigsten Schritte sind:

1) Datensatz erzeugen. Das macht die Funtkion Weka_LoadImages(List Datensatz(),DatasetPath)
1. Parameter sollte eine Liste der Struktur FileAndType sein. Das ist einfach ein String mit dem Dateinamen des Bildes und ein String mit dem Label des Bildes. Wenn ihr nicht trainiert sondern testet, dann lasst einfach das Label leer.
2. Parameter ist der absolute Pfad wo eure Bilder liegen. Sie müssen also alle an einem Ort liegen.
Wenn alles passt wird im %Temp%-Ordner eine Purebasic_Weka.arff Datei angelegt.

2) Daten filtern / Merkmale extrahieren
Der o.g. LoadImages Befehl macht automatisch diesen Schritt. Jetzt werden die Bilder von WEKA ausgewertet und die Merkmale extrahiert. Automatisch wird der FCTH-Filter angewandt, ihr könnt aber auch der Funktion Weka_Internal_ImageFilter_Extract_Features ein PHOG-Filter übergeben. Zum Abspeichern der Ergebnisse wird dann die Datei features.arff erzeugt. Die alte
Purebasic_Weka.arff wird gelöscht. Die neue Datei wird nochmal kurz umbenannt, gelöscht und wiedererzeugt. Hat was damit zu tun, dass die extrahierten Merkmale alles nur noch Zahlen sind, und das Label, also der Text des Bildes auch noch in den Daten drin steht. Das wird rausgelöscht.

3) Training
Der Befehl Weka_Train(DatasetArffFile.s, Classifier.s, SaveFileName.s) startet das Training mit der von euch oben angegebenen Arff-Datei (kam als Rückgabeparameter auch zurück) und speichert das Ergebnis in eine Wunschdatei. Ich nenne die zum Spass immer .model oder .brain, ist aber kein geschütztes Format.
Die von mir eingebauten Classifier sind zurzeit :
  • "SupportVectorMachine"
  • "NeuralNetwork"
  • "RandomForest"
Die Parameter können zurzeit nur im Code geändert werden. Erfahrungsgemäß kann ich sagen, dass die SVM am schnellsten ist, das NeuralNetwork potentiell am fähigsten ist (in der Praxis aber eher nicht) und der RandomForest die besten Ergebnisse liefert (ist so eine Art Brute-Force auf die beste Methode). Wer die Klassifizierer selbst erweitern will der sollte einfach Weka mit der GUI benutzen und den Klassifizierer aus der GUI benutzen. Danach steht rechts unten bei "Log" der genau Befehl für die CLI. AB dann muss man sich etwas an meinem Code entlanghangeln, der wesentliche Befehl auf der Console würde lauten: java.exe -cp weka.jar Weka.Run *DerBefehlAusDemLogKommtHierRein*. Wenn man das einfach mal auf der Commandline ausführt steht sehr weit oben der Fehler, warum es nicht geht. Denk dran die java.exe in Anführungszeichen zu setzen.

4) Test-Datensatz
Wenn nicht bereits geschehen, dann braucht ihr jetzt noch einen Test-Datensatz (muss disjunkt sein) mit dem ihr eure neue AI testen könnt. Disjunkt, für die die es nicht wissen heisst, dass der Datensatz keine gemeinsamen Daten mit dem Training-Satz haben sollte. Das wäre als würde man in der Mathearbeit die gleichen Aufgaben wie in den Hausaufgaben bekommen - das kann man ja eh schon ;)
Zum Erstellen nehmt ihr den Befehl aus Schritt 1: Weka_LoadImages(TestSatz(),DatasetPath)

5) Testen! Yey
Die Funktion Weka_Test(TestArffFile$,"RandomForest",TrainedBrainFile) nimmt die drei Parameter:
String mit dem Pfad auf die Arff-Datei aus Schritt 4
String für den Klassifizierer aus Schritt 3
Vortrainiertes Model aus Schritt 3

Wenn alles klappt bekommt ihr als Rückgabe einen String mit dem Ergebnis drin.

Hier ein Beispiel (auch im Code) zur Erzeugung der Datenbasis:

Code: Alles auswählen

;Our Data
  DatasetPath.s = "C:\Users\"+username()+"\wekafiles\packages\imageFilters\data\butterfly_vs_owl\"
  
  d = ExamineDirectory(#PB_Any,DatasetPath,"*.jpg")
  While NextDirectoryEntry(d)
    name$ = DirectoryEntryName(d)
    If name$ = "." Or name$ = ".."
      Continue
    EndIf
    If FindString(name$,"mno")
      AddDatensatz("Butterfly",name$)
    ElseIf FindString(name$,"owl")
      AddDatensatz("Owl",name$)
    EndIf
  Wend
  FinishDirectory(d)
  
  ;Split Test-Datensatz away
  OwlCounter = 0
  ButterflyCounter = 0
  ForEach Datensatz()
    If Datensatz()\Class = "Owl" And OwlCounter < 10
      OwlCounter +1
    ElseIf Datensatz()\Class = "Butterfly" And ButterflyCounter < 10
      ButterflyCounter+1
    Else
      Continue
    EndIf
    AddElement(TestSatz()) : TestSatz()\Class = Datensatz()\Class : TestSatz()\Filepath = Datensatz()\Filepath : DeleteElement(Datensatz())
  Next
Hier dann der entsprechende Code zum Training, Speichern, Laden und Testen

Code: Alles auswählen

;Start Working
SaveFileName.s      = DatasetPath+"Trained.brain"
ArffFile$           = Weka_LoadImages(Datensatz(),DatasetPath)
TrainedBrainFile.s  = Weka_Train(ArffFile$,"RandomForest",SaveFileName)
DeleteFile(ArffFile$)

TestArffFile$       = Weka_LoadImages(TestSatz(),DatasetPath)
TestResult.s        = Weka_Test(TestArffFile$,"RandomForest",TrainedBrainFile)

DeleteFile(TestArffFile$)
Und hier meine Ausgabe:
=== Predictions on test data ===

inst# actual predicted error prediction
1 1:Butterfly 1:Butterfly 0.83
2 1:Butterfly 1:Butterfly 0.63
3 1:Butterfly 1:Butterfly 0.98
4 1:Butterfly 2:Owl + 0.55
5 1:Butterfly 1:Butterfly 0.58
6 1:Butterfly 2:Owl + 0.52
7 1:Butterfly 2:Owl + 0.51
8 1:Butterfly 1:Butterfly 0.74
9 1:Butterfly 1:Butterfly 0.91
10 1:Butterfly 1:Butterfly 0.83
11 2:Owl 2:Owl 0.84
12 2:Owl 2:Owl 0.83
13 2:Owl 2:Owl 0.8
14 2:Owl 2:Owl 0.92
15 2:Owl 2:Owl 0.89
16 2:Owl 2:Owl 0.78
17 2:Owl 2:Owl 0.91
18 2:Owl 2:Owl 0.89
19 2:Owl 2:Owl 0.6
20 2:Owl 2:Owl 0.98
Das liest sich jetzt so, dass die erste Datei laut eigenen Angaben ein "Butterfly" ist und dass das Ergebnis mit einer Sicherheit von 83% das ganze als Butterfly erkannt hat. Im Falle der 4. Datei wurde beispielsweise ein Butterfly mit 55% als "Owl" erkannt - also falsch. Denkt an das Thema "Disjunkt" von oben, sonst steht da überall nur 1.0 und er macht angeblich alles richtig. Hier ist allerdings ein kleiner Fehler passiert: Normalerweise kennt man die Labels der Bilder ja nicht vor dem Test. Daher wäre die erste Spalte eigentlich leer. (Hab ich aus Faulheit aus dem Test-Datensatz rausgeschnitten. Richtig wäre es gewesen, die Class-Information wegzuwerfen - Ist aber für den Test egal weil es ignoriert wird)

Der hier verwendete Datensatz ist Teil des imagefilters-packets. Siehe: https://github.com/mmayo888/ImageFilter (gleicher Link wie oben)

So und jetzt ihr:
  • Soll ich auch ne Demo schreiben, wenn ja wofür? (Captchas, Spiel, Generierung...?)
  • Was ist alles unklar? Ist einfach mal so dahingeschrieben weil ich die Lib selbst schon zweimal neu geschrieben hab weil ich es nicht gespeichert hab. Also sorry für nicht schön.
Zuletzt geändert von Syr2 am 21.09.2021 22:49, insgesamt 1-mal geändert.
Benutzeravatar
dige
Beiträge: 1182
Registriert: 08.09.2004 08:53

Re: Machine Learning mit WEKA

Beitrag von dige »

Definitiv spannendes Thema und vielen Dank für deine bisherige Arbeit!

Die Bugwelle sich da reinzuarbeiten ist für mich recht hoch. Ein Demo Projekt wäre da sehr hilfreich.
Mich würden da vor allem Dinge wie Bildanalysen, Face Recognition interessieren, die einem helfen
bei der Verwaltung von Bildern.
"Papa, mein Wecker funktioniert nicht! Der weckert immer zu früh."
Syr2
Beiträge: 31
Registriert: 11.03.2020 13:39

Re: Machine Learning mit WEKA

Beitrag von Syr2 »

Irgendeinen Wunsch welche Art von Bildern? Eulen und Schmetterlinge habe ich ja oben schon gezeigt. Kannst du mir bestenfalls ein paar Bilder geben die schon gelabelt sind? Als Trainingsdaten mein ich.
Gruß
Syr2
Syr2
Beiträge: 31
Registriert: 11.03.2020 13:39

Re: Machine Learning mit WEKA

Beitrag von Syr2 »

Benutzeravatar
dige
Beiträge: 1182
Registriert: 08.09.2004 08:53

Re: Machine Learning mit WEKA

Beitrag von dige »

Syr2 hat geschrieben: 14.09.2021 20:17 Irgendeinen Wunsch welche Art von Bildern?
Also Gesichter erkennen wäre gut und dann vielleicht noch Haustiere wie Hunde, Katzen..?
"Papa, mein Wecker funktioniert nicht! Der weckert immer zu früh."
Syr2
Beiträge: 31
Registriert: 11.03.2020 13:39

Re: Machine Learning mit WEKA

Beitrag von Syr2 »

1.Download der Daten
Also als Datensatz nehme ich das hier: https://www.kaggle.com/tongpython/cat-and-dog/download
darin ist die archive.zip
  • test_set
  • training_set
mit je 1000 Katzen / Hunde Fotos

Diese Daten entpacke ich erstmal und beschränke mich auf die training_set-Dateien. Wir wollen ja nicht mit den Test-Daten trainieren.

2.Laden der Trainingsdaten und Merkmalsextraktion

Ich hab jetzt mal alle Hunde- und Katzenbilder an den gleichen Ort kopiert.
Und von da aus lade ich dann wie folgt die Daten:

Code: Alles auswählen

  DatasetPath.s = "C:\Users\"+UserName()+"\Downloads\archive\training_set\training_set\"
  
  d = ExamineDirectory(#PB_Any,DatasetPath,"*.jpg")
  While NextDirectoryEntry(d)
    name$ = DirectoryEntryName(d)
    If name$ = "." Or name$ = ".."
      Continue
    EndIf
    If Left(name$,3) = "cat"
      AddDatensatz("cat",name$)
    ElseIf Left(name$,3) = "dog"
      AddDatensatz("dog",name$)
    EndIf
  Wend
  FinishDirectory(d)
Gleich danach mache ich, wie oben vorgemacht, die Arff-Datei mit dem Befehl Weka_Loadimages. Die Daten werden also aus der Liste Datenstz() an Weka übergeben und am entsprechenden DatasetPath gesucht und abgearbeitet (Merkmale werden extrahiert mit dem FCTH-Filter, da ich keinen Parameter angegeben habe. (OHIG ginge auch)

Code: Alles auswählen

SaveFileName.s      = DatasetPath+"Trained.brain"
ArffFile$           = Weka_LoadImages(Datensatz(),DatasetPath)
3.Starte das Training

Naja und jetzt haben wir ja die Arff-Datei von oben. Die geben wir einaach an Weka_Train zusammen mit dem String für den Algorithmus, hier RandomForest. Das ganze soll als Ausgabe in der SaveFilename-Datei landen. Das ist dann das fertig vortraininerte Modell. Sozusagen das Gehirn. In meinem Fall hat das ca 4 min gedauert- man sieht aber keinen Fortschritt also einfach warten. Bei besonders vielen Bildern auf einmal kann es auch crashen glaube ich, hier aber nicht.

Code: Alles auswählen

TrainedBrainFile.s  = Weka_Train(ArffFile$,"RandomForest",SaveFileName)
DeleteFile(ArffFile$)
In meinem Fall hat die Trained.brain Datei jetzt knapp 34,5 MB.

4.Anwenden auf neue Daten - Vorbereitung der Test-Daten

Eigentlich sind wir schon fertig, aber wir wollen ja gerne wissen was das Training so gebracht hat und es auch irgendwie sinnvoll anwenden.

Jetzt arbeiten wir mit dem test_set. Auch hier kompiere ich wider alle Katzen und Hundebilder in einen Ordner. Wenn wir die Dateinamen beibehalten können wir automatisiert überprüfen, wie gut das Training war. Andernfalls müssen wir das Ergebnis eben von Hand vergleichen.

Code: Alles auswählen

NewList TestSatz.FileAndType()

  DatasetPath.s = "C:\Users\"+UserName()+"\Downloads\archive\test_set\test_set\"
  d = ExamineDirectory(#PB_Any,DatasetPath,"*.jpg")
  While NextDirectoryEntry(d)
    name$ = DirectoryEntryName(d)
    If name$ = "." Or name$ = ".."
      Continue
    EndIf
    If Left(name$,3) = "cat"
      AddDatensatz("cat",name$)
    ElseIf Left(name$,3) = "dog"
      AddDatensatz("dog",name$)
    EndIf
  Wend
  FinishDirectory(d)
5.Genau wie bei Schritt 2 : Merkmalsextraktion - jetzt

Code: Alles auswählen

 TestArffFile$       = Weka_LoadImages(TestSatz(),DatasetPath) 
6.Und Test starten

Code: Alles auswählen

debug Weka_Test(TestArffFile$,"RandomForest",TrainedBrainFile)
Fertig: Ergebnis

Hier kommt als Ergebnis:

=== Predictions on test data ===

inst# actual predicted error prediction
1 2:cat 1:dog + 0.63
2 2:cat 2:cat 0.65
3 2:cat 2:cat 0.65
4 2:cat 2:cat 0.61
5 2:cat 1:dog + 0.6
6 2:cat 2:cat 0.59
7 2:cat 1:dog + 0.55
8 2:cat 2:cat 0.69
9 2:cat 2:cat 0.65
10 2:cat 2:cat 0.6
11 2:cat 1:dog + 0.5
12 2:cat 2:cat 0.9
13 2:cat 2:cat 0.68
14 2:cat 2:cat 0.68
15 2:cat 1:dog + 0.5
16 2:cat 2:cat 0.62
17 2:cat 1:dog + 0.5
18 2:cat 2:cat 0.71
19 2:cat 2:cat 0.59
20 2:cat 2:cat 0.52
21 2:cat 2:cat 0.55
[...]
2015 1:dog 2:cat + 0.74
2016 1:dog 1:dog 0.62
2017 1:dog 1:dog 0.79
2018 1:dog 2:cat + 0.57
2019 1:dog 1:dog 0.68
2020 1:dog 1:dog 0.85
2021 1:dog 2:cat + 0.62
2022 1:dog 2:cat + 0.67
2023 1:dog 2:cat + 0.59
Fragt mich nciht warum es mehr wie 2000 Tests waren - kein Plan. Aber die linke spalte sagt was es sein sollte, die rechte was als Ergebnis bei rum kam. Man sieht also, dass wir hier gar nicht mal so gut abschneiden. Wir sollten vllt mal del Algorthmus ändern - oder wer es sich zutraut kann auch die Parameter ändern (dann aber hart eingreifen und die Command-line-Parameter im "Runprogram Weka.Run..." ändern. Fürs erste soll das hier reichen.
Syr2
Beiträge: 31
Registriert: 11.03.2020 13:39

Re: Machine Learning mit WEKA

Beitrag von Syr2 »

Lief übrigens fehlerfrei auf Anhieb ohne schummeln auf einem anderen Rechner wie die Entwicklung. Scheint also nicht ganz so übel zu sein wie ich dachte :-D
Zuletzt geändert von Syr2 am 22.09.2021 10:29, insgesamt 1-mal geändert.
Benutzeravatar
dige
Beiträge: 1182
Registriert: 08.09.2004 08:53

Re: Machine Learning mit WEKA

Beitrag von dige »

Mmmh, bei mir wurde keine .brain Datei erstellt:

Code: Alles auswählen

  DatasetPath.s = "C:\Users\"+UserName()+"\wekafiles\packages\catsndogs\training_set\training_set\"
  
  d = ExamineDirectory(#PB_Any,DatasetPath,"*.jpg")
  While NextDirectoryEntry(d)
    name$ = DirectoryEntryName(d)
    If name$ = "." Or name$ = ".."
      Continue
    EndIf
    
    If Left(name$,3) = "cat"
      AddDatensatz("cat",name$)
    ElseIf Left(name$,3) = "dog"
      AddDatensatz("dog",name$)
    EndIf
    
  Wend
  FinishDirectory(d)
  
  SaveFileName.s      = DatasetPath+"Trained.brain"
  ArffFile$           = Weka_LoadImages(Datensatz(),DatasetPath)
  
  TrainedBrainFile.s  = Weka_Train(ArffFile$,"RandomForest",SaveFileName)

  Debug ArffFile$
  Debug TrainedBrainFile.s
  
  CallDebugger
"Papa, mein Wecker funktioniert nicht! Der weckert immer zu früh."
Syr2
Beiträge: 31
Registriert: 11.03.2020 13:39

Re: Machine Learning mit WEKA

Beitrag von Syr2 »

Davon ausgehend dass du an dem Pfad auch wirklich die Bilder liegen hast kannst du ja mal folgendes probieren:

1. Debugger auf den Weka_LoadImages Befehl (F9) und dann im Variablen-Viewer suchst du nach der Liste Datensatz(). Schau mal ob die auch korrekt befüllt wurde.
2. ändere den befehl

Code: Alles auswählen

  RunProgram(javapath," -cp "+Chr(34)+WekaJarPath+Chr(34)+" weka.Run "+Filter+" -i "+ArffFile+" -D "+DatasetPath+" -o "+FeaturesFile,GetCurrentDirectory(),#PB_Program_Open | #PB_Program_Wait | #PB_Program_Hide)
zu

Code: Alles auswählen

  RunProgram(javapath," -cp "+Chr(34)+WekaJarPath+Chr(34)+" weka.Run "+Filter+" -i "+ArffFile+" -D "+DatasetPath+" -o "+FeaturesFile,GetCurrentDirectory(),#PB_Program_Open | #PB_Program_Wait)
Also einfach das hide am Ende löschen.
Dann müsste eigentlich eine Kommandozeile aufpoppen. Kannst ja mal ein Screenshot posten. Vllt stimmt iwas mit weka nicht.
Gruß
Syr2
Benutzeravatar
dige
Beiträge: 1182
Registriert: 08.09.2004 08:53

Re: Machine Learning mit WEKA

Beitrag von dige »

Als Fehler wird "An illegal reflective access operation occurred" angezeigt.

Datensatz() enthielt zunächst keine Werte. Ich habe übersehen, dass die Bilder in getrennten Verzeichnissen abgelegt sind und habe diese nun zusammen kopiert.
Danke für den Debug Tipp.

Die Datei Trained.brain (35MB) wurde erzeugt, der obige Fehler tritt zwar immer noch auf, aber es geht jetzt
Zuletzt geändert von dige am 22.09.2021 14:41, insgesamt 1-mal geändert.
"Papa, mein Wecker funktioniert nicht! Der weckert immer zu früh."
Antworten