(깔아만 놨던..) 텐서플로우 2 알파에 이어 며칠 전에 베타가 나왔다길래 드디어 한 번 써 봅니다.

뭐 의미있는 건 아니지만... 제 맘대로 썼으니 틀린 것 많을 겁니다. 어차피 보실 분 없으니 틀리면 추후 고치는 걸로.

눈에 띄는 달라진 점

(공식 문서 경로가 영구링크가 아니네...)

"이펙티브 텐서플로 2.0" --- (어디서 많이 본 제목...)
1.0에서 2.0으로 이사하기
2.0으로 변환 스크립트

아래는 "이펙티브 텐서플로 2.0" 문서에 있는 것 중 눈에 띄는 것 적어본 것입니다.

  • 그래프 차리고 이것저것 차린 다음에 세션 열고 돌리는 방식에서

    • 적절히 만든 (=데코레이터 씌운) 파이썬 함수를 호출하면 알아서 지지고 볶아준다고 합니다.
      • 각 모델 구현을 파이썬 함수로 감싸고 텐서플로 함수라고 데코레이터 씌운 뒤 (`@tf.function`) 그냥 호출하면 알아서 돌려준답니다.
      • Eager(?) 기능이 메인이 되었네요.
      • 모든 함수를 텐서플로 함수로 감쌀 필요는 없고, 최상위 작업만 (inference, train 같은 거) 감싸주면 된다고 봤습니다.
    • v1 스타일대로 세션 열고 돌리려면 tf.compat.v1 네임스페이스로 이사간 'Session' 함수를 쓰라네요.
  • 전역 네임스페이스가 없어졌대요. 이제 정의한 변수를 잘 갖고 있어야 된답니다.

    • tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES) 같은 거 이제 안 되나봅니다. 어쩌지...
    • 대신 Keras에 model, layer 단위에서 정의했던 변수를 모아두는 기능이 있다네요. variables, trainable_variables 속성이 있대요.
  • 로그 수집 방법이 살짝 좋아진 것 같네요. tf.metrics를 쓰면 평균 같은 것 쉽게 수집할 수 있는 듯 합니다.

    • 예전에 저는 잘 몰라서 직접 파이썬 변수에 loss 값 같은 거 모은 뒤, batch 개수로 나눠서 평균 표시했었는데...
  • v2 기능이 정 싫다면 v1 모드로 돌릴수도 있지만, v2로 코드 변환 스크립트 및 v1 호환성 모듈을 준비했으니 어서어서 갈아타주시라네요. 과연 몇 년 걸릴지...

설치

기존 v1 설치된 환경에서 (Ubuntu 18.04, Nvidia 10x0 시리즈 GPU, 드라이버 410, CUDA 10, libcudnn v7) 그냥 아나콘다 새 환경 파고 pip 패키지 설치로 깔았습니다.

$ conda create -n tf_2 python=3.6
$ conda activate tf_2
$ conda install <필요 패키지>

$ pip install tensorflow-gpu==2.0.0-beta

그러나 돌려보니 libcudnn 오류 ㄷㄷㄷ

다른 블로그 글 찾아보고 GPU 드라이버 버전을 430으로 올려도 봤지만, 그냥 libcudnn 최신 버전으로 업그레이드하니 잘 동작하게 되었습니다.

일부 환경에서 per_process_gpu_memory_fraction 또는 allow_growth를 켜 줘야 GPU 연산이 정상 동작한다는 이야기가 있네요.

Session이 없어졌으니... GPU 설정은 어디서 하지?

  • GPU 2개 이상인 경우 원하는 GPU만 쓰도록 설정하거나
  • TF가 GPU 메모리를 모두 할당하지 않게 하기 위해
    • 여러 사용자가, 또는 여러 프로세스가 GPU 함께 쓰는 경우를 고려해야겠죠

v1에서는 tf.Session(config=<blahblah>)했었죠. v2에는 tf.Session이 없네요..

대신, 깃헙 이슈를 보니 tf.config.experimental에 있는 함수를 쓰라는군요.

참고: tf.config 코드

아래 예시는 모든 GPU에 대해 allow_mem_growth 설정을 먹인 뒤, 두 번째 GPU(와 CPU)만 쓰도록 하는 코드 조각입니다:

# set GPU devices not to allocate all memories
gpu_devs = tf.config.experimental.list_physical_devices('GPU')
[tf.config.experimental.set_memory_growth(i, enable=True) for i in gpu_devs]

# find CPU device
cpu_devs = tf.config.experimental.list_physical_devices('CPU')

# explicitly set devices to be used
tf.config.experimental.set_visible_devices([*cpu_devs, gpu_devs[1]])

가상 디바이스를 만들 수도 있나 보던데, 아직 _메모리 상한선을 명시_해야 작동해서 안 쓰기로 했습니다.

좋은 친구 MNIST, LeNet 돌려보기

2.0 시작하기

위 문서를 보면 MNIST 돌려보는 예시가 있습니다. 내 주피터 노트북에 위 문서의 코드 복붙하고 돌려보면 당연히 잘 돌아갑니다.

코드를 둘러보면,

  • 데이터 준비가 간편해보이네요
  • 모델 클래스... Keras 쓰기 싫으면 어떻게 할 지 모르겠네요
  • loss function, optimizer도 keras 걸 갖다 쓰네요.
  • tf.GradientTape이라는 게 새로 생긴 것 같습니다
  • placeholder 그만 쓰는 것 아주 좋은데, dimension 점검이 쉽지 않을 것 같아요

소감

  • 이제 세션 같은 거 만들 필요 없이, 함수 호출만 하면 알아서 돌아가니 좋긴 하네요
    • 코드를 보다 깔끔하게, 파이썬스럽게 쓸 수 있겠습니다
    • 저수준 제어가 어려워졌을까요. 그건 차차 알아보기로
  • 데이터 로더 좋아졌다고는 하는데... v1 때 개선되었다던 데이터 로더 전혀 이해 못했는데... v2 것도 제가 쓸 정도로 쉬울 것 같지는 않습니다
  • 기존의 컴파일(?)되면 고정되는 그래프에서, 파이토치 것 같은 다이나믹 그래프로 갈아탄 것 같은데요, 실험하기 좋을 것 같습니다
    • 진짜 그런지는... 그것도 차차 알아보기로
  • Keras 안 쓰는 경우의 예시를 한 번 찾아봐야겠습니다

굳이 지금 갈아타야할까 하면... v1으로 하던 실험이나 잘 하는 걸로 합시다 😢😢

+ Recent posts