Ich habe ein einfaches NN-Modell zum Erkennen von handgeschriebenen Ziffern aus einem 28x28px-Bild, das in Python mit Keras (Theano-Backend) geschrieben wurde:
model0 = Sequential()
#number of epochs to train for
nb_Epoch = 12
#amount of data each iteration in an Epoch sees
batch_size = 128
model0.add(Flatten(input_shape=(1, img_rows, img_cols)))
model0.add(Dense(nb_classes))
model0.add(Activation('softmax'))
model0.compile(loss='categorical_crossentropy',
optimizer='sgd',
metrics=['accuracy'])
model0.fit(X_train, Y_train, batch_size=batch_size, nb_Epoch=nb_Epoch,
verbose=1, validation_data=(X_test, Y_test))
score = model0.evaluate(X_test, Y_test, verbose=0)
print('Test score:', score[0])
print('Test accuracy:', score[1])
Das läuft gut und ich bekomme ~ 90% Genauigkeit. Ich führe dann den folgenden Befehl aus, um eine Zusammenfassung der Netzwerkstruktur zu erhalten, indem Sie print(model0.summary())
ausführen. Dies gibt Folgendes aus:
Layer (type) Output Shape Param # Connected to
=====================================================================
flatten_1 (Flatten) (None, 784) 0 flatten_input_1[0][0]
dense_1 (Dense) (None, 10) 7850 flatten_1[0][0]
activation_1 (None, 10) 0 dense_1[0][0]
======================================================================
Total params: 7850
Ich verstehe nicht, wie sie zu insgesamt 7850 Params kommen und was das eigentlich bedeutet?
Die Anzahl der Parameter beträgt 7850, da Sie mit jeder verborgenen Einheit 784 Eingabegewichte und eine Verbindungsgewichtung mit Vorspannung haben. Dies bedeutet, dass Sie mit jeder verborgenen Einheit 785 Parameter erhalten. Sie haben 10 Einheiten, also summiert es sich auf 7850.
UPDATE:
Die Rolle dieses zusätzlichen Bias-Begriffs ist sehr wichtig. Es erhöht die Kapazität Ihres Modells erheblich. Sie können Details lesen, z. Hier :
Ich füge eine 514-dimensionale reelle Eingabe in ein Modell Sequential
in Keras ..__ ein. Mein Modell ist folgendermaßen aufgebaut:
predictivemodel = Sequential()
predictivemodel.add(Dense(514, input_dim=514, W_regularizer=WeightRegularizer(l1=0.000001,l2=0.000001), init='normal'))
predictivemodel.add(Dense(257, W_regularizer=WeightRegularizer(l1=0.000001,l2=0.000001), init='normal'))
predictivemodel.compile(loss='mean_squared_error', optimizer='adam', metrics=['accuracy'])
Wenn ich model.summary()
drucke, erhalte ich folgendes Ergebnis:
Layer (type) Output Shape Param # Connected to
================================================================
dense_1 (Dense) (None, 514) 264710 dense_input_1[0][0]
________________________________________________________________
activation_1 (None, 514) 0 dense_1[0][0]
________________________________________________________________
dense_2 (Dense) (None, 257) 132355 activation_1[0][0]
================================================================
Total params: 397065
________________________________________________________________
Für die Schicht "Dichte 1" ist die Anzahl der Parameter 264710 .. _. Dies wird erhalten als: 514 (Eingabewerte) * 514 (Neuronen in der ersten Schicht) + 514 (Bias-Werte)
Für die dichte_2-Schicht ist die Anzahl der Parameter 132355 .. _. Dies wird erhalten als: 514 (Eingabewerte) * 257 (Neuronen in der zweiten Schicht) + 257 (Bias-Werte für Neuronen in der zweiten Schicht)
Das "keine" in der Form bedeutet, dass es keine vordefinierte Nummer hat. Beispielsweise kann es sich um die Stapelgröße handeln, die Sie während des Trainings verwenden, und Sie möchten sie flexibel machen, indem Sie ihr keinen Wert zuweisen, sodass Sie Ihre Stapelgröße ändern können. Das Modell leitet die Form aus dem Kontext der Ebenen ab.
Um Knoten mit jeder Ebene zu verbinden, können Sie Folgendes tun:
for layer in model.layers:
print(layer.name, layer.inbound_nodes, layer.outbound_nodes)
Der einfachste Weg, die Anzahl der Neuronen in einer Schicht zu berechnen, ist: Parameterwert/(Anzahl der Einheiten * 4)
In der Antwort von Paul Lo beträgt die Anzahl der Neuronen in einer Schicht 264710/(514 * 4) = 130
Für dichte Schichten:
output_size * (input_size + 1) == number_parameters
Für Conv-Ebenen:
output_channels * (input_channels * window_size + 1) == number_parameters
Betrachten Sie folgendes Beispiel:
model = Sequential([
Conv2D(32, (3, 3), activation='relu', input_shape=input_shape),
Conv2D(64, (3, 3), activation='relu'),
Conv2D(128, (3, 3), activation='relu'),
Dense(num_classes, activation='softmax')
])
model.summary()
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_1 (Conv2D) (None, 222, 222, 32) 896
_________________________________________________________________
conv2d_2 (Conv2D) (None, 220, 220, 64) 18496
_________________________________________________________________
conv2d_3 (Conv2D) (None, 218, 218, 128) 73856
_________________________________________________________________
dense_9 (Dense) (None, 218, 218, 10) 1290
=================================================================
Berechnung der Parameter,
assert 32 * (3 * (3*3) + 1) == 896
assert 64 * (32 * (3*3) + 1) == 18496
assert 128 * (64 * (3*3) + 1) == 73856
assert num_classes * (128 + 1) == 1290
Anzahl der Parameter ist die Anzahl der Nummern, die im Modell geändert werden können. Mathematisch bedeutet dies die Anzahl der Dimensionen Ihres Optimierungsproblems. Für Sie als Programmierer ist jeder dieser Parameter eine Gleitkommazahl, die in der Regel 4 Byte Speicher benötigt, sodass Sie die Größe dieses Modells nach dem Speichern vorhersagen können.
Diese Formel für diese Zahl ist für jeden neuronalen Netzwerkschichttyp unterschiedlich, aber für die dichte Schicht ist es einfach: Jedes Neuron hat einen Bias-Parameter und eine Gewichtung pro Eingabe: N = n_neurons * ( n_inputs + 1)
.