반응형

출처: https://blog.naver.com/qbxlvnf11/221449595336

결론부터 말하자면 batch size와 성능의 상관 관계는 아직 정확하게 규정되지는 않았습니다.

task, 데이터에 따라 그 기준이 달라지기 때문입니다.

다만, 일반적으로 32, 64 크기의 mini-batch가 성능에는 가장 좋다고 알려져 있습니다.

batch size를 줄이거나 늘임으로써 얻는 장점을 요약하자면 다음과 같습니다.

▶ batch size를 줄임으로써 얻는 장점

- 필요한 메모리 감소: 전체 데이터를 쪼개어 여러 번 학습하는 것이기 때문에 최소 요구 메모리량을 줄일 수 있음.

▶ batch size를 늘임으로써 얻는 장점

- 아래 graph를 보면 전체 데이터를 활용한 Batch의 경우(파란색 그래프)보다 batch size가 작은 Mni-batch의 경우(초록색 그래프)가 더 fluctuate 한 것을 확인할 수 있음.

(더 flucatuate 하다는 것은 학습이 불안정 해진다는 의미)

▶ 정리

가용 메모리가 적을 때는 batch size를 상대적으로 작게,

보다 안정적으로 학습을 시키고 싶다면 batch size를 상대적으로 높게 설정해주면 됩니다.

다만, 아래 논문 정리글에서도 확인할 수 있듯이

batch size가 커질 수록 일반화 성능은 감소하는 경우가 다소 확인이 되었으니 그 점만 유의해주시면 되겠습니다.

[출처] 머신 러닝 - batch size 적절하게 조절하기|작성자 예비개발자

반응형
반응형

출처: https://m.blog.naver.com/qbxlvnf11/221449297033

 

이번 포스팅의 주제는 텐서플로우나 케라스 등을 사용해서 모델을 만들어 보았으면 다들 아실 용어인 epoch와 batch size 그리고 iteration입니다.


▶ 알고리즘이 iterative 하다는 것: gradient descent와 같이 결과를 내기 위해서 여러 번의 최적화 과정을 거쳐야 되는 알고리즘

optimization 과정

▶ 다루어야 할 데이터가 너무 많기도 하고(메모리가 부족하기도 하고) 한 번의 계산으로 최적화된 값을 찾는 것은 힘듭니다. 따라서, 머신 러닝에서 최적화(optimization)를 할 때는 일반적으로 여러 번 학습 과정을 거칩니다. 또한, 한 번의 학습 과정 역시 사용하는 데이터를 나누는 방식으로 세분화 시킵니다.

이때, epoch, batch size, iteration라는 개념이 필요합니다.


 

- epoch

One Epoch is when an ENTIRE dataset is passed forward and backward through the neural network only ONCE

(한 번의 epoch는 인공 신경망에서 전체 데이터 셋에 대해 forward pass/backward pass 과정을 거친 것을 말함. 즉, 전체 데이터 셋에 대해 한 번 학습을 완료한 상태)

▶ 신경망에서 사용되는 역전파 알고리즘(backpropagation algorithm)은 파라미터를 사용하여 입력부터 출력까지의 각 계층의 weight를 계산하는 과정을 거치는 순방향 패스(forward pass), forward pass를 반대로 거슬러 올라가며 다시 한 번 계산 과정을 거처 기존의 weight를 수정하는 역방향 패스(backward pass)로 나뉩니다. 이 전체 데이터 셋에 대해 해당 과정(forward pass + backward pass)이 완료되면 한 번의 epoch가 진행됐다고 볼 수 있습니다.

역전파 알고리즘이 무엇인지 잘 모른다고 하더라도 epoch를 전체 데이터 셋에 대해 한 번의 학습 과정이 완료됐다고 단편적으로 이해하셔도 모델을 학습 시키는 데는 무리가 없습니다.

epochs = 40이라면 전체 데이터를 40번 사용해서 학습을 거치는 것입니다.

