Ein Fahrrad erfinden oder ein Perzeptron in C ++ schreiben. Teil 3
Lassen Sie uns das Training eines mehrschichtigen Perzeptrons in C ++ mithilfe der Backpropagation-Methode implementieren.
Vorwort
Hallo allerseits!) Bevor wir uns mit diesem Artikel befassen, möchte ich noch ein paar Worte zu den vorherigen Teilen sagen. Die von mir vorgeschlagene Implementierung ist eine Verspottung des RAM des Computers, tk. Ein dreidimensionaler Vektor vergewaltigt das Gedächtnis mit einer Fülle leerer Zellen, für die auch das Gedächtnis reserviert ist. Daher ist die Methode alles andere als die beste, aber ich hoffe, sie wird Programmieranfängern in diesem Bereich helfen, zu verstehen, was sich unter der Haube der einfachsten neuronalen Netze befindet. Diesmal. Bei der Beschreibung der Aktivierungsfunktion im ersten Teil habe ich einen Fehler gemacht - die Aktivierungsfunktion muss nicht im Wertebereich eingeschränkt werden. Es hängt alles von den Zielen des Programmierers ab. Die einzige Bedingung ist, dass die Funktion auf der gesamten Zahlenachse definiert werden muss. Es ist zwei
Einführung
-, . backpropagation — . , !
, , , .
:

, , . , , . , , . : (1), j — , , k — , , .. .
, . "O". n6 d6 = (O — y)*( f(in) )*(1 — f(in) ) (2), in —
n6, f(in) — .
(1), . n4 :
d4 = d6 * w46 *( f(in4) ) * (1 — f(in4)), w46 — n4 n6, in4 — n4.
d5 = d6 * w56 *( f(in5) ) * (1 — f(in5)), n5.
d1 = (d4 * w14 + d5 * w15) *( f(in1) ) * (1 — f(in1)), n1, , — .
n2 n3 :
d2 = (d4 * w24 + d5 * w25) *( f(in2) ) * (1 — f(in2))
d3 = (d4 * w34 + d5 * w35) *( f(in3) ) * (1 — f(in3))
, , :
Δw46 = d6 * A * f(in4), w46 — n4 n6 , f(in4) — n4, A — , — , .
Δw56 = d6 * A * f(in5), n5 n6.
:
Δw14 = d4 * A * f(in1)
Δw24 = d4 * A * f(in2)
Δw34 = d4 * A * f(in3)
Δw15 = d4 * A * f(in1)
Δw25 = d4 * A * f(in2)
Δw35 = d4 * A * f(in3)
? . .
void NeuralNet::learnBackpropagation(double* data, double* ans, double acs, double k) { //data - , ans - , k - , acs-
, - :
for (uint32_t e = 0; e < k; e++) {
double* errors = new double[neuronsInLayers[numLayers - 1]]; //
// "Do_it" "Forward"
Forward(neuronsInLayers[0], data);//
getResult(neuronsInLayers[numLayers - 1], errors);//
:
for (uint16_t n = 0; n < neuronsInLayers[numLayers - 1]; n++) {
neurons[n][2][numLayers - 1] = (ans[n] - neurons[n][1][numLayers - 1]) * (neurons[n][1][numLayers - 1]) * (1 - neurons[n][1][numLayers - 1]);
}
, :
for (uint8_t L = numLayers - 2; L > 0; L--) {
for (uint16_t neu = 0; neu < neuronsInLayers[L]; neu++) {
for (uint16_t lastN = 0; lastN < neuronsInLayers[L + 1]; lastN++) {
neurons[neu][2][L] += neurons[lastN][2][L + 1] * weights[neu][lastN][L] * neurons[neu][1][L] * (1 - neurons[neu][1][L]);
weights[neu][lastN][L] += neurons[neu][1][L] * neurons[lastN][2][L + 1] * acs;
}
}
}
:
void NeuralNet::learnBackpropagation(double* data, double* ans, double acs, double k) { //k - acs-
for (uint32_t e = 0; e < k; e++) {
double* errors = new double[neuronsInLayers[numLayers - 1]];
Forward(neuronsInLayers[0], data);
getResult(neuronsInLayers[numLayers - 1], errors);
for (uint16_t n = 0; n < neuronsInLayers[numLayers - 1]; n++) {
neurons[n][2][numLayers - 1] = (ans[n] - neurons[n][1][numLayers - 1]) * (neurons[n][1][numLayers - 1]) * (1 - neurons[n][1][numLayers - 1]);
}
for (uint8_t L = numLayers - 2; L > 0; L--) {
for (uint16_t neu = 0; neu < neuronsInLayers[L]; neu++) {
for (uint16_t lastN = 0; lastN < neuronsInLayers[L + 1]; lastN++) {
neurons[neu][2][L] += neurons[lastN][2][L + 1] * weights[neu][lastN][L] * neurons[neu][1][L] * (1 - neurons[neu][1][L]);
weights[neu][lastN][L] += neurons[neu][1][L] * neurons[lastN][2][L + 1] * acs;
}
}
}
}
}
. :
#include <stdio.h>
#include "neuro.h"
int main()
{
uint16_t neurons[3] = {16, 32, 10}; // , -
/* ""
*/
NeuralNet net(3, neurons);
double teach[4 * 4] = {// "" "4" , - : 4*4 = 16
1,0,1,0,
1,1,1,0,
0,0,1,0,
0,0,1,0,
};
double test[4 * 4] = {// "4", -
1,0,0,1,
1,1,1,1,
0,0,0,1,
0,0,0,1,
};
double ans[10] = {0, 0, 0, 0, 1, 0, 0, 0, 0, 0,};// , "1" , "4"
double output[10] = { 0 };//
net.Forward(4*4, teach); //
net.getResult(10, output);
for (uint8_t i = 0; i < 10; i++) printf("%d: %f \n", i, output[i]*100); //
net.learnBackpropagation(teach, ans, 0.50, 1000); // "test", : 0.5
printf("\n");
net.Forward(4 * 4, test);//
net.getResult(10, output);
for (uint8_t i = 0; i < 10; i++) printf("%d: %f \n", i, output[i]*100);
return 0;
}
:
( ), , 0 9. . , «4»
, , - , . . . , , .
...
. , .
Vielen Dank für die Aufmerksamkeit, die dem Artikel geschenkt wurde, und für die Kommentare zur vorherigen Veröffentlichung. Ich werde den Link zu den Duplikat - Bibliothek - Dateien .
Hinterlassen Sie Ihre Kommentare, Vorschläge. Bis bald!