1. 의문
나를 괴롭힌 것은 책에 나온 이 짧은 코드이다:
import tensorflow as tf
x = tf.Variable(0.)
with tf.GradientTape() as tape:
y = 2 * x + 3
grad_of_y_wrt_x = tape.gradient(y, x)
의문: 내가 파이썬 경험이 많진 않지만; with문은 단지 자원을 확실하게 반납하는 데 도움을 주는, try-except-finally보다 더 편리한 예외처리 문법이라고만 알고 있었다. 그런데 저 코드는 두 가지가 이상해 보였다.
- with문의 취지가 안전한 자원 획득 및 반납이라면; 이미 반납한 자원을 쓰는 일은 있을 수 없지 않나? 그런데 저기선
tape
변수가 with문 밖에서 쓰인다. 더군다나 이게 예외적인 상황이 아니라 일반적인 쓰임새인 눈치다. - 오히려 with문 안에서는
tape
변수가 나타나지 않았다. 그런데y = 2 * x + 3
라는 저 식은 어째서tape
와 연관을 가지게 된단 말인가?
2. 컨텍스트
with문에 쓰인 GradientTape
는 파이썬에서 말하길 컨텍스트 관리자이다.
2-1. 컨텍스트 관리자
with문은 물론 자원 획득 및 반납의 경우에 흔히 쓰이지만; 더 정확히 말하면 블럭 부분에 컨텍스트(맥락)을 부여한다. 그러니까 문제의 코드에서 y = 2 * x + 3
부분은 tape
가 관리하는 어떤 맥락 안에서 실행되는 것이다. 컨텍스트 관리자는 자원 획득 및 반납뿐 아니라 전역 상태를 관리하는 용도로도 쓰일 수 있다.
2-2. GradientTape의 감시
GradientTape
라는 컨텍스트 관리자는 자신의 맥락 안에서 일어나는 텐서 연산(물론 TensorFlow 의 것만)을 감시할 수 있다. 이것은 y = 2 * x + 3
이 단순한 텐서 연산이 아니라; 연산자 오버라이딩을 쓰기 때문에 가능하다. 단; 대입문은 파이썬에서 오버라이딩 불가하다. 아마 TensorFlow에서는 y
를 x
에 대해 미분하는 대신 2 * x + 3
를 x
에 대해 미분하는 거 같다.
3. 요약 정리
- with문에
GradientTape
를 쓰면 해당GradientTape
개체는 그 with문 안에서 감시상태가 된다. - TensorFlow는 어떤
GradientTape
가 감시상태인지 안다. - TensorFlow의 텐서 개체로 연산을 하면 그 텐서연산을 실행할 뿐 아니라, 어떤 연산이 실행되었는지 감시상태인
GradientTape
에 기록한다.
4. 출처 및 참고
- Python - 컨텍스트 관리자
- TensorFlow - tf.GradientTape
- 문제의 코드: 케라스 창시자에게 배우는 딥러닝 개정 2판; 지은이: 프랑소와 숄레; 옮긴이: 박해선; 발행처: (주)도서출판 길벗; 발행년도: 2022년; 101쪽.
728x90