2016-05-05 14 views
6

Ich weiß, dass diese Frage in verschiedenen Formen gestellt wurde, aber ich kann wirklich keine Antwort finden, die ich verstehen und verwenden kann. Also verzeiht mir, wenn dies eine grundlegende Frage ist, denn ich ein Neuling auf diese Tools bin (Theano/keras)Wie kann man Tensor-Werte in Theano/Keras überwachen?

Problem zu lösen

Monitor-Variablen in Neuronale Netze (zB Eingabe/vergessen/Ausgangs-Gate-Werte in LSTM)

Was ich zur Zeit immer

egal in welchem ​​Stadium ich diese Werte immer, ich bin immer so etwas wie:

Elemwise{mul,no_inplace}.0 
Elemwise{mul,no_inplace}.0 
[for{cpu,scan_fn}.2, Subtensor{int64::}.0, Subtensor{int64::}.0] 
[for{cpu,scan_fn}.2, Subtensor{int64::}.0, Subtensor{int64::}.0] 
Subtensor{int64}.0 
Subtensor{int64}.0 

Gibt es eine Möglichkeit, die ich nicht überwachen kann (z. B. auf stdout drucken, in eine Datei schreiben usw.)?

Mögliche Lösung

Scheint, wie Rückrufe in Keras kann die Arbeit erledigen, aber es funktioniert auch nicht für mich. Ich bin immer gleiche wie oben

Meine Vermutung

Scheint, wie ich bin sehr einfach, Fehler zu machen.

Vielen Dank im Voraus, alle.


ADDED

Insbesondere, ich versuche Eingang zu überwachen/vergessen/Ausgabe-Gating-Werte in LSTM. fand ich, dass LSTM.step() ist diesen Wert zur Berechnung:

def step(self, x, states): 
    h_tm1 = states[0] # hidden state of the previous time step 
    c_tm1 = states[1] # cell state from the previous time step 
    B_U = states[2]  # dropout matrices for recurrent units? 
    B_W = states[3]  # dropout matrices for input units? 

    if self.consume_less == 'cpu':        # just cut x into 4 pieces in columns 
     x_i = x[:, :self.output_dim] 
     x_f = x[:, self.output_dim: 2 * self.output_dim] 
     x_c = x[:, 2 * self.output_dim: 3 * self.output_dim] 
     x_o = x[:, 3 * self.output_dim:] 
    else: 
     x_i = K.dot(x * B_W[0], self.W_i) + self.b_i 
     x_f = K.dot(x * B_W[1], self.W_f) + self.b_f 
     x_c = K.dot(x * B_W[2], self.W_c) + self.b_c 
     x_o = K.dot(x * B_W[3], self.W_o) + self.b_o 

    i = self.inner_activation(x_i + K.dot(h_tm1 * B_U[0], self.U_i)) 
    f = self.inner_activation(x_f + K.dot(h_tm1 * B_U[1], self.U_f)) 
    c = f * c_tm1 + i * self.activation(x_c + K.dot(h_tm1 * B_U[2], self.U_c)) 
    o = self.inner_activation(x_o + K.dot(h_tm1 * B_U[3], self.U_o)) 

    with open("test_visualization.txt", "a") as myfile: 
     myfile.write(str(i)+"\n") 

    h = o * self.activation(c) 
    return h, [h, c] 

Und wie es oben im Code ist, habe ich versucht, den Wert von i in eine Datei zu schreiben, aber es gab nur Werte mich wie: So

Elemwise{mul,no_inplace}.0 
[for{cpu,scan_fn}.2, Subtensor{int64::}.0, Subtensor{int64::}.0] 
Subtensor{int64}.0 

ich versuchte i.eval() oder i.get_value(), aber beide scheiterten mir Wert zu geben.

.eval() gab mir dies:

theano.gof.fg.MissingInputError: An input of the graph, used to compute Subtensor{::, :int64:}(<TensorType(float32, matrix)>, Constant{10}), was not provided and not given a value.Use the Theano flag exception_verbosity='high',for more information on this error. 

