자동 미분

Theo Kim·2023년 1월 14일
0

자동 미분

import tensorflow as tf

텐서플로의 자동 미분

tf.GradientTape

tf.GradientTape는 컨텍스트(context) 안에서 실행된 모든 연산을 테이프(tape)에 "기록".

그 다음 텐서플로는 후진 방식 자동 미분(reverse mode differentiation)을 사용해 테이프에 "기록된" 연산의 그래디언트를 계산합니다.

  • Scalar 를 Scalar로 미분
x = tf.Variable(3.0)

with tf.GradientTape() as tape:
    y = x**2
y
<tf.Tensor: shape=(), dtype=float32, numpy=9.0>
# dy = 2x * dx
dy_dx = tape.gradient(y, x)
dy_dx.numpy()
6.0
  • Scalar를 Vector로 미분
w = tf.Variable(tf.random.normal((3, 2)), name='w')
b = tf.Variable(tf.zeros(2, dtype=tf.float32), name='b')
x = [[1., 2., 3.]]

with tf.GradientTape(persistent=True) as tape:
    y = x @ w + b
    loss = tf.reduce_mean(y**2)
[dl_dw, dl_db] = tape.gradient(loss, [w, b])

[dl_dw, dl_db]
[<tf.Tensor: shape=(3, 2), dtype=float32, numpy=
 array([[-0.56715715, -1.0900033 ],
        [-1.1343143 , -2.1800065 ],
        [-1.7014714 , -3.2700098 ]], dtype=float32)>,
 <tf.Tensor: shape=(2,), dtype=float32, numpy=array([-0.56715715, -1.0900033 ], dtype=float32)>]
my_vars = {
    'w': w,
    'b': b
}

grad = tape.gradient(loss, my_vars)
grad['b']
<tf.Tensor: shape=(2,), dtype=float32, numpy=array([-0.56715715, -1.0900033 ], dtype=float32)>
  • 자동미분 컨트롤 하기!

    • tf.Variable만 기록 합니다!
    • A variable + tensor 는 tensor를 반환
    • trainable 조건으로 미분 기록을 제어
# A trainable variable
x0 = tf.Variable(3.0, name='x0')

# Not trainable
x1 = tf.Variable(3.0, name='x1', trainable=False)

# Not a Variable: A variable + tensor returns a tensor.
x2 = tf.Variable(2.0, name='x2') + 1.0

# Not a variable
x3 = tf.constant(3.0, name='x3')

with tf.GradientTape() as tape:
    y = (x0**2) + (x1**2) + (x2**2)

grad = tape.gradient(y, [x0, x1, x2, x3])

for g in grad:
    print(g)
tf.Tensor(6.0, shape=(), dtype=float32)
None
None
None

기록되고 있는 variable 확인하기

tape.watched_variables()
(<tf.Variable 'x0:0' shape=() dtype=float32, numpy=3.0>,)
profile
THEO's velog

0개의 댓글