▶ 우리는 모델을 만들 때 적절한 epoch 값을 설정해야만 underfitting과 overfitting을 방지할 수 있습니다.

epoch 값이 너무 작다면 underfitting이 너무 크다면 overfitting이 발생할 확률이 높은 것이죠.


- batch size

Total number of training examples present in a single batch.

- iteration

The number of passes to complete one epoch.

batch size는 한 번의 batch마다 주는 데이터 샘플의 size. 여기서 batch(보통 mini-batch라고 표현)는 나눠진 데이터 셋을 뜻하며 iteration는 epoch를 나누어서 실행하는 횟수라고 생각하면 됨.

▶ 메모리의 한계와 속도 저하 때문에 대부분의 경우에는 한 번의 epoch에서 모든 데이터를 한꺼번에 집어넣을 수는 없습니다. 그래서 데이터를 나누어서 주게 되는데 이때 몇 번 나누어서 주는가를 iteration, 각 iteration마다 주는 데이터 사이즈를 batch size라고 합니다.


출처: https://www.slideshare.net/w0ong/ss-82372826

- 정리

전체 2000 개의 데이터가 있고, epochs = 20, batch_size = 500이라고 가정합시다.

그렇다면 1 epoch는 각 데이터의 size가 500인 batch가 들어간 네 번의 iteration으로 나누어집니다.

그리고 전체 데이터셋에 대해서는 20 번의 학습이 이루어졌으며, iteration 기준으로 보자면 총 80 번의 학습이 이루어진 것입니다.

반응형
반응형

한국어 NLP와 딥러닝을 위한 도커이미지 만들기

딥러닝 + 도커?

딥러닝 프로젝트를 진행할 때 귀찮은 것 중 하나는 여러 라이브러리를 관리하고 어떤 버전을 설치했는지를 매번 체크하는 것이다.

Tensorflow나 PyTorch의 경우 매 시즌별로 버전 업데이트가 이뤄지며 동시에 api가 이전 버전과 달라져 어떤 것을 사용해야 하는지 선택이 곤란해지는 때가 있다.

한편 위 문제는 양반일 정도로 귀찮은 것이 하나 더 있다. 바로 CUDA와 cuDNN, APEX등을 버전을 맞춰 설치하고 PATH를 잡아서 진행하는 부분은 정말 끔찍하다.

다만 딥러닝만이 아닌 웹 개발을 진행한다 하더라도 버전 관리와 재현성이 제공되는 개발환경은 필수이기 때문에 도커를 사용해서 관리하는 것은 사실상 기본이 되어가고 있다.

귀여운 도커 아이콘을 찾아보았다

딥러닝 도커 이미지

딥러닝에 도커를 사용하는 이유는 또 다른 이유도 있다.

딥러닝 라이브러리들에서 GPU 가속을 사용하기 위해서는 앞서 말했던 것과 같이 CUDA와 여러 GPU 관련 라이브러리를  잡아줘야 한다. 하지만 이 작업이 생각보다 귀찮은 것은 차치하더라도, Tensorflow나 PyTorch가 (특히 TF가..!!!) 요구하는 CUDA/cuDNN을 버전 세트를 맞춰주는 것도 한세월.

하지만 최근 몇년 사이 딥러닝을 위한 도커 이미지가 넘쳐나고 있다.

당장 Tensorflow나 PyTorch의 공식 이미지부터 시작해 deepo, h2o.ai등 굉장히 다양한 이미지들이 넘쳐나고 있다. 이들을 이용해 추가적인 라이브러리를 설치해 입맛에 맞는 도커 이미지를 만들면 가장 편안하게 연구 개발을 할 수 있다.

Deepo 이미지로 띄우기

여러가지를 사용해 보았지만 현재(2019.11.27)시점 체감상 가장 안정적이고 잘 동작하고 나름 설정이 잘 되어있는 - 혹은 개인적 취향에 맞는 - 라이브러리는 바로 deepo 였다.

