Vorwort
Im maschinellen Lernen sind Faltungsnetzwerke tiefe künstliche neuronale Netzwerke, die erfolgreich auf die Bilderkennung angewendet wurden. Gegenwärtig verwenden viele Nummernschildnummer -Anerkennung, Gesichtserkennung usw. Faltungsnetzwerke. Es kann gesagt werden, dass die neuronalen Netzwerke mit Faltungsstücken großer Erfolg bei der Bilderkennung erzielt haben. Es gibt viele Open -Source -Deep -Lern -Frameworks wie Kaffe, Tensorflow, Taschenlampe usw. Diese Deep -Learning -Frameworks umfassen die Implementierung vollständiger Faltungsnetzwerke. Warum müssen wir uns noch immer mit Faltungsnetzen schreiben? Es ist besser, diese Open Source Deep Learning -Frameworks direkt zu verwenden, die schnell und einfach zu handhaben sind, eine gute Leistung und nur wenige Fehler haben. Ja, wenn Sie nur neuronale Netzwerke mit Faltungsstücken einsetzen, um einige Anwendungen zu erstellen und sich nicht für das Arbeitsprinzip zu interessieren, müssen Sie nicht hart arbeiten, um neurale Faltungsnetzwerke zu schreiben. Aber wenn Sie das Arbeitsprinzip der neuronalen Faltungsnetzwerke vollständig beherrschen möchten, sagten die Alten: Was Sie auf Papier erhalten, ist immer flach, und Sie müssen zu diesem Zeitpunkt das Bewusstsein praktizieren. Daher ist es sehr notwendig, dass Sie das neuronale Netzwerk von Faltungen selbst implementieren, um Ihr Verständnis davon zu vertiefen.
Was ist Cupcnn
Cupcnn ist ein in Java geschriebenes Faltungsnetz. Zusätzlich zur Arbeit erkannte ich es, um mein Verständnis von Faltungsnetzwerken zu vertiefen. Es ist einfach genug und funktioniert gut, sodass Anfänger sehr geeignet sind. Sein Quellcode kann von Github: Cupcnn heruntergeladen werden
Sie müssen sich keine Sorgen über die Grenzen seines Protokolls oder so machen. Sie können es verwenden, um alles zu tun und willkürlich zu ändern. Wenn es Ihnen helfen kann, hoffe ich, dass es Ihnen einen Stern geben kann! ! !
^-^^-^^-^^-^
Designideen
Ich hoffe, es ist ein neuronales Netzwerk, das einfach genug ist, um Anfängern zu erleichtern. Deshalb habe ich diese gleichzeitigen Beschleunigungsmaterial nicht implementiert, die die Einführung des Codes garantieren. Beim Entwerfen habe ich das Faltungsnetz in vier Module unterteilt: Network (Layer Blob Loss Active), die aus dem Paketnamen ersichtlich sind. Schicht, Verlust und Aktiv haben alle eine Basisklasse, und die Programmierung des gesamten neuronalen Netzwerks ist auf die Basisklasse ausgerichtet. Das Netzwerk ist das Zentrum, das diese vier Module, Koordinaten und Versand von Ressourcen integriert. Jede Schicht hat eine Instanz des Netzwerks, so dass verschiedene Daten leicht über das Netzwerk erhalten werden können, z.
Das Design -Block -Diagramm lautet wie folgt:
Das Speichern von Parametern ist für Java sehr einfach. Durch die Implementierung der serialisierbaren Schnittstelle kann die Serialisierung und Deserialisierung von Parametern schnell implementiert werden. Cupcnn implementiert nur die serialisierbare Schnittstelle für Blob und Blobparams im Datenverzeichnis, und alle Parameter werden von diesen beiden implementiert.
Aktuelle Leistung
Vollständiger neuronales Netzwerk
Derzeit ist im MNIST -Datensatz ein vollständig verbundenes neuronales Netzwerk (Vollverbindung (100) + Vollverbindung (30) + Vollverbindung (10) + Softmax) mit 30 Epoes mit einer Genauigkeitsrate von 96,76 trainiert
Faltungsnetzwerk
Faltungsnetzwerk (6 Merkmale) + Maximale Pooling + Faltung (6 Merkmale) + Vollständige Verbindung (512) + Vollständige Verbindung (30) + Vollständige Verbindung (10) + Softmax), wenn die Lernrate 0,2, 30 EPOES geschult werden, beträgt die Genauigkeitsrate 97,79. Ich glaube, dass die Genauigkeitsrate nach einer weiteren Parameterabstimmung unter ausreichendem Training höher sein kann.
Der Trainings -Schnappschuss des neuronalen Netzwerks ist wie folgt:
mit dem Zug beginnen
Epoe: 0 Verlustwert: 2.3019369891560455 LR: 0,2 Genauigkeit beträgt 0,13
Epoe: 0 Verlustwert: 2.0722489482105195 LR: 0,2 Genauigkeit beträgt 0,44
Epoe: 0 Verlustwert: 1.2423286194012682 LR: 0.2 Genauigkeit beträgt 0,72
Epoe: 0 Verlustwert: 0,7860529560675255 LR: 0,2 Genauigkeit beträgt 0,79
Epoe: 0 Verlustwert: 0,6272194196176664 LR: 0,2 Genauigkeit beträgt 0,87
Epoe: 0 Verlustwert: 0,5240051326725808 LR: 0,2 Genauigkeit beträgt 0,84, 0,84
Epoe: 0 Verlustwert: 0,27637563581928026 LR: 0,2 Genauigkeit beträgt 0,95
Epoe: 0 Verlustwert: 0,35585388987055083 LR: 0,2 Genauigkeit beträgt 0,92
Epoe: 0 Verlustwert: 0,441971528417802 LR: 0,2 Genauigkeit beträgt 0,92
Epoe: 0 Verlustwert: 0,25637710325999674 LR: 0,2 Genauigkeit beträgt 0,95
Epoe: 0 Verlustwert: 0,39872273532502 LR: 0,2 Genauigkeit beträgt 0,9
Epoe: 1 Verlustwert: 0,264085484522027 LR: 0,160000000000000000003 Die Genauigkeit von 0,91 beträgt 0,91
Epoe: 1 Verlustwert: 0,22754066024803088 LR: 0,1600000000000000003 Die Genauigkeit von 0,96 beträgt 0,96
Epoe: 1 Verlustwert: 0,30256420975577103 LR: 0.160000000000000000003 Die Genauigkeit von 0,96 beträgt 0,96
Epoe: 1 Verlustwert: 0,18149648622985948 LR: 0,16000000000000000003 Die Genauigkeit beträgt 0,99.
Epoe: 1 Verlustwert: 0.177239938748327 LR: 0.160000000000000000003 Die Genauigkeit von 0,96 beträgt 0,96
Epoe: 1 Verlustwert: 0.15041993009777443 LR: 0.160000000000000000003 Die Genauigkeit von 0,98 beträgt 0,98
Epoe: 1 Verlustwert: 0.10759545752665524 LR: 0.16000000000000000003 Genauigkeit 1,0 beträgt 1,0
Die Verwendung von Cupcnn
Derzeit implementiert Cupcnn Tests zum MNIST -Datensatz. Nach SRC/Test ist MnistTest der Eingang zur Hauptfunktion, und das spezifische neuronale Netzwerk ist in der MNISTNETWORK -Klasse integriert. In der MNISTNETWORK -Klasse implementieren BuildConvNetwork und BuildFcNetwork jeweils die Konstruktion von Faltungsnetzwerken und den Aufbau vollständig verbundener neuronaler Netze. Dank der guten plattformübergreifenden Eigenschaften von Java verwenden Sie nach dem Herunterladen des Quellcode von Cupcnn Eclipse, um das Projekt zu öffnen und es dann direkt auszuführen.
Aufbau eines neuronalen Netzwerks
public void BuildNetwork () {// Erstellen Sie zuerst das neuronale Netzwerkobjekt und setzen Sie das Parameter network = new network (); Network.SetBatch (100); network.setLoss (new Log -LothoodLosSt ()); //network.setloss(new crosseltropyloss ()); Optimierer = neuer SGDoptimizer (0,2); network.setoptimizer (optimizer); // BuildfcNetwork (); BuildConvnetwork (); network.prepare (); } Die Funktion setBatch () legt fest, wie viele Bilder in einer Stapel enthalten sind.
setloss () legt die zu verwendende Verlustfunktion fest. Cupcnn implementiert die Querentropieverlustfunktion und die Log-Likelihood-Verlustfunktion.
SetOptimizer () sollte verwendet werden, um den Optimierer festzulegen. Cupcnn implementiert nur den SGD -Optimierer. Wenn Sie einen besseren Optimierer implementieren und bereit sind, ihn an Cupcnn zu leisten, möchte ich ihn zutiefst begrüßen.
Bauen Sie ein vollständig verbundenes neuronales Netzwerk auf
private void buildfcNetwork () {// Netzwerkschicht zum Netzwerk inputLayer Layer1 = New InputLayer (Netzwerk, neue BlobParams (network.getbatch (), 1,28,28)); network.addlayer (Layer1); FullConnectionLayer Layer2 = NEU FullConnectionLayer (Netzwerk, neue Blobparams (network.getbatch (), 784,1,1)); Layer2.SetActivationFunc (neue ReluaktivationFunc ()); network.addlayer (Layer2); FullConnectionLayer Layer3 = NEU FullConnectionLayer (Netzwerk, neue Blobparams (network.getbatch (), 100,1,1)); Layer3.SetActivationFunc (neue ReluaktivationFunc ()); network.addlayer (Layer3); FullConnectionLayer Layer4 = NEU FullConnectionLayer (Netzwerk, neue Blobparams (network.getbatch (), 30,1,1)); Layer4.SetActivationFunc (neue SigmodActivationFunc ()); network.addlayer (Layer4); FullConnectionLayer Layer5 = Neue FullConnectionLayer (Netzwerk, neue Blobparams (network.getbatch (), 10,1,1)); Layer5.SetActivationFunc (neue ReluaktivationFunc ()); network.addlayer (Layer5); SoftMaxLayer sflayer = new SoftMaxLayer (Netzwerk, neue Blobparams (network.getbatch (), 10,1,1)); network.addlayer (sflayer); }Wie im obigen Code gezeigt, benötigt jede Ebene ein Netzwerk, das eine Instanz des Netzwerks ist. Das Netzwerk ist der globale Administrator und der Dispatcher von Ressourcen. Mit der Referenz des Netzwerks können wir die Ausgabedaten, Ausgabefehler usw. jeder Ebene problemlos abrufen. Zusätzlich benötigt jede Schicht einen Parameter, der die Größe des Ausgangsdatenblocks der aktuellen Ebene angibt, wodurch einer bestimmten Ebene angegeben ist, wie viel Daten Sie ausgeben müssen. Beispielsweise ist die letzte Schicht eines neuronalen Netzwerks SoftmaxLayer, welche Zahl ausgeben muss. Diese Zahl wird durch einen Vektor mit Länge 10 dargestellt, z. B. die Zahl 7, sodass SoftmaxLayer den Wert des 8. Elements auf 1 und den Wert anderer Elemente auf 0 ausgeben sollte. Die Faltungsschicht und die Pooling -Schicht erfordern mehr Parameter, da beide einen Kernel haben. Für die Faltungsschicht wird sie als Faltungskern als Faltungskern bezeichnet. Der Schritt jeder Richtung der Faltungsschicht beträgt 1, was immer noch Verbesserungsraum ist. Für die Pooling -Schicht müssen Sie zusätzlich zu den Parametern des Pooling -Kerns auch die notwendigen horizontalen und vertikalen Schritte übergeben.
Training und Test
Nach dem Erstellen eines neuronalen Netzwerks müssen Sie die Methode Network.Prepare () aufrufen, mit der Ausgabedatenblöcke und Fehlerdatenblöcke basierend auf den Datenparametern jeder Ebene erstellt werden. Daher ist der Aufruf dieser Methode erforderlich.
public void Train (Liste <Digitimage> Imglist, int epoes) {System.out.println ("Beginn Train"); int batch = network.getBatch (); double loclalr = optimizer.getLr (); für (int e = 0; e <epoes; e ++) {collections.shuffle (Imglist); für (int i = 0; i <imglist.size ()-batch; i+= batch) {list <blob> InputAndLabel = BuildBByImagelist (Imglist, I, Batch, 1,28,28); Double LossValue = Network.Train (inputandLabel.get (0), InputandLabel.get (1)); if (i> batch && i/batch%50 == 0) {System.out.print ("epoe:"+e+"Verlustvalue:"+Verlustvalue+""+"lr:"+optimizer.getL ()+""); Testser (inputAndLabel.get (0), InputandLabel.get (1)); }} if (loclalr> 0,001) {loclalr*= 0,8; optimizer.setlr (localr); }}} public void test (Liste <Digitimage> imglist) {System.out.println ("test"); int batch = network.getBatch (); int korrectCount = 0; int i = 0; für (i = 0; i <imglist.size ()-batch; i+= batch) {list <blob> InputAndLabel = BuildBByImagelist (Imglist, I, Batch, 1,28,28); Blob output = network.PREDICT (inputandLabel.get (0)); int [] caloutlabels = getBatchOutputLabel (outputdata ()); int [] reallabels = getBatchOutputLabel (inputandLabel.get (1) .getData ()); für (int kk = 0; kk <caloutLabels.length; kk ++) {if (caloutLabels [kk] == reallabels [kk]) {correcount ++; }}} Double Accuracy = CorrectCount/(1.0*i+Batch); System.out.println ("Testgenauigkeit ist"+Genauigkeit+"CorrectCount"+CorrectCount); }Wie oben erwähnt, können Sie trainieren, indem Sie den Zug des Netzwerks aufrufen, und Sie können die Vorhersagemethode des Netzwerks testen.
Parameter speichern und laden
public void savemodel (String name) {network.savemodel (name); } public void loLeModel (String -Name) {network = new Network (); Network.loadModel (Name); network.prepare (); }Das Aufrufen von Savemodel und LoadModel des Netzwerks kann jeweils Parameter speichern und laden. Sie müssen nur einen Dateinamen übergeben. Wenn wir über gespeicherte Parameter ein neuronales Netzwerk erstellen, müssen wir das erste neue ein Netzwerk aufrufen, dann das LoadModel dieses Netzwerks aufrufen, um die gespeicherten Parameter zu laden, und vergessen Sie dann nicht, die Methode vorbereiten zu rufen, um Ausgabedatenblöcke und Fehlerdatenblöcke für jede Ebene zu erstellen.
Aktueller Abschlussstatus und zukünftige Pläne
Derzeit umfassen die implementierten Ebenen: vollständige Verbindung, Faltung, maximale Pooling -Schicht, durchschnittliche Pooling -Schicht und Softmax -Schicht. Die implementierten Aktivierungsfunktionen sind: Sigmod, Tanh, Relu.
Die implementierten Verlustfunktionen sind: Cross Entropy, Log-Likelihood. Die implementierte Optimierung ist: SGD. Die Parameter können bereits speichern und laden. Als nächstes wird die Dropout-Schicht hinzugefügt und die Beispiele auf CIFAR-10 werden hinzugefügt.
Darüber hinaus werde ich einige Artikel schreiben, um meine Gedanken und Fragen beim Schreiben von Cupcnn als Referenz durch Anfänger zu überprüfen. Bitte machen Sie einen Umweg. Diejenigen, die interessiert sind, können weiterhin Aufmerksamkeit schenken. Ich hoffe, es wird für das Lernen aller hilfreich sein und ich hoffe, jeder wird Wulin.com mehr unterstützen.