[PYTHON] Wählen Sie die erforderlichen Variablen in TensorFlow aus und speichern / wiederherstellen

Bei der Aufteilung des Lernprozesses in TensorFlow ist die Variable save / restore erforderlich, die von der Klasse tf.train.Saver in TensorFlow unterstützt wird. Wenn der Maßstab des Modells klein ist, können Sie alle verwendeten Variablen speichern / wiederherstellen. Wenn das Modell jedoch groß ist, möchten Sie nur die Variablen speichern / wiederherstellen, die Sie wirklich benötigen.

In diesem Artikel werden wir die Methode zum Speichern / Wiederherstellen von Variablen am Beispiel der handschriftlichen Nummernklassifizierung MNIST bestätigen. (Die Umgebung ist Python 2.7.11, Tensorflow 0.8.0.)

Fügen Sie trainable = True zu den erforderlichen Variablen hinzu

Abhängig vom Inhalt des Programms gibt es verschiedene mögliche Situationen, was benötigt wird. Am einfachsten ist es, die gesamte verwendete Variable (tf.Variable-Klassenvariable) zu speichern.


chkpt_file = '../MNIST_data/mnist_cnn.ckpt'

# Create the model
def inference(x, y_, keep_prob, phase_train):
(Weggelassen)
Aufbau eines Netzwerkmodells usw.
    
    return loss, accuracy, y_pred

if __name__ == '__main__':
(Weggelassen)
    loss, accuracy, y_pred = inference(x, y_, 
                                         keep_prob, phase_train)
    #                                    
    #Speichern Sie den Vorgang, bevor Sie in die Sitzung eintreten(ops)Wird ohne Argumente definiert
    #
    saver = tf.train.Saver()

    with tf.Session() as sess:
        sess.run(init) 
               
        if restore_call:
            # Restore variables from disk.
            saver.restore(sess, chkpt_file) 

        if TASK == 'train':
            print('\n Training...')
            for i in range(5001):
            
(Lernprozess)
   
        # Save the variables to disk.Zum Schluss auf CD schreiben
        if TASK == 'train':
            save_path = saver.save(sess, chkpt_file)
            print("Model saved in file: %s" % save_path)

Wie oben erwähnt, können Sie Operationen (ops) mit "tf.train.Saver ()" ohne Argumente definieren und die gesamte tf.Variable mit ihrer Speichermethode speichern. (Hinweis. Die in tf.placeholder definierten gelten nicht.)

In den meisten einfachen Modellen neuronaler Netze sind jedoch das ** Gewicht w ** und die ** Vorspannung b ** jeder Einheit ausreichend. Die hier empfohlene Methode besteht darin, das trainierbare Flag in die Variablendefinition einzufügen.

Das Folgende ist eine Klassendefinition der Faltungsschicht und ein Klassenbeispiel der vollständig verbundenen Schicht.

class Convolution2D(object):
    '''
      constructor's args:
          input     : input image (2D matrix)
          input_siz ; input image size
          in_ch     : number of incoming image channel
          out_ch    : number of outgoing image channel
          patch_siz : filter(patch) size
          weights   : (if input) (weights, bias)
    '''
    def __init__(self, input, input_siz, in_ch, out_ch, patch_siz, activation='relu'):
        self.input = input      
        self.rows = input_siz[0]
        self.cols = input_siz[1]
        self.in_ch = in_ch
        self.activation = activation
        
        wshape = [patch_siz[0], patch_siz[1], in_ch, out_ch]
        
        w_cv = tf.Variable(tf.truncated_normal(wshape, stddev=0.1), 
                            trainable=True)
        b_cv = tf.Variable(tf.constant(0.1, shape=[out_ch]), 
                            trainable=True)
        
        self.w = w_cv
        self.b = b_cv
        self.params = [self.w, self.b]
        
(Weggelassen)

# Full-connected Layer   
class FullConnected(object):
    def __init__(self, input, n_in, n_out):
        self.input = input
    
        w_h = tf.Variable(tf.truncated_normal([n_in,n_out],
                          mean=0.0, stddev=0.05), trainable=True)
        b_h = tf.Variable(tf.zeros([n_out]), trainable=True)
     
        self.w = w_h
        self.b = b_h
        self.params = [self.w, self.b]
    
(Weggelassen)

Wenn Sie die Variablen (w_cv, b_cv) und (w_h, b_h) deklarieren, die dem Gewicht und der Abweichung entsprechen, wird "trainable = True" (trainable) hinzugefügt. Mit diesem Aufwand können Sie später nur trainierbare Variablen erfassen.