deepo

Deepo 바로가기: https://github.com/ufoym/deepo

Deepo는 처음부터 도커기반 딥러닝 이미지 프로젝트였고, CPU와 GPU 모든 경우이고 동시에 현재 자주 사용중인 딥러닝 라이브러리 대부분을 지원한다.

Deepo 도커 이미지 tag들

https://github.com/ufoym/deepo#available-tags 에서 볼 수 있는 Deepo에서 제공하는 태그들.

웬만한 것들은 다 지원하는 셈이다.

따라서 이 도커 이미지 위에 우리가 원하는 추가 패키지들을 설치하고 세팅을 진행하면 보다 편안-한 마음으로 개발을 할 수 있다.

Deepo 이미지 중 어떤 것을 사용하나?

개인적으로는 PyTorch를 가장 많이 사용하고 종종 Tensorflow도 사용하기 때문에 위 이미지 중 전체가 다 설치되어있는 all 시리즈를 사용한다.

그 중에서도 CUDA버전을 명시적으로 지정하는 all-jupyter-py36-cu100 (혹은 all-jupyter-py36-cu101)을 이용해서 진행하면 좋다.

최신버전을 사용하려면 all-jupyter 을 사용하면 된다.

이 버전에 따라서 Pre installed 라이브러리들의 버전이 달라진다.

도커 이미지 만들기

도커 이미지는 보통 아래 요소들로 만들어진다.

  1. FROM: 어떤 이미지에서 받아서 진행할지

  2. RUN: 어떤 명령어를 실행해서 이미지로 만들지

  3. WORKDIR: 현재 있는 폴더에서 명령을 실행할지

각 요소 하나하나가 실행될 때 마다 도커 이미지의 layer가 된다. = 이미지가 무거워진다!

따라서 apt-get 와 같이 한번만 실행하면 되는 경우에는 한 세트로 넣어서 돌리는 것이 유리하다.

Ubuntu 기반인 deepo

deepo는 ubuntu 기반으로 이미지를 제작하기 때문에 apt 등을 보다 편안하게 사용할 수 있다.

RUN 을 사용할 경우, 상위 이미지(deepo)에서 지정한 root 유저로 실행되기 때문에 apt 와 같은 명령어를 sudo 권한 없이도 실행할 수 있다.

1) Ubuntu 기반으로 불러오기

FROM 을 이용해 Deepo 이미지를 불러오자.

   

2) KoNLPy를 사용하기 위해 JVM을 설치해준다. 이와 함께 python, curl, wget등을 같이 설치해주자.

   

3) 언어팩 설정을 하기 위해 가장 많이 지원되는 en_US.UTF-8 을 시스템 언어로 지정해주자.

   

4) zsh를 설치한다. (Optional, 하지만 나중에 작업 편함)

   

5) Kakao에서 발표한 CNN기반 토크나이저인 Khaiii를 설치한다.

  • 빌드 시간이 조금 오래걸린다.
   

6) Jupyter Notebook 환경을 좀더 편리하게 사용하기 위해 Extension들을 설치해준다.

  • 추가적으로 필요한 Extension이 있다면 이 단계에서 설치하는 것을 추천한다.
   

7) 기타 Python라이브러리와 mecab을 설치한다.

  • 기타 라이브러리를 설치해준다. 간단히 소개하자면…
    • Pandas_explode는 pandas Dataframe에 .explode('column') 등을 사용 가능하게 만들어준다. (속도가 빠르진 않다.)
    • autopep8은 PEP8을 자동으로 맞춰준다. (ipynb파일도 지원함)
    • s3fs - s3:// 주소를 사용 가능하도록 만들어준다. (pd.read_csv 등에서 유용)
    • fastparquet - parquet 파일 형식을 읽고 쓸 수 있도록 해준다.
    • soynlp / konlpy - 한국어 토크나이저
    • dask - Pandas와 비슷하지만 Distributed Computing을 지원하는 라이브러리
    • python-snappy - parquet 파일 사용시 snappy 알고리즘을 사용하는데 이때 필요함
  • mecab-ko: KoNLPy에서 Mecab 클래스 사용을 위해서 필요
    • mecab은 초당 3~5000개 처리 / 1core
    • 다른것은 초당 100-300개 처리 / 1core
    • (라이젠 1800x 기준)
   

