본문 바로가기

Deep Learning/Keras & Tensorflow

TF 버전 별 재현성 잡는 방법 정리

320x100
320x100

 

 

 이전 글에 정리한 것처럼 재현성 잡힌 결과를 얻고 싶다면 Tensorflow-Determinism을 다운받아 사용해주면 된다. UpSampling의 Interpolation 이슈만 제외하고 나머지는 거의 다 재현성이 잡혀서 원하는 결과를 얻을 수 있다. TF 1.14.0 버전을 사용하던 나는 1년 동안 아무 문제 없이 잘 사용하고 있었는데... 최근 들어서 또 다시 재현성의 늪에 빠지게 됐다.

 

TF 2.1 이상은 tf-deteminism이 지원을 안 하네..? 

 

 

 말 그대로다. 회사 서버 업데이트를 하게 돼서 TF 2.5 버전을 사용하게 됐는데 tf-determinism이 해당 버전은 지원 안 한다는 에러 문구가 뜨더라. 그러면서 TF 2.8부터는 tf-determinism을 따로 설치할 필요 없이 간단한 설정으로 재현성을 잡을 수 있도록 지원한다고 하더라.

 

 그래서 Tensorflow 버전 별로 재현성을 잡으려면 어떻게 해야하는지 알아봤다. 그 결과를 정리하면 아래와 같다.

random_seed = 7
tf_version = tf.__version__
if tf_version == '1.14.0':
    from tfdeterminism import patch
    patch()
    os.environ["PYTHONHASHSEED"] = "0"
    os.environ['TF_DETERMINISTIC_OPS'] = '1'
    os.environ['TF_CUDNN_DETERMINISTIC'] = '1'
    np.random.seed(random_seed)
    random.seed(random_seed)
    tf.set_random_seed(random_seed)
    
elif tf_version == '2.5.0':
    os.environ["PYTHONHASHSEED"] = "0"
    os.environ['TF_DETERMINISTIC_OPS'] = '1'
    os.environ['TF_CUDNN_DETERMINISTIC'] = '1'
    os.environ['TF_CUDNN_USE_FRONTEND '] = '1' # https://github.com/tensorflow/tensorflow/issues/53771
    np.random.seed(random_seed)
    random.seed(random_seed)
    tf.random.set_seed(random_seed) # https://github.com/keras-team/keras/blob/v2.10.0/keras/utils/tf_utils.py#L34-L66
    
elif tf_version == '2.10.0':
    tf.keras.utils.set_random_seed(random_seed)
    tf.config.experimental.enable_op_determinism()
    np.random.seed(random_seed)
    random.seed(random_seed)
  • TF version ≤ 2.0
    tf-determinism을 지원하니까 기존 방식처럼 patch( )를 사용해주면 된다.
  • 2.1 ≤ TF version ≤ 2.7
    tf-determinism 지원도 안 하고 TF에서 자체적으로 지원해주지도 않는다.
    아무래도 해당 범위의 TF는 붕 뜬 버전인 것 같다.
    os.environ['TF_CUDNN_USE_FRONTEND'] = '1' 을 설정해주면 된다고는 하지만
    실제로 해보면 재현성이 안 잡힌다.
  • 2.8 ≤ TF version
    아나콘다를 통해 tensorflow-gpu 버전을 받다보면 뭔가 에러나고 꼬이고 그래서 난 TF 2.10를 받았다. 잘 돌아간다.
    tf.config.experimental.enable_op_determinism( )을 설정해주자.
    그리고 앞 줄에는 tf.keras.utils.set_random_seed(random_seed)를 꼭 먼저 적어주자. 안 그럼 에러난다.
    이렇게 설정해주면 재현성이 잡힌다.
  • TF 2.10 한계
    여전히 UpSampling 부분에서 재현성이 안 잡히는 현상이 나타나는 것 같다.
    interpolation 부분에서 발생하는 문제로 보여진다.
    layers.UpSampling2D( )의 interpolation default는 'nearest'인데,
    'nearest'를 사용하면 지원하지 않는다는 에러문구가 뜬다.
    그러니 'bicubic'이나 'bilinear'로 설정해주면 재현성이 잡히는 걸 확인할 수 있다.

 

  • Tip1
    bicubic이 upsampling했을 때 이미지 품질은 좋은데 '엄청' 느리다. bilinear로 설정할 것을 추천한다.
  • Tip2
    model.fit_generator( )에서 num_workers=1로 설정해야 재현성이 잡힌다.
    num_workers는 multi-thread (CPU) 사용 여부를 결정해주는 매개변수이다.
    재현성을 잡으려면 반복 실험을 할 때 이미지도 같은 순서로 넣어줘야 하는데,
    multi-thread를 사용하면 이미지 넣는 순서가 CPU 마음이라서 재현성을 잡기 어렵다.
    But!!!
    나라면 num_workers=6로 두고 학습을 시키겠다.
    이유1) 이미지 넣는 순서가 재현성에 지대한 영향을 줄 것 같진 않고..
    이유2) 어쨌거나 모델의 재현성은 잡힌 상황이기 때문
    이유3) 무엇보다도 재현성이 약간 안 잡히지만 학습 속도는 하늘과 땅차이!! 훨씬 빠름!!

 

 

< 참고 사이트 >

https://ballentain.tistory.com/32

https://github.com/NVIDIA/framework-determinism/blob/master/doc/tensorflow.md

https://github.com/tensorflow/tensorflow/issues/53771

https://github.com/NVIDIA/framework-determinism/issues/38

https://github.com/tensorflow/tensorflow/issues/53771