In [ ]:
#@title Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
Note: La nostra comunità di Tensorflow ha tradotto questi documenti. Poichè questa traduzioni della comunità sono best-effort, non c'è garanzia che questa sia un riflesso preciso e aggiornato della documentazione ufficiale in inglese. Se avete suggerimenti per migliorare questa traduzione, mandate per favore una pull request al repository Github tensorflow/docs. Per proporsi come volontari alla scrittura o alla review delle traduzioni della comunità contattate la mailing list docs@tensorflow.org.
Nel tutorial precedente abbiamo introdotto i Tensori
e le loro operazioni. In questo tutorial copriremo la differenziazione automatica, una tecnica importante per ottimizare i modelli di machine learning.
In [ ]:
import tensorflow as tf
TensorFlow fornisce l'API tf.GradientTape per la differenziazione automatica che calcola il gradiente di una computazione rispetto alle sue variabili in input. Tensorflow "registra" tutte le operazioni eseguite dentro il contesto di un tf.GradientTape
su un "tape". Tensorflow quindi usa quel "tape" e i gradienti associati con ogni operazione registrata per calcolare il gradiente di una computazione "registrata" utilizzando l'accumulazione inversa.
Per esempio:
In [ ]:
x = tf.ones((2, 2))
with tf.GradientTape() as t:
t.watch(x)
y = tf.reduce_sum(x)
z = tf.multiply(y, y)
# Derivative of z with respect to the original input tensor x
dz_dx = t.gradient(z, x)
for i in [0, 1]:
for j in [0, 1]:
assert dz_dx[i][j].numpy() == 8.0
Puoi anche richiedere i gradienti dell'output rispetto ai valori intermedi calcolati in un contesto "registrato" di tf.GradientTape
.
In [ ]:
x = tf.ones((2, 2))
with tf.GradientTape() as t:
t.watch(x)
y = tf.reduce_sum(x)
z = tf.multiply(y, y)
# Use the tape to compute the derivative of z with respect to the
# intermediate value y.
dz_dy = t.gradient(z, y)
assert dz_dy.numpy() == 8.0
Di default, le risorse tenute da un GradientTape sono rilasciate non appena il metodo GradientTape.gradient() è chiamato. Per calcolare multipli gradienti sullo stesso calcolo, crea un persistent
gradient tape. Questo da la possibilità di fare chiamate multiple del metodo gradient()
non appena le risorse sono rilasciate quando l'oggetto tape è liberato dal garbage collector. Per esempio:
In [ ]:
x = tf.constant(3.0)
with tf.GradientTape(persistent=True) as t:
t.watch(x)
y = x * x
z = y * y
dz_dx = t.gradient(z, x) # 108.0 (4*x^3 at x = 3)
dy_dx = t.gradient(y, x) # 6.0
del t # Drop the reference to the tape
In [ ]:
def f(x, y):
output = 1.0
for i in range(y):
if i > 1 and i < 5:
output = tf.multiply(output, x)
return output
def grad(x, y):
with tf.GradientTape() as t:
t.watch(x)
out = f(x, y)
return t.gradient(out, x)
x = tf.convert_to_tensor(2.0)
assert grad(x, 6).numpy() == 12.0
assert grad(x, 5).numpy() == 12.0
assert grad(x, 4).numpy() == 4.0
Le operazioni dentro il gestore di contesto di GradientTape
sono registrati per la differenziazione automatica. Se i gradienti sono calcolati nello stesso contesto, allora anche il calcolo del gradiente è registrato. Come risultato, la stessa API funziona per gradienti di ordine superiore. Per esempio:
In [ ]:
x = tf.Variable(1.0) # Create a Tensorflow variable initialized to 1.0
with tf.GradientTape() as t:
with tf.GradientTape() as t2:
y = x * x * x
# Compute the gradient inside the 't' context manager
# which means the gradient computation is differentiable as well.
dy_dx = t2.gradient(y, x)
d2y_dx2 = t.gradient(dy_dx, x)
assert dy_dx.numpy() == 3.0
assert d2y_dx2.numpy() == 6.0