TensorFlow - 윈디하나의 솔라나라
|
하드웨어 지원 항목 | 하드웨어 조건 | 설명 |
GPU: CUDA | CUDA Compute Capability 3.5 이상 지원되는 nVidia 그래픽 카드 | 지원되는 그래픽 카드는 CUDA GPUs 참조 |
CPU: AVX | AVX 명령셋 지원 CPU | 인텔 샌디브릿지 코어, 에이엠디 불도저 코어 이상 |
CPU: AVX2 | AVX2 명령셋 지원 CPU | 인텔 하스웰 코어, 에이엠디 엑스카베이터 코어 이상 |
Ubuntu 최신버전이 필요하다. 이 글을 쓰는 시점에서 최신 버전은 Ubuntu 18.04.2 LTS Server 이다. 설치 후 최신 업데이트를 진행해 놓는다. Ubuntu 에 대한 일반적인 사항은 윈디하나의 솔라나라: Ubuntu (작성중)를 참고하자.
windy@wll ~ $ sudo apt update windy@wll ~ $ sudo apt upgrade
nVidia 의 GPU 가 시스템에 설치되어있다면, 아래와 같이 드라이버를 설치하자. GPU support | TensorFlow를 읽어보자.
디바이스 확인
windy@wll:~$ ubuntu-drivers devices
드라이버 설치 https://www.nvidia.com/Download/index.aspx?lang=en-us
windy@wll:~$ sudo sh NVIDIA-Linux-x86_64-418.56.run
CUDA® Toolkit 및 CUDA Profiling Tools Interface (CUPTI) https://developer.nvidia.com/cuda-zone
windy@wll:~$ sudo dpkg -i cuda-repo-ubuntu1810_10.1.105-1_amd64.deb windy@wll:~$ sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1810/x86_64/7fa2af80.pub windy@wll:~$ sudo apt-get update windy@wll:~$ sudo apt-get install cuda windy@wll:~$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda/extras/CUPTI/lib64
cuDNN SDK https://developer.nvidia.com/cudnn
windy@wll:~$ sudo dpkg -i libcudnn7_7.5.0.56-1+cuda10.1_amd64.deb windy@wll:~$ sudo dpkg -i libcudnn7-dev_7.5.0.56-1+cuda10.1_amd64.deb
TensorRT 5.0 https://developer.nvidia.com/tensorrt https://developer.nvidia.com/nvidia-tensorrt-5x-download
windy@wll:~$ sudo dpkg -i nv-tensorrt-repo-ubuntu1x04-cudax.x-trt5.x.x.x-ga-yyyymmdd_1-1_amd64.deb windy@wll:~$ sudo apt-key add /var/nv-tensorrt-repo-cudax.x-trt5.x.x.x-ga-yyyymmdd/7fa2af80.pub windy@wll:~$ sudo apt-get update windy@wll:~$ sudo apt-get install tensorrt
Python 3 및 부가 패키지를 설치한다.
windy@wll ~ $ sudo apt install python3-dev python3-pip
파이선 패키지중에 virtualenv 를 설치해 텐서플로를 실행할 가상 환경을 만들어 놓고 최신 버전으로 업그레이드 한다.
windy@wll ~ $ sudo pip3 install -U virtualenv windy@wll ~ $ cd ~ windy@wll ~ $ virtualenv --system-site-packages -p python3 ./venv windy@wll ~ $ source ~/venv/bin/activate (venv) windy@wll:~$ pip install --upgrade pip
이후 작업은 virtualenv 에서 작업하면 된다. virtualenv 에서 나가려면 deactivate 를 입력하면 된다.
Ubuntu 에는 Python 2와 Python 3가 공존하고 있기 때문에, virtualenv 를 사용해 Python 3 용 환경을 구성하여 사용하는것이 여러모로 편하다.
이제 텐서플로를 설치할 차례다. CPU 또는 GPU 버전을 선택해 설치하자.
(venv) windy@wll:~$ pip3 install tensorflow이외에도
pip install tensorflow==2.0.0-alpha0
과 같은 형식의 명령을 사용해, 텐서플로의 버전을 지정해 설치할 수 있다.
(venv) windy@wll:~$ pip3 install tensorflow-gpu
이후 텐서플로를 사용하려면 계정에 접속한 후 아래와 같이 입력한다.
windy@wll ~ $ source ~/venv/bin/activate (venv) windy@wll:~$
프롬프트가 (venv) windy@wll:~$
으로 보인다면 텐서플로를 실행할 수 있는 환경으로 진입된 것이다.
윈도에서 설치하는 방법에 대해 다룬다.
텐서플로의 GPU 버전을 사용하기 위해 아래와 같은 순서대로 윈도의 드라이버를 미리 설치해놓자. 만약 nVidia 그래픽 카드가 없다면 이 과정은 넘어가도 된다. 자세한 사항은 GPU support | TensorFlow, CUDA Installation Guide, Anaconda Tenserflow Installation를 읽어보자.
최신 nVidia GPU 드라이버 설치
다운로드: NVIDIA 드라이버 다운로드419.67-notebook-win10-64bit-international-whql.exe
→ 430.86-notebook-win10-64bit-international-whql.exe
→ 436.48-notebook-win10-64bit-international-whql.exe
CUDA 10.1 설치
다운로드: https://developer.nvidia.com/cuda-downloadscuda_10.1.105_418.96_win10.exe
→ cuda_10.1.168_425.25_win10.exe
→ cuda_10.1.243_426.00_win10.exe
cuDDN 7.5 for CUDA 10.1 설치
다운로드: https://developer.nvidia.com/cudnncudnn-10.1-windows10-x64-v7.5.0.56.zip
→ cudnn-10.1-windows10-x64-v7.6.0.64.zip
→ cudnn-10.1-windows10-x64-v7.6.4.38.zip
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.1
에 압축 풀기TensorRT 5.1.2 for CUDA 10.1 cuDNN 7.5 설치
다운로드: https://developer.nvidia.com/nvidia-tensorrt-downloadTensorRT-5.1.2.2.Windows10.x86_64.cuda-10.1.cudnn7.5.zip
→ TensorRT-5.1.5.0.Windows10.x86_64.cuda-10.1.cudnn7.5.zip
C:\Program Files\NVIDIA GPU Computing Toolkit\TensorRT
에 압축 풀기드라이버 설치시, 각각의 드라이버 설치 파일 버전을 확인해 설치해야 한다. 파일 이름을 자세히 보면 드라이버에 맞는 버전이 어느것인지 알 수 있다. 2019.06 현재 위와 같은 파일을 사용해 필자의 노트북에 설치했고 작동하는 것을 확인했다. 경험상 4가지 드라이버 "모두" 최신버전으로 설치하면 잘 작동했다.
이후 파이썬3를 설치해야 한다. 윈도에서는 유명한 윈도용 파이썬 개발 환경인 아나콘다(Anaconda)를 설치하곤 한다. 이 문서에서도 아나콘다를 설치할 것이다.
아나콘다 설치
다운로드: https://www.anaconda.com/distribution/Anaconda3-2019.03-Windows-x86_64.exe
이제 텐서플로를 설치할 차례다.
Anaconda Prompt를 관리자권한으로 실행한 후 아래와 같이 입력하자.
(base) C:\Users\windy>conda --version conda 4.6.14 (base) C:\Users\windy>conda update conda ... (base) C:\Users\windy>conda update --all ... # All requested packages already installed. (base) C:\Users\windy>conda create -n tensorflow_gpuenv tensorflow-gpu ... tensorboard pkgs/main/win-64::tensorboard-1.13.1-py37h33f27b4_0 tensorflow pkgs/main/win-64::tensorflow-1.13.1-gpu_py37h83e5d6a_0 tensorflow-base pkgs/main/win-64::tensorflow-base-1.13.1-gpu_py37h871c8ca_0 tensorflow-estima~ pkgs/main/noarch::tensorflow-estimator-1.13.0-py_0 tensorflow-gpu pkgs/main/win-64::tensorflow-gpu-1.13.1-h0d30ee6_0 ... Proceed ([y]/n)?y ... done # # To activate this environment, use # # $ conda activate tensorflow_gpuenv # # To deactivate an active environment, use # # $ conda deactivate이후 텐서 플로 GPU 를 업그레이드하려면 아래와 같이 한다.
(tensorflow_gpuenv) C:\Users\windy>pip install --upgrade tensorflow-gpu버전을 지정해 업그레이드 하려면
pip install --upgrade tensorflow-gpu==1.14
와 같이 버전을 지정한다.
TensorFlow GPU 환경 설정
(base) C:\Users\windy>cd %CONDA_PREFIX% (base) C:\ProgramData\Anaconda3>mkdir .\etc\conda\activate.d (base) C:\ProgramData\Anaconda3>mkdir .\etc\conda\deactivate.d (base) C:\ProgramData\Anaconda3>type NUL > .\etc\conda\activate.d\env_vars.bat (base) C:\ProgramData\Anaconda3>type NUL > .\etc\conda\deactivate.d\env_vars.bat (base) C:\ProgramData\Anaconda3>notepad .\etc\conda\activate.d\env_vars.bat @echo off SET OLDPATH=%PATH% SET PATH=C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.1\bin;%PATH% SET PATH=C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.1\extras\CUPTI\libx64;%PATH% SET PATH=C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.1\include;%PATH% SET PATH=C:\Program Files\NVIDIA GPU Computing Toolkit\TensorRT\bin;%PATH% SET PATH=C:\Program Files\NVIDIA GPU Computing Toolkit\TensorRT\lib;%PATH% SET PATH=C:\tools\cuda\bin;%PATH% # Object Detection 환경 SET PYTHONPATH=C:\models\research;C:\models\research\slim (base) C:\ProgramData\Anaconda3>notepad .\etc\conda\deactivate.d\env_vars.bat @echo off SET PATH=%OLDPATH% SET OLDPATH= SET PYTHONPATH=
이후 텐서플로를 사용하려면 Anaconda를 실행한 후 아래와 같이 입력한다.
(base) C:\Users\windy>conda activate tensorflow_gpuenv (tensorflow_gpuenv) C:\Users\windy>
프롬프트가 (tensorflow_gpuenv) C:\Users\windy>
으로 보인다면 텐서플로를 실행할 수 있는 환경으로 진입된 것이다.
몇가지 아나콘다 사용 방법에 대해 설명한다. (콘다 프롬프트를 관리자로 실행해야 한다)
#아나콘다버전확인 conda --version #아나콘다정보보기 conda info #아나콘다업데이트 conda update conda #아나콘다가상환경생성 (Python 3.5 환경을 가진 test 라는 가상 환경 생성) conda create -n test python=3.5 #아나콘다가상환경목록보기 conda info -e # 아나콘다개발환경활성화하기 conda activate test # 아나콘다개발환경제거 conda remove --name test --all #패키지설치 conda install simplejson #패키지리스트확인 conda list #패키지삭제 (test 가상환경에서 simplejson 패키지 삭제) conda remove -n test simplejson #아나콘다클린(캐시삭제) conda clean -a
텐서플로가 제대로 설치되었는지 확인해보자.
하기 예제에서, 윈도와 리눅스로 표기된 부분이 서로 다르다. 기본적으로 이 문서는 윈도에서 텐서플로 GPU으로 작성하였지만, 샘플 코드는 윈도및 리눅스, 텐서플로 CPU 및 텐서플로 GPU버전에서도 테스트하였다. 하기 예제에서 윈도용인지 리눅스용인지 구분은 프롬프트로 하면 된다.
- 윈도용 프롬프트
(tensorflow_gpuenv) C:\Users\windy>
- 리눅스용 프롬프트
(venv) windy@wll:~$
현시점에서 사용한 텐서플로 버전은 2.0.0이다.
텐서플로 1.x와 2.0 이 많이 변경되었기 때문에, 텐서플로 1.x용 소스코드를 2.0에서 사용하기 위해 제법 많은 소스코드를 수정해야할 수도 있다. 이를 위해 텐서플로 2.0에서는 tf_upgrade_v2(1)을 제공해준다.
tf_upgrade_v2 --infile infile --outfile outfile자세한 사항은
tf_upgrade_v2 -h
를 참고하자. 디렉토리에 있는 전체 소스를 변경하거나, .ipynb 파일도 변환할 수 있다.
(tensorflow_gpuenv) C:\Users\windy> python -c "import tensorflow as tf; print(tf.__version__)" 2.0.0
(tensorflow_gpuenv) C:\Users\windy> python -c "import tensorflow as tf; tf.compat.v1.enable_eager_execution(); print(tf.reduce_sum(input_tensor=tf.random.normal([1000, 1000])))" tf.Tensor(340.48917, shape=(), dtype=float32)
CUDA 가속 사용 여부를 아래와 같이 확인해볼 수 있다.
(tensorflow_gpuenv) C:\Users\windy>python -c "import tensorflow as tf; print(tf.test.is_gpu_available())" 2019-10-02 00:52:58.674765: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library cudart64_100.dll 2019-10-02 00:53:02.104225: I tensorflow/core/platform/cpu_feature_guard.cc:142] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 2019-10-02 00:53:02.122567: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library nvcuda.dll 2019-10-02 00:53:02.266711: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1618] Found device 0 with properties: name: GeForce GTX 960M major: 5 minor: 0 memoryClockRate(GHz): 1.176 pciBusID: 0000:01:00.0 2019-10-02 00:53:02.281193: I tensorflow/stream_executor/platform/default/dlopen_checker_stub.cc:25] GPU libraries are statically linked, skip dlopen check. 2019-10-02 00:53:02.292560: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1746] Adding visible gpu devices: 0 2019-10-02 00:54:53.484009: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1159] Device interconnect StreamExecutor with strength 1 edge matrix: 2019-10-02 00:54:53.495297: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1165] 0 2019-10-02 00:54:53.500887: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1178] 0: N 2019-10-02 00:54:53.513165: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1304] Created TensorFlow device (/device:GPU:0 with 1374 MB memory) -> physical GPU (device: 0, name: GeForce GTX 960M, pci bus id: 0000:01:00.0, compute capability: 5.0) True1) 시스템에서 처음 실행시 수행하는데 시간이 오래 걸린다. (필자의 노트북에서는 3분 넘게 걸렸다) 끈기있게 기다리자. 이후부터는 1~2초 사이에 완료된다.
로그를 끄려면 set TF_CPP_MIN_LOG_LEVEL=2
명령을 사용하자. 아래는 인터프리터 형식으로 "Hello World!"를 텐서플로를 사용해 출력하는 예제이다.
(tensorflow_gpuenv) C:\Users\windy>python Python 3.7.3 (default, Apr 24 2019, 15:29:51) [MSC v.1915 64 bit (AMD64)] :: Anaconda, Inc. on win32 Type "help", "copyright", "credits" or "license" for more information. >>> import tensorflow as tf >>> welcome = tf.constant("Hello World!") >>> sess = tf.compat.v1.Session() >>> sess.run(welcome) b'Hello World!' >>> exit() (tensorflow_gpuenv) C:\Users\windy>2.0 에서 안됨! Constant Operation 이 없어짐?
(tensorflow_gpuenv) C:\Users\windy>pip install pillow (tensorflow_gpuenv) C:\Users\windy>pip install lxml (tensorflow_gpuenv) C:\Users\windy>pip install matplotlib (tensorflow_gpuenv) C:\Users\windy>pip install scipy scikit-learn (tensorflow_gpuenv) C:\Users\windy>pip install python-mnist (tensorflow_gpuenv) C:\Users\windy>pip install pandas
tensorflow_keras_lstm_stateful_2.py | (7,979 바이트) |
#!/usr/bin/env python # coding: utf-8 # In[1]: # 0. 사용할 패키지 불러오기 import os import numpy as np import tensorflow as tf from tensorflow import keras from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense, LSTM from keras.utils import np_utils # 랜덤시드 고정시키기 np.random.seed(5) # In[2]: # 가중치 저장 파일 checkpoint_path = "output/checkpoint/weight.ckpt" # 텐서보드 저장 경로(디렉토리) tensorboard_path = "output/tensorboard" # 모델 저장 파일 model_path = "output/model.h5" # 손실 이력 클래스 정의 class LossHistory(keras.callbacks.Callback): def init(self): self.losses = [] def on_epoch_end(self, batch, logs={}): self.losses.append(logs.get('loss')) # 데이터셋 생성 함수 def seq2dataset(seq, window_size): dataset_X = [] dataset_Y = [] for i in range(len(seq)-window_size): # subset = [['g8', 'e8', 'e4', 'f8', 'd8'], # ['e8', 'e4', 'f8', 'd8', 'd4']...] subset = seq[i:(i+window_size+1)] for si in range(len(subset)-1): # subset[si] 에는 g8이 features = code2features(subset[si]) # feature 에는 [0.666, 1]이 dataset_X.append(features) dataset_Y.append([code2idx[subset[window_size]]]) return np.array(dataset_X), np.array(dataset_Y) # 속성 변환 함수 def code2features(code): features = [] features.append(code2scale[code[0]]/float(max_scale_value)) features.append(code2length[code[1]]) return features # In[3]: # 1. 데이터 준비하기 # 코드 사전 정의 # 도레미파솔라시도 이기 때문에 0 ~ 6까지 code2scale = {'c':0, 'd':1, 'e':2, 'f':3, 'g':4, 'a':5, 'b':6} code2length = {'4':0, '8':1} code2idx = {'c4':0, 'd4':1, 'e4':2, 'f4':3, 'g4':4, 'a4':5, 'b4':6, 'c8':7, 'd8':8, 'e8':9, 'f8':10, 'g8':11, 'a8':12, 'b8':13} idx2code = {0:'c4', 1:'d4', 2:'e4', 3:'f4', 4:'g4', 5:'a4', 6:'b4', 7:'c8', 8:'d8', 9:'e8', 10:'f8', 11:'g8', 12:'a8', 13:'b8'} # 최대 6까지 나옴 max_scale_value = 6.0 # 시퀀스 데이터 정의 seq = ['g8', 'e8', 'e4', 'f8', 'd8', 'd4', 'c8', 'd8', 'e8', 'f8', 'g8', 'g8', 'g4', 'g8', 'e8', 'e8', 'e8', 'f8', 'd8', 'd4', 'c8', 'e8', 'g8', 'g8', 'e8', 'e8', 'e4', 'd8', 'd8', 'd8', 'd8', 'd8', 'e8', 'f4', 'e8', 'e8', 'e8', 'e8', 'e8', 'f8', 'g4', 'g8', 'e8', 'e4', 'f8', 'd8', 'd4', 'c8', 'e8', 'g8', 'g8', 'e8', 'e8', 'e4'] # In[4]: # 2. 데이터셋 생성하기 # 여기서 windows_size =4 부분은 LSTM 에 들어가는 timestep = 4 와 동일하다. # 4개의 데이터 추이를 보고 다음의 것을 추론하는 형태로 구성할 것이다. x_train, y_train = seq2dataset(seq, window_size = 4) # x_train # array([[0.66666667, 1. ], # [0.33333333, 1. ], # [0.33333333, 0. ], # [0.5 , 1. ], # y_train # array([[ 8], # [ 1], # [ 7], # [ 8], # In[5]: # 입력을 (샘플 수, 타임스텝, 특성 수)로 형태 변환 x_train = np.reshape(x_train, (50, 4, 2)) # array([[[0.66666667, 1. ], # [0.33333333, 1. ], # [0.33333333, 0. ], # [0.5 , 1. ]], # # [[0.33333333, 1. ], # [0.33333333, 0. ], # [0.5 , 1. ], # [0.16666667, 1. ]], # In[6]: # 라벨값에 대한 one-hot 인코딩 수행 # [8] -> [0,0,0,0,0,0,0,0,1,0,0,0] # [1] -> [0,1,0,0,0,0,0,0,0,0,0,0] # 최대값은 12이므로 출력되는 배열의 개수가 12개임 y_train = np_utils.to_categorical(y_train) # array([[0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0.], # [0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], # In[7]: one_hot_vec_size = y_train.shape[1] #print("one hot encoding vector size is ", one_hot_vec_size) # numpy 에서 행이 2이고 열이 3인 2차원 배열에서 rank는 2 이고, shape는 (2, 3) # In[8]: # 3. 모델 구성하기 # 상태유지 모델(stateful=True) 에서, 배치 크기 = 1, 타임스탭 = 4, 속성개수(입력 값의 개수) = 2 # LSTM에서 상태유지모델에서 배치크기 1의 의미는, 동시에 상태를 유지할 개수다. 여기서는 곡 1개만 학습할것이라 1로 했다. 가중치는 공유된다. # LSTM에서 상태를유지하지않는 모델에서 배치크기는 상태를 유지할 개수. 1이면 상태를 유지하지 않는다. def create_LSTM_model(): model = Sequential() # 아래에서 128 은 특별히 의미가 없다. ^^ model.add(LSTM(128, batch_input_shape = (1, 4, 2), stateful=True)) model.add(Dense(one_hot_vec_size, activation='softmax')) return model def create_StackedLSTM_model(): model = Sequential() model.add(LSTM(32, return_sequences=True, stateful=True,batch_input_shape=(1, 4, 2))) model.add(LSTM(32, return_sequences=True, stateful=True)) model.add(LSTM(32, stateful=True)) model.add(Dense(one_hot_vec_size, activation='softmax')) return model model = create_StackedLSTM_model() model.summary() # In[9]: # 4. 모델 학습과정 설정하기 model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy']) # In[10]: # 5. 모델 학습시키기 # 테스트삼아 20개로 했다. 10000 번은 해야 함. num_epochs = 20 history = LossHistory() # 손실 이력 객체 생성 history.init() # 가중치 저장 #checkpoint_dir = os.path.dirname(os.path.abspath(checkpoint_path)) #if not os.path.exists(checkpoint_dir): # os.makedirs(checkpoint_dir) #print("CheckPoint DIR: ", checkpoint_dir) #cp_callback = tf.keras.callbacks.ModelCheckpoint(checkpoint_path, save_weights_only=True, verbose=1) # 텐서보드용 로그 저장 tb_hist = keras.callbacks.TensorBoard(log_dir=tensorboard_path, histogram_freq=0, write_graph=True, write_images=True) # 학습 시작 for epoch_idx in range(num_epochs): print ('epochs : ' + str(epoch_idx) ) model.fit(x_train, y_train, epochs=1, batch_size=1, verbose=2, shuffle=False, callbacks=[history, tb_hist]) # 50 is X.shape[0] model.reset_states() # 곡 전체에 대한 시퀀스를 학습시키므로, 한곡이 끝날때에 상태 리셋하면 됨 # In[11]: # 6. 학습과정 살펴보기 get_ipython().run_line_magic('matplotlib', 'inline') import matplotlib.pyplot as plt plt.plot(history.losses) plt.ylabel('loss') plt.xlabel('epoch') plt.legend(['train'], loc='upper left') plt.show() # In[12]: # 7. 모델 평가 및 가중치 저장 loss, acc = model.evaluate(x_train, y_train, batch_size=1) print("복원된 모델의 정확도: {:5.2f}%".format(100*acc)) # 모델 저장 model.save_weights(checkpoint_path) # HDF5 포맷으로 저장 model.save(model_path) model.reset_states() # In[13]: # 8. 모델 사용하기 pred_count = 50 # 최대 예측 개수 정의 # 한 스텝 예측 seq_out = ['g8', 'e8', 'e4', 'f8'] pred_out = model.predict(x_train, batch_size=1) for i in range(pred_count): idx = np.argmax(pred_out[i]) # one-hot 인코딩을 인덱스 값으로 변환 seq_out.append(idx2code[idx]) # seq_out는 최종 악보이므로 인덱스 값을 코드로 변환하여 저장 print("one step prediction : ", seq_out) model.reset_states() # 곡 전체 예측 seq_in = ['g8', 'e8', 'e4', 'f8'] seq_out = seq_in seq_in_featrues = [] for si in seq_in: features = code2features(si) seq_in_featrues.append(features) for i in range(pred_count): sample_in = np.array(seq_in_featrues) sample_in = np.reshape(sample_in, (1, 4, 2)) # 샘플 수, 타입스텝 수, 속성 수 pred_out = model.predict(sample_in) idx = np.argmax(pred_out) seq_out.append(idx2code[idx]) features = code2features(idx2code[idx]) seq_in_featrues.append(features) seq_in_featrues.pop(0) model.reset_states() print("full song prediction : ", seq_out) # In[ ]:
tensorflow_keras_lstm_stateful_2_load.py | (6,609 바이트) |
#!/usr/bin/env python # coding: utf-8 # In[1]: # 0. 사용할 패키지 불러오기 import numpy as np import tensorflow as tf from tensorflow import keras from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense, LSTM from keras.utils import np_utils # 랜덤시드 고정시키기 np.random.seed(5) # In[2]: # 가중치 저장 파일 checkpoint_path = "output/checkpoint/weight.ckpt" # 텐서보드 저장 경로(디렉토리) tensorboard_path = "output/tensorboard" # 모델 저장 파일 model_path = "output/model.h5" # 손실 이력 클래스 정의 class LossHistory(keras.callbacks.Callback): def init(self): self.losses = [] def on_epoch_end(self, batch, logs={}): self.losses.append(logs.get('loss')) # 데이터셋 생성 함수 def seq2dataset(seq, window_size): dataset_X = [] dataset_Y = [] for i in range(len(seq)-window_size): # subset = [['g8', 'e8', 'e4', 'f8', 'd8'], # ['e8', 'e4', 'f8', 'd8', 'd4']...] subset = seq[i:(i+window_size+1)] for si in range(len(subset)-1): # subset[si] 에는 g8이 features = code2features(subset[si]) # feature 에는 [0.666, 1]이 dataset_X.append(features) dataset_Y.append([code2idx[subset[window_size]]]) return np.array(dataset_X), np.array(dataset_Y) # 속성 변환 함수 def code2features(code): features = [] features.append(code2scale[code[0]]/float(max_scale_value)) features.append(code2length[code[1]]) return features # In[3]: # 1. 데이터 준비하기 # 코드 사전 정의 # 도레미파솔라시도 이기 때문에 0 ~ 6까지 code2scale = {'c':0, 'd':1, 'e':2, 'f':3, 'g':4, 'a':5, 'b':6} code2length = {'4':0, '8':1} code2idx = {'c4':0, 'd4':1, 'e4':2, 'f4':3, 'g4':4, 'a4':5, 'b4':6, 'c8':7, 'd8':8, 'e8':9, 'f8':10, 'g8':11, 'a8':12, 'b8':13} idx2code = {0:'c4', 1:'d4', 2:'e4', 3:'f4', 4:'g4', 5:'a4', 6:'b4', 7:'c8', 8:'d8', 9:'e8', 10:'f8', 11:'g8', 12:'a8', 13:'b8'} # 최대 6까지 나옴 max_scale_value = 6.0 # 시퀀스 데이터 정의 seq = ['g8', 'e8', 'e4', 'f8', 'd8', 'd4', 'c8', 'd8', 'e8', 'f8', 'g8', 'g8', 'g4', 'g8', 'e8', 'e8', 'e8', 'f8', 'd8', 'd4', 'c8', 'e8', 'g8', 'g8', 'e8', 'e8', 'e4', 'd8', 'd8', 'd8', 'd8', 'd8', 'e8', 'f4', 'e8', 'e8', 'e8', 'e8', 'e8', 'f8', 'g4', 'g8', 'e8', 'e4', 'f8', 'd8', 'd4', 'c8', 'e8', 'g8', 'g8', 'e8', 'e8', 'e4'] # In[4]: # 2. 데이터셋 생성하기 # 여기서 windows_size =4 부분은 LSTM 에 들어가는 timestep = 4 와 동일하다. # 4개의 데이터 추이를 보고 다음의 것을 추론하는 형태로 구성할 것이다. x_train, y_train = seq2dataset(seq, window_size = 4) # x_train # array([[0.66666667, 1. ], # [0.33333333, 1. ], # [0.33333333, 0. ], # [0.5 , 1. ], # y_train # array([[ 8], # [ 1], # [ 7], # [ 8], # In[5]: # 입력을 (샘플 수, 타임스텝, 특성 수)로 형태 변환 x_train = np.reshape(x_train, (50, 4, 2)) # array([[[0.66666667, 1. ], # [0.33333333, 1. ], # [0.33333333, 0. ], # [0.5 , 1. ]], # # [[0.33333333, 1. ], # [0.33333333, 0. ], # [0.5 , 1. ], # [0.16666667, 1. ]], # In[6]: # 라벨값에 대한 one-hot 인코딩 수행 # [8] -> [0,0,0,0,0,0,0,0,1,0,0,0] # [1] -> [0,1,0,0,0,0,0,0,0,0,0,0] # 최대값은 12이므로 출력되는 배열의 개수가 12개임 y_train = np_utils.to_categorical(y_train) # array([[0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0.], # [0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], # In[7]: one_hot_vec_size = y_train.shape[1] #print("one hot encoding vector size is ", one_hot_vec_size) # numpy 에서 행이 2이고 열이 3인 2차원 배열에서 rank는 2 이고, shape는 (2, 3) # In[8]: # 3. 모델 구성하기 # 상태유지 모델(stateful=True) 에서, 배치 크기 = 1, 타임스탭 = 4, 속성개수(입력 값의 개수) = 2 # LSTM에서 상태유지모델에서 배치크기 1의 의미는, 동시에 상태를 유지할 개수다. 여기서는 곡 1개만 학습할것이라 1로 했다. 가중치는 공유된다. # LSTM에서 상태를유지하지않는 모델에서 배치크기는 상태를 유지할 개수. 1이면 상태를 유지하지 않는다. def create_LSTM_model(): model = Sequential() # 아래에서 128 은 특별히 의미가 없다. ^^ model.add(LSTM(128, batch_input_shape = (1, 4, 2), stateful=True)) model.add(Dense(one_hot_vec_size, activation='softmax')) return model def create_StackedLSTM_model(): model = Sequential() model.add(LSTM(32, return_sequences=True, stateful=True,batch_input_shape=(1, 4, 2))) model.add(LSTM(32, return_sequences=True, stateful=True)) model.add(LSTM(32, stateful=True)) model.add(Dense(one_hot_vec_size, activation='softmax')) return model model = create_StackedLSTM_model() model.summary() # In[9]: # 4. 모델 학습과정 설정하기 model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy']) # In[10]: # 4. 가중치 로드하기 model.load_weights(checkpoint_path) loss, acc = model.evaluate(x_train, y_train, batch_size=1) print("복원된 모델의 정확도: {:5.2f}%".format(100*acc)) # In[11]: # 8. 모델 사용하기 pred_count = 50 # 최대 예측 개수 정의 # 한 스텝 예측 seq_out = ['g8', 'e8', 'e4', 'f8'] pred_out = model.predict(x_train, batch_size=1) for i in range(pred_count): idx = np.argmax(pred_out[i]) # one-hot 인코딩을 인덱스 값으로 변환 seq_out.append(idx2code[idx]) # seq_out는 최종 악보이므로 인덱스 값을 코드로 변환하여 저장 print("one step prediction : ", seq_out) model.reset_states() # 곡 전체 예측 seq_in = ['g8', 'e8', 'e4', 'f8'] seq_out = seq_in seq_in_featrues = [] for si in seq_in: features = code2features(si) seq_in_featrues.append(features) for i in range(pred_count): sample_in = np.array(seq_in_featrues) sample_in = np.reshape(sample_in, (1, 4, 2)) # 샘플 수, 타입스텝 수, 속성 수 pred_out = model.predict(sample_in) idx = np.argmax(pred_out) seq_out.append(idx2code[idx]) features = code2features(idx2code[idx]) seq_in_featrues.append(features) seq_in_featrues.pop(0) model.reset_states() print("full song prediction : ", seq_out)
tensorflow_keras_lstm_stateful_2_modelload.py | (5,376 바이트) |
#!/usr/bin/env python # coding: utf-8 # In[1]: # 0. 사용할 패키지 불러오기 import numpy as np import tensorflow as tf from tensorflow import keras from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense, LSTM from keras.utils import np_utils # 랜덤시드 고정시키기 np.random.seed(5) # In[2]: # 가중치 저장 파일 checkpoint_path = "output/checkpoint/weight.ckpt" # 텐서보드 저장 경로(디렉토리) tensorboard_path = "output/tensorboard" # 모델 저장 파일 model_path = "output/model.h5" # 손실 이력 클래스 정의 class LossHistory(keras.callbacks.Callback): def init(self): self.losses = [] def on_epoch_end(self, batch, logs={}): self.losses.append(logs.get('loss')) # 데이터셋 생성 함수 def seq2dataset(seq, window_size): dataset_X = [] dataset_Y = [] for i in range(len(seq)-window_size): # subset = [['g8', 'e8', 'e4', 'f8', 'd8'], # ['e8', 'e4', 'f8', 'd8', 'd4']...] subset = seq[i:(i+window_size+1)] for si in range(len(subset)-1): # subset[si] 에는 g8이 features = code2features(subset[si]) # feature 에는 [0.666, 1]이 dataset_X.append(features) dataset_Y.append([code2idx[subset[window_size]]]) return np.array(dataset_X), np.array(dataset_Y) # 속성 변환 함수 def code2features(code): features = [] features.append(code2scale[code[0]]/float(max_scale_value)) features.append(code2length[code[1]]) return features # In[3]: # 1. 데이터 준비하기 # 코드 사전 정의 # 도레미파솔라시도 이기 때문에 0 ~ 6까지 code2scale = {'c':0, 'd':1, 'e':2, 'f':3, 'g':4, 'a':5, 'b':6} code2length = {'4':0, '8':1} code2idx = {'c4':0, 'd4':1, 'e4':2, 'f4':3, 'g4':4, 'a4':5, 'b4':6, 'c8':7, 'd8':8, 'e8':9, 'f8':10, 'g8':11, 'a8':12, 'b8':13} idx2code = {0:'c4', 1:'d4', 2:'e4', 3:'f4', 4:'g4', 5:'a4', 6:'b4', 7:'c8', 8:'d8', 9:'e8', 10:'f8', 11:'g8', 12:'a8', 13:'b8'} # 최대 6까지 나옴 max_scale_value = 6.0 # 시퀀스 데이터 정의 seq = ['g8', 'e8', 'e4', 'f8', 'd8', 'd4', 'c8', 'd8', 'e8', 'f8', 'g8', 'g8', 'g4', 'g8', 'e8', 'e8', 'e8', 'f8', 'd8', 'd4', 'c8', 'e8', 'g8', 'g8', 'e8', 'e8', 'e4', 'd8', 'd8', 'd8', 'd8', 'd8', 'e8', 'f4', 'e8', 'e8', 'e8', 'e8', 'e8', 'f8', 'g4', 'g8', 'e8', 'e4', 'f8', 'd8', 'd4', 'c8', 'e8', 'g8', 'g8', 'e8', 'e8', 'e4'] # In[4]: # 2. 데이터셋 생성하기 # 여기서 windows_size =4 부분은 LSTM 에 들어가는 timestep = 4 와 동일하다. # 4개의 데이터 추이를 보고 다음의 것을 추론하는 형태로 구성할 것이다. x_train, y_train = seq2dataset(seq, window_size = 4) # x_train # array([[0.66666667, 1. ], # [0.33333333, 1. ], # [0.33333333, 0. ], # [0.5 , 1. ], # y_train # array([[ 8], # [ 1], # [ 7], # [ 8], # In[5]: # 입력을 (샘플 수, 타임스텝, 특성 수)로 형태 변환 x_train = np.reshape(x_train, (50, 4, 2)) # array([[[0.66666667, 1. ], # [0.33333333, 1. ], # [0.33333333, 0. ], # [0.5 , 1. ]], # # [[0.33333333, 1. ], # [0.33333333, 0. ], # [0.5 , 1. ], # [0.16666667, 1. ]], # In[6]: # 라벨값에 대한 one-hot 인코딩 수행 # [8] -> [0,0,0,0,0,0,0,0,1,0,0,0] # [1] -> [0,1,0,0,0,0,0,0,0,0,0,0] # 최대값은 12이므로 출력되는 배열의 개수가 12개임 y_train = np_utils.to_categorical(y_train) # array([[0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., 0.], # [0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], # In[7]: one_hot_vec_size = y_train.shape[1] #print("one hot encoding vector size is ", one_hot_vec_size) # numpy 에서 행이 2이고 열이 3인 2차원 배열에서 rank는 2 이고, shape는 (2, 3) # In[8]: # 3. 모델 및 가중치 로드하기 model = keras.models.load_model(model_path) model.summary() loss, acc = model.evaluate(x_train, y_train, batch_size=1) print("복원된 모델의 정확도: {:5.2f}%".format(100*acc)) # In[9]: # 8. 모델 사용하기 pred_count = 50 # 최대 예측 개수 정의 # 한 스텝 예측 seq_out = ['g8', 'e8', 'e4', 'f8'] pred_out = model.predict(x_train, batch_size=1) for i in range(pred_count): idx = np.argmax(pred_out[i]) # one-hot 인코딩을 인덱스 값으로 변환 seq_out.append(idx2code[idx]) # seq_out는 최종 악보이므로 인덱스 값을 코드로 변환하여 저장 print("one step prediction : ", seq_out) model.reset_states() # 곡 전체 예측 seq_in = ['g8', 'e8', 'e4', 'f8'] seq_out = seq_in seq_in_featrues = [] for si in seq_in: features = code2features(si) seq_in_featrues.append(features) for i in range(pred_count): sample_in = np.array(seq_in_featrues) sample_in = np.reshape(sample_in, (1, 4, 2)) # 샘플 수, 타입스텝 수, 속성 수 pred_out = model.predict(sample_in) idx = np.argmax(pred_out) seq_out.append(idx2code[idx]) features = code2features(idx2code[idx]) seq_in_featrues.append(features) seq_in_featrues.pop(0) model.reset_states() print("full song prediction : ", seq_out)
RSS ATOM XHTML 5 CSS3 |
Copyright © 2004-2024 Jo HoSeok. All rights reserved. |