Dies ist ein Artikel über das Abschneiden jedes Werts, der von einem von TensorFlow behandelten Tensor gehalten wird. Insbesondere wird es ein Erklärungs- und Implementierungsbeispiel für die Systemmethoden "tf.clip_by ..." sein.
Ich denke, es gibt verschiedene Verwendungszwecke, aber bei Berechnungen im Zusammenhang mit maschinellem Lernen (insbesondere Gradientenberechnung), die der Hauptzweck von TensorFlow sind, gibt es viele Fälle, in denen das Skalengefühl der zu behandelnden Variablen unterschiedlich ist und es nicht möglich ist, gut zu berechnen. In solchen Fällen werden Clipping und Normalisierung verwendet.
In TensorFlow wird die herkömmliche Verarbeitung, die Variablen, Konstanten und verschiedene Operationen darstellt, als Op-Knoten bezeichnet (Referenzartikel). Durch Ausführen (Ausführen) in der Sitzung enthält der Op-Knoten eine Menge (Tensor) des Werts des Operationsergebnisses und überträgt ihn an den nächsten Op-Knoten. In diesem Artikel wird der numerische Satz nach Abschluss einer Verarbeitung als ** Knoten ** bezeichnet.
Bild der Unterdrückung des Werts eines Knotens, wenn dieser die Bedingungen für einen festen Standard erfüllt
tf.clip_by_value
tf.clip_by_value(
t,
clip_value_min,
clip_value_max,
name=None
)
Ändern Sie für jeden vom Knoten gehaltenen Wert den Wert, der größer als der Maximalwert "clip_value_max" ist, in "clip_value_max" und den Wert, der kleiner als der Minimalwert "clip_value_min" ist, in "clip_value_min".
example1.py
p1 = tf.placeholder(tf.int32, 6, name='p1')
p2 = tf.placeholder(tf.float32, 6, name='p2')
clip_value1 = tf.clip_by_value(p1, clip_value_max=2, clip_value_min=-2, name='clip_value1')
clip_value2 = tf.clip_by_value(p2, clip_value_max=2., clip_value_min=-2., name='clip_value2')
num1 = np.linspace(-4, 6, 6)
with tf.Session() as sess:
print(p1.eval(feed_dict={p1: num1}, session=sess))
print(p2.eval(feed_dict={p2: num1}, session=sess))
print(clip_value1.eval(feed_dict={p1: num1}, session=sess))
print(clip_value2.eval(feed_dict={p2: num1}, session=sess))
console
[-4 -2 0 2 4 6]
[-4. -2. 0. 2. 4. 6.]
[-2 -2 0 2 2 2]
[-2. -2. 0. 2. 2. 2.]
** Sie erhalten eine Fehlermeldung, wenn die Typen node und clip_value nicht übereinstimmen. ** ** **
example1.py
print(clip_error1.eval(feed_dict={p1: num1}, session=sess))
console
TypeError: Expected int32 passed to parameter 'y' of op 'Minimum', got 2.0 of type 'float' instead.
tf.clip_by_norm
tf.clip_by_norm(
t,
clip_norm,
axes=None,
name=None
)
Wenn die L2-Norm des Knotens größer als "clip_norm" ist, ändern Sie jeden Wert, um ihn in diese Norm zu ändern. Wenn es kleiner als clip_norm
ist, wird es nicht geändert.
example2.py
p3 = tf.placeholder(tf.float32, [2, 3], name='p3')
clip_norm1 = tf.clip_by_norm(p3, clip_norm=4, name='clip_norm1')
clip_norm2 = tf.clip_by_norm(p3, clip_norm=5, name='clip_norm2')
num2 = np.linspace(-2, 3, 6).reshape((2, 3))
with tf.Session() as sess:
print(p3.eval(feed_dict={p3: num2}, session=sess))
print(clip_norm1.eval(feed_dict={p3: num2}, session=sess))
print(clip_norm2.eval(feed_dict={p3: num2}, session=sess))
console
[[-2. -1. 0.]
[ 1. 2. 3.]] #Die gesamte L2-Norm beträgt 4.358 ...
[[-1.8353258 -0.9176629 0. ]
[ 0.9176629 1.8353258 2.7529888]]
[[-2. -1. 0.]
[ 1. 2. 3.]]
Sie können Achsen in tf.clip_by_norm
angeben.
Normalisiert den Wert mit der L2-Norm für jede durch Achsen angegebene Achse.
example3.py
clip_norm3 = tf.clip_by_norm(p3, clip_norm=3, axes=1, name='clip_norm3')
with tf.Session() as sess:
print(p3.eval(feed_dict={p3: num2}, session=sess))
print(clip_norm3.eval(feed_dict={p3: num2}, session=sess))
console
[[-2. -1. 0.] #Die L2-Norm in Spalte 0 ist 2.236 ...
[ 1. 2. 3.]] #Die L2-Norm in der ersten Reihe ist 3.741 ...
[[-2. -1. 0. ]
[ 0.8017837 1.6035674 2.4053512]]
Außerdem verursacht "tf.clip_by_norm" einen TypeError, wenn der zu beißende Knoten den Dezimalpunkt nicht verarbeiten kann. Bitte verwenden Sie den Typ float ◯◯ oder complex ◯◯.
tf.clip_by_global_norm
tf.clip_by_global_norm(
t_list,
clip_norm,
use_norm=None,
name=None
)
Im Gegensatz zu tf.clip_by_norm wird ** eine Liste von Knoten ** anstelle von Knoten übergeben. Wenn Sie den Knoten selbst übergeben, erhalten Sie einen TypeError.
Die L2-Norm des gesamten in der Liste gespeicherten Knotens sei "global_norm". Wenn dieser Wert größer als "clip_norm" ist, ändern Sie alle Werte in der Liste so, dass die L2-Norm "clip_norm" lautet. Wenn es kleiner als clip_norm
ist, wird es nicht geändert.
Außerdem gibt es zwei Rückgabewerte: eine Liste mit ** Knoten nach dem Abschneiden ** list_clipped
und eine berechnete global_norm
.
example4.py
c1 = tf.constant([[0, 1, 2], [3, 4, 5]], dtype=tf.float32, name='c1')
c2 = tf.constant([[-2, -4], [2, 4]], dtype=tf.float32, name='c2')
C = [c1, c2]
clip_global_norm, global_norm = tf.clip_by_global_norm(C, clip_norm=9, name='clip_global_norm')
with tf.Session() as sess:
for c in C:
print(c.eval(session=sess))
print(global_norm.eval(session=sess))
for cgn in clip_global_norm1:
print(cgn.eval(session=sess))
console
[[0. 1. 2.]
[3. 4. 5.]]
[[-2. -4.]
[ 2. 4.]]
9.746795
[[0. 0.9233805 1.846761 ]
[2.7701416 3.693522 4.6169024]]
[[-1.846761 -3.693522]
[ 1.846761 3.693522]]
Die Methoden "tf.clip_by_norm" und "tf.clip_by_global_norm" selbst sind einfach, können jedoch beispielsweise verwendet werden, um Gradientenexplosions-Gegenmaßnahmen "Gradientenbeschneidung" in RNNs anzugehen.
Folgendes wird hilfreich sein.
- Pascanu et al., (2012), On the difficulty of training Recurrent Neural Networks (pdf)
- [Grundlegendes zum LSTM-Clipping-Gradienten-Cliping mit #rnn und Gradienten mit aktuellen Trends](https://qiita.com/t_Signull/items/21b82be280b46f467d1b#rnn%E3%81%A8%E5%8B%BE%E9 % 85% 8D% E3% 81% AE% E3% 82% AF% E3% 83% AA% E3% 83% 83% E3% 83% 94% E3% 83% B3% E3% 82% B0 Gradienten-Cliping)
Wenn Sie das Modell nach dem Erstellen trainieren möchten, können Sie es möglicherweise mit dieser Methode lösen, wenn Sie durch Berechnung der Fehlerausbreitung usw. zu inf springen.
Durch das Abschneiden wurde der Besitzwert des Knotens tatsächlich geändert, es ist jedoch auch möglich, nur die Norm zu berechnen.
tf.norm
tf.norm(
tensor,
ord='euclidean',
axis=None,
keepdims=None,
name=None
)
Der Parameter ord
bestimmt den Wert von p in der Lp-Norm.
Geben Sie für die L∞-Norm np.inf an.
example4.py
p4 = tf.placeholder(tf.float32, [3, 4], name='p4')
normalize1 = tf.norm(p4, name='normalize1')
normalize2 = tf.norm(p4, ord=1.5, axis=0, name='normalize2')
normalize3 = tf.norm(p4, ord=np.inf, axis=1, name='normalize3')
num3 = np.linspace(-10, 8, 12).reshape((3, 4))
with tf.Session() as sess:
print(p4.eval(feed_dict={p4: num3}, session=sess))
print(normalize1.eval(feed_dict={p4: num3}, session=sess))
print(normalize2.eval(feed_dict={p4: num3}, session=sess))
print(normalize3.eval(feed_dict={p4: num3}, session=sess))
console
[[-10. -8.363636 -6.7272725 -5.090909 ]
[ -3.4545455 -1.8181819 -0.18181819 1.4545455 ]
[ 3.090909 4.7272725 6.3636365 8. ]]
19.87232
[12.364525 11.0871725 10.408293 10.876119 ]
[10. 3.4545455 8. ]
TensorFlow > API > TensorFlow Core r2.0 > Python > tf.cilp_by_value TensorFlow > API > TensorFlow Core r2.0 > Python > tf.clip_by_norm TensorFlow > API > TensorFlow Core r2.0 > Python > tf.clip_by_global_norm TensorFlow > API > TensorFlow Core r2.0 > Python > tf.norm
Morgen ist "Hacken des Reservierungssystems mit Ruby" von @yoshishin. Bitte genießen Sie weiterhin GMO Ad Marketing Adventskalender 2019!
Recommended Posts