8) Docker 이미지를 root아닌 유저로 쓰도록 지정하는 유저 생성하기 (Optional)

  • user 라는 이름을 가진 유저가 생성된다.
   

유저를 root 가 아닌 유저로 생성하는 경우의 이점과 단점

  • 장점

    • 이후 Volume 마운트 시 권한이 꼬이지 않을 수 있고, 조금 더 안전하다.
  • 단점

    • 이와 같이 유저를 생성할 경우, sudo 권한을 명시적으로 주지 않는 한 sudo 명령을 쓰지 못한다.

    • apt-get 등으로 설치가 필요한 경우 Dockerfile을 새로 빌드해야 한다.

하지만 간단한 pip install 등은 User 디렉토리에 설치하는 방법을 통해 조금 환경 제약을 줄일 수도 있다.

최종본 Dockerfile

최종본 파일은 https://github.com/Beomi/deepo-nlp/blob/master/Dockerfile 에서 받을 수 있다.

위와 같이 Dockerfile을 작성한 뒤, 아래 명령어를 통해 도커 이미지를 빌드하면 된다.

   

도커 띄우기 RUN!

위와 같이 도커이미지를 만든 뒤, Jupyter Notebook 환경을 원활하게 사용하기 위해서는 여러 세팅이 필요하지만, 그 중에서 몇가지 지원을 하는 방식을 보자.

아래 파일은 내가 위 도커 이미지를 실행할때 쓰는 Shell Script다.

   

하나씩 뜯어보자.

1) GPU설정 & ipc=host

   

nvidia-docker 를 사용해야 도커 환경 내에서 CUDA가속을 사용할 수 있다.

Nvidia Docker 공식 레포: https://github.com/NVIDIA/nvidia-docker

도커 이미지 실행시 어떤 GPU를 사용할지 지정해야 하는데, --gpus=all 로 사용할 경우 해당 시스템에 있는 모든 GPU를 사용하도록 지정하고, -gpus '"device=1,2"' 와 같이 지정시 PCIe Bus기준 1,2번에 해당하는 것만 사용하도록 지정할 수 있다.

2) 도커 이미지로 연결할 포트 지정

   

-p 명령어를 통해 어떤 외부포트 를 어떤 내부포트 로 연결할지 지정할 수 있다.

위와같이 -p 18888:8888 로 지정할 경우 해당컴퓨터IP:18888 로 접속시 Jupyter Notebook 포트인 내부 8888에 접근할 수 있게 된다.

3) 유저명으로 접근

   

위와 같이 사용시 현재컴퓨터에 로그인한 유저의 ID와 Group ID를 알 수 있다.

만약 첫 유저라면 보통은 1000:1000 속성을 가지게 된다.

앞서 Dockerfile에서 지정했던 유저는 1000번이기 때문에 만약 혼자 사용하는 컴퓨터라면 유저 권한을 맞춰줄 수 있다.

만약 여럿이서 사용하는 서버라면 Dockerfile 빌드시 유저 id를 다르게 생성하면 된다.

4) 로컬의 임의의 폴더(.dockervm)을 연결

   

위와 같이 임의의 폴더에 도커 내부의 폴더와 연결하면, pip install --user 와 같은 명령어를 통해 설치한 패키지는 도커 이미지를 재시작 할 경우에도 여전히 설치된 상태를 유지할 수 있고, JupyterNotebook의 패스워드 역시 매번 새로운 토큰 대신 고정된 패스워드를 사용할 수 있다.

