2017-03-23 3 views
9

Ich möchte einen Weg, um die Präzision der Schwimmer in TensorFlow (ungefähr: die Mantisse zu kürzen) auf eine beliebige Anzahl von Bits innerhalb eines definierten vollen Bereichs zu reduzieren. Ich muss den Code nicht vollständig mit reduzierter Genauigkeit schreiben (wie tf.float16), sondern vielmehr mit einer Reihe von Operationen, die die Genauigkeit eines Tensors reduzieren und dabei den ursprünglichen Typ beibehalten (zB tf.float32).Wie simuliert man in TensorFlow Schwebekörper mit reduzierter Präzision?

Wenn beispielsweise der gesamte Bereich 0 bis 1 ist und die Genauigkeit 8 Bit beträgt, wird 0,1234 rund (0,1234 * 256)/256 = 0,125. Dies verwendet eine einfache Rundung.

Ich würde auch gerne statistische Rundung machen, wo die Wahrscheinlichkeit der Rundung in jeder Richtung proportional dazu ist, wie weit der Wert davon ist. Beispiel: 0,1234 * 256 = 31,5904, was in 59% der Fälle auf 32/256 und in 41% der Fälle auf 31/256 aufrundet.

Zusätzliche Frage: Wie man ein vorhandenes Diagramm nimmt und es ändert, um Rundung nach jeder Faltung hinzuzufügen?

+1

Haben definieren können Sie lesen https://www.tensorflow.org/performance/quantization ? –

+0

@OlivierMoindrot Ja, ich habe mir das angesehen, es scheint ein etwas anderer Anwendungsfall zu sein. Ich brauche eine beliebige Anzahl von Bits, nicht nur 8, und ich möchte nicht jeden OP in einem Graphen konvertieren. –

+0

Okay, das war alles, was ich tun konnte, um Entschuldigung zu helfen! :) –

Antwort

2

Der einzige schwierige Teil besteht darin, die Verläufe für den Rundungsvorgang bereitzustellen. Der bereits implementierte tf.round hat keinen Gradienten implementiert. Aber Sie können Ihre eigene Rundungsoperation (statistische oder einfache Rundung arbeiten beide) implementieren, wie hier gezeigt: Tensorflow: How to write op with gradient in python?

Wo können Sie einfach verwenden:

grad(round(T)) = round(grad(T)) 

Nun, wenn Sie sich ein persönliches round Betrieb haben, die Steigungen über Sie können einfach tun:

def reduce_precision(tensor, precision_bits=8): 
    N = 2**precision_bits 
    return round(N * tensor)/N 

Und für die stochastische Rundung, können Sie eine einfache numpy Funktion wie

erstellen
def stochastic_round(x): 
    r,f = np.modf(x) 
    return r + np.random.binomial(1,r) 

und dann tensoflow-ize es wie in How to make a custom activation function with only Python in Tensorflow?

gezeigt, wo Sie es Steigung Betrieb als

def grad_stochastic_round(op, grad): 
    return stochastic_round(grad) 
+0

Cool! Ich denke in meinem Fall grad (rund (T)) = rund (grad (T)). Irgendwelche Tipps für die statistische Rundung? –

+0

Sie können es mit einer normalen Python/numpy Funktion tun und es in Tensorflow wie hier gezeigt konvertieren: http://stackoverflow.com/questions/39921607/tensorflow-how-to-make-a-custom-activation-function-with -only-python/39921608 # 39921608 –

+1

die Python-Funktion selbst ist sehr einfach, da Sie so etwas tun können wie 'def Runde (x): np.floor (x) + np.random.binomial (1, np.modf (x) [0]) ' –

Verwandte Themen