2017-11-15 5 views
1

Beim Training konvolutioneller neuronaler Netzwerke für Bildklassifizierungsaufgaben möchten wir im Allgemeinen unseren Algorithmus die Filter (und Verzerrungen) lernen, die ein gegebenes Bild in die richtige Bezeichnung transformieren. Ich habe ein paar Modelle, die ich in Bezug auf Modellgröße, Anzahl der Operationen, Genauigkeit usw. vergleichen möchte. Allerdings ist die Größe des Modells aus Tensorflow, konkret die model.ckpt.data Datei, die die Werte speichert outputed von allen Variablen in der Grafik, ist nicht die eine, die ich erwartet habe. Tatsächlich scheint es dreimal so groß zu sein.Erwartete Tensorflow-Modellgröße aus erlernten Variablen

Um direkt auf das Problem zu gehen werde ich meine Frage auf this Jupyter Notebook basieren. Im Folgenden ist der Abschnitt, in dem die Variablen (Gewichtungen und Bias) definiert sind:

# Store layers weight & bias 
weights = { 
# 5x5 conv, 1 input, 32 outputs 
'wc1': tf.Variable(tf.random_normal([5, 5, 1, 32]),dtype=tf.float32), 
# 5x5 conv, 32 inputs, 64 outputs 
'wc2': tf.Variable(tf.random_normal([5, 5, 32, 64]),dtype=tf.float32), 
# fully connected, 7*7*64 inputs, 1024 outputs 
'wd1': tf.Variable(tf.random_normal([7*7*64, 1024]),dtype=tf.float32), 
# 1024 inputs, 10 outputs (class prediction) 
'out': tf.Variable(tf.random_normal([1024, num_classes]),dtype=tf.float32) 
} 

biases = { 
'bc1': tf.Variable(tf.random_normal([32]),dtype=tf.float32), 
'bc2': tf.Variable(tf.random_normal([64]),dtype=tf.float32), 
'bd1': tf.Variable(tf.random_normal([1024]),dtype=tf.float32), 
'out': tf.Variable(tf.random_normal([num_classes]),dtype=tf.float32) 
} 

ich ein paar Zeilen, um hinzugefügt habe das Modell am Ende des Trainingsprozesses zu speichern:

# Save the model 
save_path = saver.save(sess, logdir+"model.ckpt") 
print("Model saved in file: %s" % save_path) 

Addieren Sie alle diese Variablen, die wir erwarten würden, eine model.ckpt.data Datei der Größe 12.45Mb (Ich habe dies durch nur die Anzahl der Float-Elemente, die unser Modell lernt berechnet und dann konvertieren Sie diesen Wert in MegaBytes erhalten) . Aber! die .data gespeicherte datei ist 39.3Mb. Warum ist das?

ich den gleichen Ansatz mit einem komplexeren Netzwerk verfolgt hat (eine Variation von RESNET) und meine erwarteten model.data Größe ist auch ~ 3x kleiner als das, was die tatsächliche .data Datei.

Der Datentyp all dieser Variablen ist float32.

Antwort

1

Addiert man all diese Variablen würden wir erwarten, eine model.ckpt.data Datei Größe

12.45Mb

Kultur zu bekommen, sind die meisten Modellparameter in der ersten vollständig verbundenen Schicht, in diesem Fall wd1. Computing nur seine Größe ergibt:

7*7*128 * 1024 * 4 = 25690112 

... oder 25.6Mb. Hinweis 4 Koeffizient, weil die Variable dtype=tf.float32, d. H. 4 Bytes pro Parameter. Andere Schichten tragen ebenfalls zur Modellgröße bei, aber nicht so drastisch.

Wie Sie sehen können, ist Ihre Schätzung 12.45Mbein bisschen aus (haben Sie 16bit pro param verwendet?). Der Checkpoint speichert auch einige allgemeine Informationen, daher der Overhead um 25%, der immer noch groß ist, aber nicht 300%.

[Update]

Das Modell in Frage hat eigentlich FC1 Schicht Form [7*7*64, 1024], wie geklärt. Die oben berechnete Größe sollte also 12.5Mb sein. Das brachte mich dazu, genauer in den gespeicherten Checkpoint zu schauen.

Nachdem sie die Kontrolle, bemerkte ich andere große Variablen, die ich ursprünglich verpasst:

... 
Variable_2 (DT_FLOAT) [3136,1024] 
Variable_2/Adam (DT_FLOAT) [3136,1024] 
Variable_2/Adam_1 (DT_FLOAT) [3136,1024] 
... 

Die Variable_2 ist genau wd1, aber es gibt 2 weitere Kopien für den Adam-Optimierer. Diese Variablen werden von the Adam optimizer erstellt, sie heißen Steckplätze und halten die m und v Akkus für alle trainierbaren Variablen. Jetzt macht die Gesamtgröße Sinn.

Sie können den folgenden Code ausführen, um die Gesamtgröße der Graph Variablen zu berechnen - 37.47Mb:

var_sizes = [np.product(list(map(int, v.shape))) * v.dtype.size 
      for v in tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES)] 
print(sum(var_sizes)/(1024 ** 2), 'MB') 

So ist der Overhead eigentlich ziemlich klein ist. Die zusätzliche Größe ist auf den Optimierer zurückzuführen.

+0

oh! Danke. Nein, ich benutze 32bit, aber ich habe "7 * 7 * 64 * 1024 * 4". Mein Fehler. – karl71

+0

Ich habe meine Nummern aktualisiert (siehe Edit 1). Ich habe immer noch das Problem in meiner Frage beschrieben. – karl71

+1

@ karl71 Sind Sie sicher, dass Sie das gleiche Modell gespeichert haben? Ich habe gerade 39Mb, wie Sie ursprünglich beschrieben – Maxim