und .get_value() gab mir dies:

AttributeError: 'TensorVariable' object has no attribute 'get_value' 

So Rückzieher ich diese Ketten (die Linie nennt, welche Funktionen ..) und Ich versuchte bei jedem Schritt Werte zu finden, aber vergeblich.

Fühlt sich an, als ob ich in einigen grundlegenden Fallstricke bin.

+0

Wie erhalten Sie die Werte? Fügen Sie Ihren Code ein, anscheinend drucken Sie die symbolischen Variablen und nicht ihre Werte. –

+0

Vielen Dank für Ihre schnelle Antwort @MatiasValdenegro. Ich habe meine Frage oben mit Codes und Fehlermeldungen aktualisiert. – totuta

Antwort

1

Ich benutze die Lösung in der Keras FAQ beschrieben:

http://keras.io/getting-started/faq/#how-can-i-visualize-the-output-of-an-intermediate-layer

Im Detail:

from keras import backend as K 

intermediate_tensor_function = K.function([model.layers[0].input],[model.layers[layer_of_interest].output]) 
intermediate_tensor = intermediate_tensor_function([thisInput])[0] 

ergibt:

array([[ 3., 17.]], dtype=float32) 

Allerdings würde Ich mag die verwenden Funktionale API, aber ich kann nicht den tatsächlichen Tensor, nur das symbolische Repräsentat erhalten Ion. Zum Beispiel:

model.layers[1].output 

ergibt:

<tf.Tensor 'add:0' shape=(?, 2) dtype=float32> 

fehlt mir etwas über die Interaktion von Keras und Tensorflow hier, aber ich bin mir nicht sicher, was. Jeder Einblick sehr geschätzt.

1

Eine Lösung besteht darin, eine Version Ihres Netzwerks zu erstellen, die auf der LSTM-Ebene abgeschnitten wird, deren Gatterwerte überwacht werden sollen. Anschließend wird die ursprüngliche Ebene durch eine benutzerdefinierte Ebene ersetzt, in der die Schrittfunktion nicht zurückgegeben wird nur die Werte der versteckten Ebene, aber auch die Gate-Werte.

Zum Beispiel sagen Sie, dass Sie Zugriff auf die Gate-Werte einer GRU zugreifen möchten. Erstellen Sie ein benutzerdefiniertes Layer GRU2, das alles von der GRU-Klasse erbt, aber die Schrittfunktion so anpasst, dass es eine Verkettung der zu überwachenden Zustände zurückgibt und dann nur den Teil mit den vorherigen Aktivierungen der ausgeblendeten Ebenen übernimmt, wenn die nächsten Aktivierungen berechnet werden. Ie:

def step(self, x, states): 

    # get prev hidden layer from input that is concatenation of 
    # prev hidden layer + reset gate + update gate 
    x = x[:self.output_dim, :] 


    ############################################### 
    # This is the original code from the GRU layer 
    # 

    h_tm1 = states[0] # previous memory 
    B_U = states[1] # dropout matrices for recurrent units 
    B_W = states[2] 

    if self.consume_less == 'gpu': 

     matrix_x = K.dot(x * B_W[0], self.W) + self.b 
     matrix_inner = K.dot(h_tm1 * B_U[0], self.U[:, :2 * self.output_dim]) 

     x_z = matrix_x[:, :self.output_dim] 
     x_r = matrix_x[:, self.output_dim: 2 * self.output_dim] 
     inner_z = matrix_inner[:, :self.output_dim] 
     inner_r = matrix_inner[:, self.output_dim: 2 * self.output_dim] 

     z = self.inner_activation(x_z + inner_z) 
     r = self.inner_activation(x_r + inner_r) 

     x_h = matrix_x[:, 2 * self.output_dim:] 
     inner_h = K.dot(r * h_tm1 * B_U[0], self.U[:, 2 * self.output_dim:]) 
     hh = self.activation(x_h + inner_h) 
    else: 
     if self.consume_less == 'cpu': 
      x_z = x[:, :self.output_dim] 
      x_r = x[:, self.output_dim: 2 * self.output_dim] 
      x_h = x[:, 2 * self.output_dim:] 
     elif self.consume_less == 'mem': 
      x_z = K.dot(x * B_W[0], self.W_z) + self.b_z 
      x_r = K.dot(x * B_W[1], self.W_r) + self.b_r 
      x_h = K.dot(x * B_W[2], self.W_h) + self.b_h 
     else: 
      raise Exception('Unknown `consume_less` mode.') 
     z = self.inner_activation(x_z + K.dot(h_tm1 * B_U[0], self.U_z)) 
     r = self.inner_activation(x_r + K.dot(h_tm1 * B_U[1], self.U_r)) 

     hh = self.activation(x_h + K.dot(r * h_tm1 * B_U[2], self.U_h)) 
    h = z * h_tm1 + (1 - z) * hh 

    # 
    # End of original code 
    ########################################################### 


    # concatenate states you want to monitor, in this case the 
    # hidden layer activations and gates z and r 
    all = K.concatenate([h, z, r]) 

    # return everything 
    return all, [h] 