또한 로컬의 code 폴더와 내부의 code 폴더를 맞춰 쉽게 액세스 할 수 있도록 실제 작업환경 공간을 맞춰준다.

5) 로컬의 유저 폴더를 내부에 ReadOnly로 연결

   

Docker의 Volume Mount시 :ro 옵션을 붙이면 ReadOnly 모드로 동작한다. 특정 파일들을 접근할 때 매번 도커 이미지 내에 업로드 하는 대신, 로컬의 파일을 손쉽게 가져다 쓸 수 있도록 만들어 준다.

6) ZSH를 이용한 JupyterNotebook 실행

   

마지막 단계인 도커 이미지 실행 단계이다.

단순하게 jupyter notebook 이라고 실행하면 문제가 발생한다. PATH 지정이 되지 않아 앞서 설치한 패키지가 인식되지 않을 수 있기 때문이다.

따라서 PATH 를 오버라이딩해줘 Python이 인식하도록 만들어줄 수 있다.

이후 No browser(CLI인 경우) 옵션, 그리고 모든 hostname을 통해 접근 가능하도록 0.0.0.0 으로 지정하고, JupyterNotebook이 실행될 기본 폴더를 /code 로 지정해주면 끝이 난다.

정리

딥러닝, 혹은 자연어 처리 등을 위해 Docker 이미지를 직접 만들어서 쓰는건 사실 당연한 일이다. 아무리 기존의 딥러닝 이미지들이 잘 되어있다고 하더라도 특히 한국어를 위한 이미지는 많이 부족한 것이 사실이다.

시스템을 많이 건드리지 않으면서도 커스터마이징을 좀 더 쉽고 빠른 연구가 가능하도록 자신만의 환경을 쌓아가는 것도 중요한 부분이지 않을까 생각해 본다.

 

출처: https://beomi.github.io/2019/12/20/DockerImage_for_KoreanNLP/#%EC%B5%9C%EC%A2%85%EB%B3%B8-Dockerfile

반응형
반응형

딥러닝 환경 구축의 어려움

개인 데스크탑에서 cuda나 cudnn 등 nvidia 가속을 이용하는 환경을 구축하는 게 간단하지는 않습니다. 저의 경우 파이선 가성화를 위해서 anaconda를 주로 사용하는데, conda 업그레이드시 함께 포함된 패키지가 업데이트되면서 호환성이 깨지는 경우가 종종 발생하였습니다.

그래서, 차라리 누군가 잘 만들어놓은 도커를 가져다가 조금만 변경해서 사용하면 좋겠다는 생각에서 저의 개인적인 경험을 바탕으로 소개하도록 하겠습니다.

Deepo 도커 소개

deepo는 딥러닝/머신러닝 개발 환경을 쉽게 구축할 수 있는 all-in-one 도커입니다.
자세한 것은 이 링크를 눌러 deepo 깃헙 페이지를 방문하면 알 수 있습니다.

간략하게 소개해보면,

  • python 3.6.9
  • Keras 2.3.1
  • tensorflow 2.1.0
  • torch 1.5.0
  • Theano 1.0.4
  • scikit-learn 0.22.2
  • jupyter 1.0.0

등 딥러닝/머신러닝 개발에 필요한 프레임워크와 라이브러리 등을 거의다 갖추고 있습니다.

이거 하나면 왠만한 개발환경은 다 커버할것 같습니다.

Deepo 설치하기

Deepo 설치에 앞서서

아래가 대략의 설치 환경입니다.

Deepo 설치하기

Docker Hub에서 Deepo 이미지 설치하기

아래 명령어를 실행하면 최신 deepo 도커 이미지를 설치할 수 있습니다.

$ docker pull ufoym/deepo

설치가 잘 되었는지 확인해봅니다.

$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE ... ufoym/deepo all-py36-cu101 5d5a5c342dbf 2 weeks ago 13.3GB ufoym/deepo latest 5d5a5c342dbf 2 weeks ago 13.3GB ...

