텐서플로 함수와 그래프(tf.function, autograph)
텐서플로1 버전에서는 그래프가 API의 핵심으로 피할 수가 없었고...이때문에 더 복잡했다.
텐서플로2에서도 그래프가 있긴 하지만, 사용하기 매우 쉬워짐
텐서플로 함수 변환
일반 함수를 @tf.function 으로 데커레이터 싸거나, tf.function()함수안에 넣음으로써 그래프를 반영한 함수로 사용할 수 있음
def cube(x):
return x ** 3
cube(tf.constant(2.0))
cube라는 함수가 있다면 아래와 같이 텐서플로 함수로 변환이 가능하다.
tf_cube = tf.function(cube)
tf_cube(2)
@tf.function
def tf_cube(x):
return x ** 3
원본 파이썬 함수가 필요하다면 python_function을 호출하여 확인할 수 있다
tf_cube.python_function(2)
# 8
텐서플로는 사용하지 않는 노드를 제거하고 표현을 단순화하는 등의 방식으로 계산 그래프를 최적화 -> Lazy evaluation
따라서, 일반적으로 텐서플로 함수는 원본 파이썬 함수보다 훨씬 빠르게 실행됨
파이썬 함수를 빠르게 실행하려면 텐서 플로함수로 변환!!!
기본적으로 텐서플로 함수는 매번 새로운 그래프를 생성 -> 텐서플로 함수를 여러번 호출할때마다 프로그램이 느려지고, 메모리가 많이 사용됨 -> 메모리를 해제하기 위해 텐서플로 함수를 삭제해야함
오토그래프와 트레이싱
텐서플로는 어떻게 그래프를 생성할까?
- 파이썬 함수의 소스 코드를 분석하여 for, while, if, vreak, continue, return과 같은 제어문을 모두 찾음 -> 오토그래프
- 오토그래프는 함수의 모든 제어문을 텐서플로 연산으로 바꾼 업그레이드된 버전을 생성함
- 반복문은 tf.while_loop()로 바꾸고, for 문은 loop_body()함수로 바꿈 -> 그다음 함수를 호출함
매개변수 값을 전달하는 대신 심볼릭 텐서를 전달함 -> 이 텐서는 실제 값이 없고, 이름, 데이터 타입, 크기만 가짐
이 함수는 그래프 모드로 실행 -> 각 텐서플로 연산이 해당 연산을 나타내고 텐서를 출려하기 위해 그래프에 노드를 추가
> 즉 , eager mode나 eger execution과는 반대의 모드임
>> 텐서플로1과 비슷해지는 구조
최종 그래프는 트레이싱(tracing)과정을 통해 생성 -> 노드는 연산을 나타내고, 화살표는 텐서를 나타냄