(Beachten Sie, dass die einzigen Zeilen, die ich hinzugefügt habe, am Anfang und am Ende der Funktion stehen).

Wenn Sie dann Ihr Netzwerk mit GRU2 als letzte Ebene anstelle von GRU ausführen (mit return_sequences = True für die GRU2-Ebene), können Sie einfach in Ihrem Netzwerk voraussagen, dies gibt Ihnen alle versteckten Layer- und Gate-Werte.

Das gleiche sollte für LSTM funktionieren, obwohl Sie möglicherweise ein wenig rätseln müssen, um herauszufinden, wie Sie alle gewünschten Ausgaben in einem Vektor speichern und danach wieder abrufen können.

Hoffe, dass hilft!

0

können Sie Theano die Verwendung printing Modul während der Ausführung für den Druck (und nicht bei der Definition, was ist das, was Sie tun, und der Grund, warum Sie nicht Werte bekommen, aber ihre abstrakte Definition).

Drucken

Verwenden Sie einfach die Print Funktion. Vergessen Sie nicht, die Ausgabe Print zu verwenden, um Ihr Diagramm fortzusetzen, andernfalls wird die Ausgabe getrennt und Print wird höchstwahrscheinlich während der Optimierung entfernt. Und du wirst nichts sehen.

from keras import backend as K 
from theano.printing import Print 

def someLossFunction(x, ref): 
    loss = K.square(x - ref) 
    loss = Print('Loss tensor (before sum)')(loss) 
    loss = K.sum(loss) 
    loss = Print('Loss scalar (after sum)')(loss) 
    return loss 

Plot

Ein kleiner Bonus, den Sie genießen können.

Die Print-Klasse verfügt über einen global_fn-Parameter, um den Standard-Callback zum Drucken zu überschreiben. Sie können Ihre eigene Funktion bereitstellen und direkt auf die Daten zugreifen, um beispielsweise ein Diagramm zu erstellen.

from keras import backend as K 
from theano.printing import Print 
import matplotlib.pyplot as plt 

curve = [] 

# the callback function 
def myPlottingFn(printObj, data): 
    global curve 
    # Store scalar data 
    curve.append(data) 

    # Plot it 
    fig, ax = plt.subplots() 
    ax.plot(curve, label=printObj.message) 
    ax.legend(loc='best') 
    plt.show() 

def someLossFunction(x, ref): 
    loss = K.sum(K.square(x - ref)) 
    # Callback is defined line below 
    loss = Print('Loss scalar (after sum)', global_fn=myplottingFn)(loss) 
    return loss 

BTW die Zeichenfolge, die Sie übergeben Drucken ('...') in dem Druckobjekt unter Eigenschaftsnamen gespeichert message (siehe Funktion myPlottingFn). Dies ist nützlich für die Erstellung von Multi-Kurven-Plot automatisch

Verwandte Themen