Copyright 2018 The TensorFlow Authors.
Eager execution
Note: 이 문서는 텐서플로 커뮤니티에서 번역했습니다. 커뮤니티 번역 활동의 특성상 정확한 번역과 최신 내용을 반영하기 위해 노력함에도 불구하고 공식 영문 문서의 내용과 일치하지 않을 수 있습니다. 이 번역에 개선할 부분이 있다면 tensorflow/docs-l10n 깃헙 저장소로 풀 리퀘스트를 보내주시기 바랍니다. 문서 번역이나 리뷰에 참여하려면 [email protected]로 메일을 보내주시기 바랍니다.
텐서플로의 즉시 실행은 그래프를 생성하지 않고 함수를 바로 실행하는 명령형 프로그래밍 환경입니다. 나중에 실행하기 위해 계산가능한 그래프를 생성하는 대신에 계산값을 즉시 알려주는 연산입니다. 이러한 기능은 텐서플로를 시작하고 모델을 디버깅하는 것을 더욱 쉽게 만들고 불필요한 상용구 코드(boilerplate code) 작성을 줄여줍니다. 가이드를 따라하려면, 대화형 파이썬
해석기(interpreter)를 이용해 아래에 있는 코드 샘플을 실행하세요.
즉시 실행은 연구와 실험을 위한 유연한 기계학습 플랫폼으로 다음과 같은 기능을 제공합니다:
직관적인 인터페이스-코드를 자연스럽게 구조화하고 파이썬의 데이터 구조를 활용. 작은 모델과 작은 데이터를 빠르게 반복
손쉬운 디버깅-실행중인 모델을 검토하거나 변경 사항을 테스트해보기 위해서 연산을 직접 호출. 에러 확인을 위해서 표준 파이썬 디버깅 툴을 사용
자연스런 흐름 제어-그래프 제어 흐름 대신에 파이썬 제어 흐름을 사용함으로써 동적인 모델 구조의 단순화
즉시 실행은 대부분의 텐서플로 연산과 GPU 가속을 지원합니다.
Note: 일부 모델은 즉시 실행을 활성화한 경우 추가연산비용(overhead)이 증가한 경우도 있습니다.성능을 향상시키려는 노력은 계속 진행 중이지만 만약에 문제점을 찾거나 관련된 벤치마크를 공유하고 싶다면 버그를 기록해주세요
설치와 기본 사용법
텐서플로 2.0에서 즉시 실행은 기본으로 활성화되어 있습니다.
이제부터는 텐서플로 연산을 바로 실행할 수 있고 결과를 즉시 확인할 수 있습니다:
즉시 실행 활성화는 텐서플로 연산을 바로 평가하고 그 결과를 파이썬에게 알려주는 방식으로 동작을 변경합니다. tf.Tensor
객체는 계산 그래프에 있는 노드를 가르키는 간접 핸들(symbolic handle) 대신에 구체적인 값을 참조합니다. 나중에 실행하기 위해서 생성된 계산 그래프가 없기 때문에, print()
나 디버거를 통해서 결과를 검토하기 쉽습니다. 텐서값을 평가, 출력하거나 확인하는 것이 그래디언트(gradients)를 계산하는 흐름을 방해하지 않습니다.
즉시 실행은 NumPy와 같이 잘 작동됩니다. NumPy 연산에 tf.Tensor
를 매개변수로 사용가능합니다. 텐서플로 수학 연산은 파이썬 객체와 NumPy 배열을 tf.Tensor
객체로 변환합니다. tf.Tensor.numpy
메서드는 객체 값을 NumPy ndarray
로 반환합니다.
동적인 제어 흐름
즉시 실행의 가장 큰 이점은 모델을 실행하는 동안에도 호스트 언어의 모든 기능을 활용할 수 있다는 것입니다. 그래서 다음과 같이 fizzbuzz를 손쉽게 작성할 수 있습니다:
여기에 텐서값에 따른 조건절이 있고 실행중에 그 결과를 출력합니다.
즉시 훈련
그래디언트 계산하기
자동 미분은 인공 신경망 훈련을 위한 역전파와 같은 기계학습 알고리즘을 구현하는데 유용합니다. 즉시 실행을 사용하는 동안에는, 나중에 그래디언트를 계산하는 연산을 추적하기 위해 tf.GradientTape
을 사용하세요.
즉시 실행 중에 그래디언트를 계산하고 모델 훈련에 이용하기 위해서 tf.GradientTape
을 사용할 수 있습니다. 특히 복잡하고 반복적인 훈련인 경우에 더 유용합니다.
매번 실행될 때 서로 다른 연산이 수행될 수 있기 때문에 모든 정방향(forward-pass) 연산은 "tape"에 기록됩니다. 그다음 tape를 거꾸로 돌려 그래디언트를 계산한 후 tape를 폐기합니다. 특정한 tf.GradientTape
는 오직 하나의 그래디언트만을 계산할 수 있고 부가적인 호출은 실행중 에러(runtime error)를 발생시킵니다.
모델 훈련
다음 예는 표준 MNIST 손글씨 분류를 위한 다층 모델을 생성합니다. 즉시 실행 환경에서 훈련가능한 그래프를 생성하기 위한 옵티마이저(optimizer)와 층 API를 보여줍니다.
즉시 실행에서는 훈련을 하지 않아도 모델을 사용하고 결과를 점검할 수 있습니다:
케라스 모델은 자체적인 훈련 메서드(fit)을 포함하고 있지만 때로는 좀 더 수정할 필요가 있습니다. 다음은 즉시 실행을 활용한 반복적인 훈련의 예입니다:
Note: 조건을 만족했는지 확인하기 위해서 tf.debugging
에 있는 단언문(assert) 함수를 사용하세요. 이것은 즉시 실행과 그래프 실행 모두에서 동작합니다.
변수와 옵티마이저
tf.Variable
객체는 자동 미분을 쉽게 하기 위해서 학습동안 변경된 tf.Tensor
값을 저장합니다. 모델 파라미터는 클래스 인스턴스 변수로 캡슐화될 수 있습니다.
효과적으로 모델 파라미터를 캡슐화하려면 tf.Variable
을 tf.GradientTape
과 함께 사용합니다. 예를 들어, 위의 자동 미분은 다음과 같이 재작성 가능합니다:
즉시 실행에서 상태를 위한 객체 사용
텐서플로 1.x 그래프 실행에서, 프로그램 상태(예: 변수)는 전역 컬렉션에 저장되고 그 수명은 tf.Session
객체에 의해서 관리됩니다. 반면에 즉시 실행에서 상태 객체 수명은 그와 관련된 파이썬 객체 수명에 의해서 결정됩니다.
변수는 객체입니다
즉시 실행에서 변수는 그 객체의 마지막 참조가 제거될 때까지 유지되고 그 이후 삭제됩니다.
객체 기반의 저장
이번 장은 훈련 체크포인트 가이드 요약버전입니다.
tf.train.Checkpoint
는 tf.Variable
을 체크포인트 파일로 저장하거나 체크포인트 파일에서 복구할 수 있습니다:
모델을 저장하거나 읽어들이기 위해서, tf.train.Checkpoint
는 숨겨진 변수를 요구하지 않고 객체 내부 상태를 저장합니다. 옵티마이저
와 모델
, 전역 단계 상태를 기록하려면 tf.train.Checkpoint
에 전달하면 됩니다:
Note: 대부분의 반복 훈련 과정에서 변수는 tf.train.Checkpoint.restore
가 호출된 이후에 생성됩니다. 이러한 변수는 생성되자마자 복원될 것이므로 단언문을 통해 체크포인트가 완벽히 적재되었다는 것을 보장받을 수 있습니다. 자세한 내용은 훈련 체크포인트 가이드를 참고하세요.
객체 지향형 지표
tf.keras.metrics
는 객체로 저장됩니다. 새로운 데이터를 이 객체에 전달하여 지표를 수정하고 tf.keras.metrics.result
메서드를 사용해 그 결과를 얻습니다. 예를 들어:
서머리(summary)와 텐서보드
텐서보드는 훈련과정에서 모델을 파악하거나 디버깅하고 최적화하기 위해 사용하는 시각화 도구입니다. 텐서보드는 프로그램이 실행되는 동안 작성된 서머리 이벤트를 사용합니다.
즉시 실행에서 변수의 서머리 정보를 기록하기 위해서 tf.summary
를 사용합니다. 예를 들어, 다음은 매 100번째 훈련마다 loss
의 서머리 정보를 기록합니다:
자동 미분 관련 고급편
동적 모델
tf.GradientTape
는 또한 동적인 모델에서도 사용가능합니다. 아래 예는 역추적 길찾기 알고리즘의 복잡한 제어 흐름에도 불구하고, 그래디언트가 있으며 미분 가능이 하다는 것을 제외하면 일반적인 NumPy으로 작성한 코드처럼 보입니다:
사용자 정의 그래디언트
사용자 정의 그래디언트는 그래디언트를 재정의(override)하는 가장 쉬운 방법입니다. 정방향 함수안에서 입력값 또는 출력값, 중간값과 관련된 그래디언트를 정의해야 합니다. 예를 들어 다음은 역전파 과정에서 그래디언트의 놈(norm)을 클리핑(clip)하는 가장 쉬운 방법입니다:
사용자 정의 그래디언트는 일반적으로 연산에 대해 수치적으로(numerically) 안정된 그래디언트를 제공하기 위해 사용됩니다:
여기 log1pexp
함수는 이론적으로 사용자 정의 그래디언트를 활용해 간결해 질 수 있습니다. 아래 구현은 불필요한 계산을 제거함으로써 계산을 좀 더 효율적으로 하기 위해 정방향 경로안에서 계산된 tf.exp(x)
값을 재사용합니다:
성능
즉시 실행에서 계산은 자동으로 GPU로 분배됩니다. 만약 계산 분배를 사용자가 제어하고 싶다면 그 부분을 tf.device('/gpu:0')
블록 (또는 CPU도 동일)으로 감싸서 실행하세요:
tf.Tensor
객체는 실제로 그 연산을 수행할 다른 디바이스로 복사될 수 있습니다:
벤치마크
GPU에서 학습을 하는 ResNet50 같은 계산량이 많은 모델에서, 즉시 실행 성능은 tf.function
실행과 비교될 수 있습니다. 그러나 이러한 차이는 계산량이 작은 모델인 경우 더 커지고, 수많은 작은 연산으로 구성된 모델은 자주 반복되는 부분을 최적화하는 사례도 있습니다.
함수를 활용
즉시 실행이 개발과 디버깅 과정을 좀 더 대화형(interactive)으로 만들어 주지만 텐서플로 1.x 형태 그래프 실행은 학습의 분산과 성능, 운영 배포에 장점을 가지고 있습니다. 이러한 차이를 해소하기 위해서, 텐서플로 2.0에서는 tf.function
API를 도입했습니다. 자세한 내용은 tf.function 가이드를 참고하세요.