if __name__ == '__main__':
(Weggelassen)
    vars_to_train = tf.trainable_variables()
    
    if os.path.exists(chkpt_file) == False:
        restore_call = False
        init = tf.initialize_all_variables()

    else:
        restore_call = True
        vars_all = tf.all_variables()
        vars_to_init = list(set(vars_all) - set(vars_to_train))
        init = tf.initialize_variables(vars_to_init)
          
    saver = tf.train.Saver(vars_to_train)

    with tf.Session() as sess:
(Weggelassen)
    

Der Punkt im obigen Code ist Wir haben gerade die mit trainable = True deklarierten Variablen mit ** tf.trainable_variables () ** und die gesamten mit ** tf.all_variables () ** deklarierten Variablen gesammelt. Das Bild des Variablensatzes ist wie folgt.

tf_vars_1.png

Im ersten Prozess werden nur die Variablen mit trainierbar gespeichert, und im zweiten und nachfolgenden Prozess werden diese gespeicherten Variablen wiederhergestellt und verwendet. Der Ablauf besteht jedoch darin, dass Variablen, die nicht gespeichert / wiederhergestellt werden, initialisiert werden (auch nach dem zweiten Mal).

Vergleichen Sie hier die Größe der gespeicherten Dateien.

-rw-rw-r--1 52404005 31. Mai 09:54 mnist_cnn.all_vars
-rw-rw-r--1 13100491 22. Mai 09:15 mnist_cnn.trainable

Dies ist nur ein Beispiel, aber die gespeicherte Datei kann bis zu 1/4 klein sein. (Die obige Datei wurde von mnist_cnn.ckpt umbenannt.)

Sammeln von Variablen mithilfe von Namespaces

Als nächstes werden wir eine andere Methode vorstellen, eine Methode zum Sammeln von Variablen unter Verwendung des Variablennamensraums und zum Speichern / Wiederherstellen. In TensorFlow denke ich, dass zur Visualisierung von Graph (Modellkonfiguration) die Graphkonstruktion beim Definieren eines Namespace fortgesetzt werden kann, aber dieser Namespace kann zum Sammeln der definierten Variablen verwendet werden.

Das folgende Beispiel ist ein Verfahren zum Sammeln der Variablen, die bei der der Faltungsschicht hinzugefügten Chargennormalisierung verwendet werden.

def batch_norm(x, n_out, phase_train):
    with tf.variable_scope('bn'):

(Stapelnormalisierungsverarbeitung, verschiedene)

    return normed
    
#Erstellen Sie das Modellmodellbauteil, Stapel oben_norm()Ruft an
def inference(x, y_, keep_prob, phase_train):
    x_image = tf.reshape(x, [-1, 28, 28, 1])
    
    with tf.variable_scope('conv_1'):
        conv1 = Convolution2D(x, (28, 28), 1, 32, (5, 5), activation='none')
        conv1_bn = batch_norm(conv1.output(), 32, phase_train)
        conv1_out = tf.nn.relu(conv1_bn)
           
        pool1 = MaxPooling2D(conv1_out)
        pool1_out = pool1.output()
    
    with tf.variable_scope('conv_2'):
        conv2 = Convolution2D(pool1_out, (28, 28), 32, 64, (5, 5), 
                                                          activation='none')
        conv2_bn = batch_norm(conv2.output(), 64, phase_train)
        conv2_out = tf.nn.relu(conv2_bn)
           
        pool2 = MaxPooling2D(conv2_out)
        pool2_out = pool2.output()    
        pool2_flat = tf.reshape(pool2_out, [-1, 7*7*64])
    
(Andere Schichten weggelassen)
    
    return loss, accuracy, y_pred
 
#Hauptverarbeitung
if __name__ == '__main__':
    TASK = 'train'    # 'train' or 'test'
    
    # Variables
    x = tf.placeholder(tf.float32, [None, 784])
    y_ = tf.placeholder(tf.float32, [None, 10])
    keep_prob = tf.placeholder(tf.float32)
    phase_train = tf.placeholder(tf.bool, name='phase_train')
    
    loss, accuracy, y_pred = inference(x, y_, 
                                         keep_prob, phase_train)

    # Train
    lr = 0.01
    train_step = tf.train.AdagradOptimizer(lr).minimize(loss)
    vars_to_train = tf.trainable_variables()    # option-1
    vars_for_bn1 = tf.get_collection(tf.GraphKeys.VARIABLES, scope='conv_1/bn')
    vars_for_bn2 = tf.get_collection(tf.GraphKeys.VARIABLES, scope='conv_2/bn')
    vars_to_train = list(set(vars_to_train).union(set(vars_for_bn1)))
    vars_to_train = list(set(vars_to_train).union(set(vars_for_bn2)))
    
    if TASK == 'train':
        restore_call = False
        init = tf.initialize_all_variables()
    elif TASK == 'test':
        restore_call = True
        vars_all = tf.all_variables()
        vars_to_init = list(set(vars_all) - set(vars_to_train))
        init = tf.initialize_variables(vars_to_init)  # option-1
        # init = tf.initialize_all_variables()    option-2
    else:
        print('Check task switch.')
          
    saver = tf.train.Saver(vars_to_train) 

    with tf.Session() as sess:
