2017-07-06 2 views
0

Ich arbeite mit keras zum ersten Mal und versuche, eine benutzerdefinierte keras.callbacks.Callback zu schreiben, die die Gewichte jeder Modellschicht während fit speichert. Ich habe Probleme beim Umwandeln des Typs keras.models.layers.weights in ein numpy Array (oder irgendetwas, aus dem ich den primitiven Typ Wert extrahieren kann).Speichern von Schichtgewichten in jeder Epoche während des Trainings in einem numpigen Typ/Array? TensorFlow Variable in numpy Array konvertieren?

Von dem, was ich sagen kann keras.models.layers.weights (für mein Modell) ist eine Liste von tensorflow.python.ops.variables.Variable, die entweder eine (1, 1) Matrix oder (1,) Matrix halten. Ich kann diesen variablen Typ einfach nicht als float (dtype der Matrizen) bekommen.

Hier ist ein SSCCE meines Problems.

import keras 
import numpy as np 

xONE = np.mat([[0], [1]]) 
yNOT = np.mat([[1], [0]]) 

# Simple Keras callback which saves not only loss and acc 
# but also the layer weights at each epoch end 
class History_LAW(keras.callbacks.Callback): 
    def on_train_begin(self, logs={}): 
     self.epoch = [] 
     self.weights = [] 
     self.history = {} 
     self.weights.append(self.model.weights) 

    def on_epoch_end(self, epoch, logs={}): 
     logs = logs or {} 
     self.epoch.append(epoch) 
     self.weights.append(self.model.weights) 
     for k, v in logs.items(): 
      self.history.setdefault(k, []).append(v) 

# Used to programmatically generaly a simple model 
# given the data that it is meant to fit to 
def generateModel(xShape, yShape): 
    model = keras.models.Sequential() 
    model.add(
     keras.layers.Dense(
      yShape[1], input_shape = (xShape[1],))) 
    model.add(keras.layers.Activation('hard_sigmoid')) 
    model.summary() 
    return model 

# Generate a model based on the simply NOT relationship 
model = generateModel(xONE.shape, yNOT.shape) 
model.compile(
    optimizer = 'adam', 
    loss = 'binary_crossentropy', 
    metrics = ['accuracy']) 

# Create the custom callback and pass it to fit 
model_Hist = History_LAW() 
model.fit(xONE, yNOT, 
    epochs = 4, batch_size = 2, verbose = 1, callbacks = [model_Hist]) 

# Display the raw weight structure and its type 
print('========== Raw w output') 
for weight in model_Hist.weights: 
    print([w for w in weight]) 

print('========== Type of w') 
for weight in model_Hist.weights: 
    print([type(w) for w in weight]) 

habe ich diese SO answer finden, die eval() verwenden will (ich glaube, eine TensorFlow Funktion) auf „evalute“ die Tensoren (nicht ganz sicher, was das bedeutet noch nicht, aber ich denke, das ist die richtige Terminologie) in ihren zugrunde liegenden Typen - Ich nehme an, ist eine numpy Matrix oder Array. Obwohl dies zu folgen scheint, führt dies zu einem weiteren Kaninchenloch von Fehlern (die session = tf.InteractiveSession) an eval übergeben wird, was dazu führt, dass "das Diagramm des Tensors sich vom Diagramm der Sitzung unterscheidet").

Ich habe various callbacks gefunden, die Schichtgewichte während der Montage aufzeichnen kann, obwohl ich nichts davon sagen kann, geben sie sie im gewünschten Format zurück.

Wie kann ich diese Gewichte in einige numpy Objekt konvertieren? Gibt es einen anderen Weg als den, den ich im SSCCE vorschlage, um das zu erreichen, was ich will?


Als Referenz der Ausgang des SSCCE oben ist:

========== Raw w output 
[<tf.Variable 'dense_1/kernel:0' shape=(1, 1) dtype=float32_ref>, <tf.Variable 'dense_1/bias:0' shape=(1,) dtype=float32_ref>] 
[<tf.Variable 'dense_1/kernel:0' shape=(1, 1) dtype=float32_ref>, <tf.Variable 'dense_1/bias:0' shape=(1,) dtype=float32_ref>] 
[<tf.Variable 'dense_1/kernel:0' shape=(1, 1) dtype=float32_ref>, <tf.Variable 'dense_1/bias:0' shape=(1,) dtype=float32_ref>] 
[<tf.Variable 'dense_1/kernel:0' shape=(1, 1) dtype=float32_ref>, <tf.Variable 'dense_1/bias:0' shape=(1,) dtype=float32_ref>] 
[<tf.Variable 'dense_1/kernel:0' shape=(1, 1) dtype=float32_ref>, <tf.Variable 'dense_1/bias:0' shape=(1,) dtype=float32_ref>] 
========== Type of w 
[<class 'tensorflow.python.ops.variables.Variable'>, <class 'tensorflow.python.ops.variables.Variable'>] 
[<class 'tensorflow.python.ops.variables.Variable'>, <class 'tensorflow.python.ops.variables.Variable'>] 
[<class 'tensorflow.python.ops.variables.Variable'>, <class 'tensorflow.python.ops.variables.Variable'>] 
[<class 'tensorflow.python.ops.variables.Variable'>, <class 'tensorflow.python.ops.variables.Variable'>] 
[<class 'tensorflow.python.ops.variables.Variable'>, <class 'tensorflow.python.ops.variables.Variable'>] 

Antwort

0

Ich habe festgestellt, dass ich keras.model.layer.get_weights() die Methode verwenden, um die Gewichte als numpy Arrays zu erhalten.

Zum Beispiel mein Rückruf wie

def on_epoch_end(self, epoch, logs={}): 
    logs = logs or {} 
    self.epoch.append(epoch) 
    for k, v in logs.items(): 
     self.history.setdefault(k, []).append(v) 

    modelWeights = [] 
    for layer in model.layers: 
     layerWeights = [] 
     for weight in layer.get_weights(): 
      layerWeights.append(weight) 
     modelWeights.append(layerWeights) 
    self.weights.append(modelWeights) 
etwas ändern würde
Verwandte Themen