저는 2개의 별도 버전을 설치했는데, 동일한 것으로 보이네요.

이것으로 설치완료입니다. 이제부터 사용하기만 하면 됩니다. 다만, 도커에 익숙하지 않은 분들을 위해서 몇 가지 더 설명해봅니다.

Docker 실행하기

아래는 deepo 도커를 실행하고 bash로 진입하는 명령어입니다.

$ docker run -p 8888:8888 --gpus all -it -v {host-dir}:{container-dir} ufoym/deepo bash

도커 옵션 설명:

  • run: 도커 실행 명령어
  • "-p 8888:8888": 컨테이너의 8888번 포트를 호스트 OS 8888번 포트로 포워드하는 옵션입니다. 나중에 jupyter notebook이나 lab에서 사용하는 8888번 포트를 외부에서도 접속이 가능해집니다.
  • "--gpus all": 컨테이너의 gpu 사용을 가능하도록 하는 옵션입니다.
  • "-it": 인터랙티브 터미널을 사용하기 위한 옵션입니다.
  • "-v {host-dir}:{container-dir}": 호스트의 디렉토리를 컨테이너 내부에 공유하기 위한 옵션입니다.
  • "bash": 터미널에서 실행할 명령어입니다. bash 쉘을 통해 도커에 진입하게 됩니다.

Jupyter Lab 설치하기

저는 Jupyter Notebook 보다는 Jupyter Lab을 선호하는데 Deepo에는 안타깝게도 Jupyter Notebook만 설치되어 있습니다. Jupyter Lab을 설치하겠습니다. 컨테이너 내부에서 설치한다고 가정합니다.

# pip install jupyterlab

또는 컨테이너 외부에서도 설치할 수 있습니다.

# docker exec -it {container-name} pip install jupyterlab

Jupyer Lab 실행하기

컨테이너 내부에서 실행할 때는 아래와 같이 실행하면 됩니다.

# nohup jupyter lab --ip 0.0.0.0 --port 8888 --allow-root --no-browser &

포트는 아까 실행할때 지정한 8888번 포트로 띄웁니다. 그러면, 이제 호스트 OS의 8888번 포트를 열어두기만 하면 외부에서도 접근이 가능해집니다. 그리고 컨테이너 내부에서 root로 실행시키고 있기 때문에, --allow-root 옵션이 필요하고 브라우저가 없기 때문에 --no-browser 옵션도 같이 붙여 실행합니다.

Deepo에 변경사항 저장하기

필요에 따라서 Jupyter Lab 등 별도의 라이브러리나 프레임워크를 설치하는 경우에는 도커를 실행할 때마다 리셋되기 때문에 재설치의 번거로움이 있습니다. 이런 경우 변경사항을 저장해서 내가 원하는 최적의 환경을 구축할 수 있습니다.

$ docker commit {container-id} {new-image-name}

위 명령어를 실행하면 현재 실행중인 컨테이너의 상태를 저장하여 새로운 도커 이미지로 생성합니다.

$ docker commit f7e19aaeef3f deepo_jupyterlab

을 실행하고 이미지를 확인해보겠습니다.

$ sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE deepo_jupyterlab latest 19ea1eeb6d17 2 hours ago 13.3GB ufoym/deepo all-py36-cu101 5d5a5c342dbf 2 weeks ago 13.3GB ufoym/deepo latest 5d5a5c342dbf 2 weeks ago 13.3GB

위와 같이 새롭게 생성한 도커 이미지를 실행하면 jupyter lab이 설치된 나만의 이미지를 실행할 수 있게 됩니다.

 

출처: https://velog.io/@vanang7/%EB%8F%84%EC%BB%A4%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%9C-%EB%94%A5%EB%9F%AC%EB%8B%9D-%ED%99%98%EA%B2%BD-%EA%B5%AC%EC%B6%95%ED%95%98%EA%B8%B0

반응형

+ Recent posts