(Im Folgenden der Inhalt der TensorFlow-Sitzung)

Hier gibt es die Faltungsschicht 1 (conv_1) und die Faltungsschicht 2 (conv_2), und es wird jeweils eine Chargennormalisierung durchgeführt. Die dort verwendeten Variablen werden von ** tf.get_collection () ** wie folgt gesammelt. ing.

vars_for_bn1 = tf.get_collection(tf.GraphKeys.VARIABLES, scope='conv_1/bn')
vars_for_bn2 = tf.get_collection(tf.GraphKeys.VARIABLES, scope='conv_2/bn')

In diesem Beispiel definiert inference () die Namespaces von ** conv_1 ** und ** conv_2 **, und in diesem Beispiel wird batch_norm () mit dem Namespace von ** bn ** aufgerufen. , Die oben genannten (verschachtelten) Namespaces "conv_1 / bn", "conv_2 / bn".

Danach wird der Variablensatz organisiert und in "zu speichernde Dinge" und "nicht zu speichernde Dinge (nach dem nächsten Mal initialisiert)" unterteilt. (Da der Code schwer zu lesen ist, werde ich eine Abbildung anhängen, um Ihnen das Verständnis zu erleichtern.)

tf_vars_2.png

Die erforderlichen Variablen werden gespeichert, indem der farbige Teil in der obigen Abbildung als "vars_to_train" an "tf.train.Saver ()" übergeben wird. Bei der Einführung der Chargennormalisierung "in einer Black Box" trat ein Fehler auf, da die erforderlichen Variablen nicht gespeichert wurden. Mit der oben beschriebenen Methode konnte der Fehler jedoch behoben werden.

Überprüfen Sie abschließend erneut die Dateigröße.

-rw-rw-r--1 52404005 31. Mai 09:54 mnist_cnn.all_vars
-rw-rw-r--1 13105573 31. Mai 10:05 mnist_cnn.ckpt
-rw-rw-r--1 13100491 22. Mai 09:15 mnist_cnn.trainable

Das obere ist der Fall, in dem alle Variablen gespeichert sind, ungefähr 52 MB, das zweite ist der Fall, in dem das obige trainable und der Namespace zusammen verwendet werden, ungefähr 13 MB, und das dritte ist der Fall, in dem nur trainable verwendet wird ( Die Operation enthält Fehler), was ungefähr 13 MB entspricht. Wir glauben, dass das Reduzieren der Dateigröße die Datenträger-E / A-Zeit effektiver reduziert als die Datenträgerverwendung.

(Ich werde den endgültigen Code auf Gist hochladen. Hier ist er.)

Referenzen (Website)

Recommended Posts

Wählen Sie die erforderlichen Variablen in TensorFlow aus und speichern / wiederherstellen
12. Speichern Sie die erste Spalte in col1.txt und die zweite Spalte in col2.txt
Verstehen Sie den TensorFlow-Namespace und die gemeinsam genutzten Mastervariablen
Untersuchen Sie die Beziehung zwischen TensorFlow und Keras in der Übergangszeit
Clipping und Normalisierung in TensorFlow
Legen Sie die erforderlichen Umgebungsvariablen für PySide (Qt4) und PyQt (Qt5) fest.
Durchsuche den pandas.DataFrame mit einer Variablen und erhalte die entsprechende Zeile.
Speichern Sie die Binärdatei in Python
[Python3] Speichern Sie die Mittelwert- und Kovarianzmatrix in json mit Pandas
Suchen Sie den Namen und die Daten einer freien Variablen in einem Funktionsobjekt
Suchen Sie es in der Warteschlange und bearbeiten Sie es
Erstellen Sie eine REST-API mit dem in Lobe und TensorFlow Serving erlernten Modell.
Speichern Sie die angegebene Kanal-ID im Text und laden Sie sie beim nächsten Start
Python-Variablen und Datentypen, die mit Chemoinfomatik gelernt wurden
Unterschied zwischen Variablen und Selbst. Variablen in der [Python] -Klasse
Über den Unterschied zwischen "==" und "is" in Python
Überprüfen von Methoden und Variablen mithilfe der Bibliothek siehe
Wenn sich Achse und Beschriftung in matplotlib überlappen
Schleifen Sie gleichzeitig Variablen in der Vorlage
Greifen Sie über REPL auf die im Skript definierten Variablen zu
Extrahieren Sie die Textinformationen in die MP3 / MP4-Datei und speichern Sie sie in der Textdatei (* .lrc) für Sony Walkman.
Ich möchte die Variablen in der Python-Vorlagendatei ersetzen und in einer anderen Datei in Massenproduktion herstellen