Browse Source

업데이트 'README.md'

Hio-Been Han 3 years ago
parent
commit
a47e8a73ad
1 changed files with 592 additions and 2 deletions
  1. 592 2
      README.md

+ 592 - 2
README.md

@@ -1,3 +1,593 @@
-# Tutorial_of_video_tracking_JEELAB
+# 애들 교육용으로 만든 자료
+아래 링크로 COLAB 접속하셔요~~~~~~~~~~~~
 
-애들 교육용
+Visit here: https://colab.research.google.com/drive/1UWqUtZdTbFKBWgcSD9x-LhjfTF9nUOW-?usp=sharing
+
+# Jeelab mouse body tracking example using U-Net
+
+written by 한효빈, HioBeen Han - hiobeen.han@kaist.ac.kr
+
+JEELAB, KIST
+
+version 2021-04-03a
+
+Visit here: https://colab.research.google.com/drive/1UWqUtZdTbFKBWgcSD9x-LhjfTF9nUOW-?usp=sharing
+
+
+# Part 1. 환경 설정 & 데이터 불러오기
+
+
+```python
+""" SET ENVIRONMENT """
+# Drive mount
+from google.colab import auth,drive,files
+drive.mount('/content/gdrive')
+
+""" Load modules """
+import os, cv2
+import numpy as np
+from glob import glob
+from matplotlib import pyplot as plt; from matplotlib import cm; plt.style.use('ggplot')
+# Download U-net
+!pip install git+https://github.com/karolzak/keras-unet
+from keras_unet.models import custom_unet
+```
+
+    Mounted at /content/gdrive
+    Collecting git+https://github.com/karolzak/keras-unet
+      Cloning https://github.com/karolzak/keras-unet to /tmp/pip-req-build-f1bk3r61
+      Running command git clone -q https://github.com/karolzak/keras-unet /tmp/pip-req-build-f1bk3r61
+    Building wheels for collected packages: keras-unet
+      Building wheel for keras-unet (setup.py) ... [?25l[?25hdone
+      Created wheel for keras-unet: filename=keras_unet-0.1.2-cp37-none-any.whl size=16992 sha256=5fababfae4ceea970f38f08de8905ecaa2a730a742f19c8c2d23559848a6bb2c
+      Stored in directory: /tmp/pip-ephem-wheel-cache-6fwpnftv/wheels/b3/3a/85/c3df1c96b5d83dcd2c09b634e72a98cafcf12a52501ac5cd77
+    Successfully built keras-unet
+    Installing collected packages: keras-unet
+    Successfully installed keras-unet-0.1.2
+    -----------------------------------------
+    keras-unet init: TF version is >= 2.0.0 - using `tf.keras` instead of `Keras`
+    -----------------------------------------
+
+
+
+```python
+""" Google Drive 경로 파일에 되었는지 확인하기 """
+# 시스템(리눅스) 명령어 사용은 커맨드 앞에 느낌표(!)를 붙이고 작성
+# ls -> listdir의 약자로, directory 내 파일들을 listing 하는 기능을 수행함
+#
+!ls gdrive/MyDrive/'Colab Notebooks'/tutorial_data/
+```
+
+    frames.zip  trainset_added.zip	trainset.zip
+
+
+
+```python
+""" 구글드라이브에 올라간 데이터를 Colab 가상환경으로 복사하기 """
+# cp 명령어는 copy의 약자로, cp A B라고 쓰면 A를 B 경로로 복사함.
+# cp -r A B 라고 쓰면, A라는 디렉토리 내 파일들을 통째로 B에 복사함.
+# 이 예시에서는 tutorial_data/ 폴더 내의 파일들을 content/ 안으로 옮길 것.
+#
+!cp -r gdrive/MyDrive/'Colab Notebooks'/tutorial_data/ content/
+```
+
+
+```python
+""" Zip 파일들 압축 해제하기 """
+!unzip content/trainset.zip -d content/
+!unzip content/frames.zip -d content/
+```
+
+    Archive:  content/trainset.zip
+      inflating: content/data/trainset/.DS_Store  
+      inflating: content/data/trainset/frame-000007-sample_04-from1024x1024-to448x448.jpg  
+      inflating: content/data/trainset/frame-000024-sample_02-from1024x1024-to448x448.jpg  
+      inflating: content/data/frames/sample_02/frame-000223-sample_02-from1024x1024-to448x448.jpg  
+      inflating: content/data/frames/sample_02/frame-000224-sample_02-from1024x1024-to448x448.jpg  
+      inflating: content/data/frames/sample_02/frame-000225-sample_02-from1024x1024-to448x448.jpg  
+
+
+```python
+""" 이미지 데이터를 Numpy array로 읽어오기 """
+data_dir = 'content/data/trainset/'
+filename_x = glob( data_dir+'frame*.jpg' ); filename_x.sort()
+filename_y = glob( data_dir+'mask*.jpg' ); filename_y.sort()
+
+n_files = len( filename_x )
+shape = (448, 448)
+x_raw = np.zeros(shape=(n_files,shape[0],shape[1]), dtype='float32')
+y_raw = np.zeros(shape=(n_files,shape[0],shape[1]), dtype='bool')
+for fileIdx in range(n_files):
+  x_raw[fileIdx,] = cv2.imread( filename_x[fileIdx] )[:,:,0]
+  y_raw[fileIdx,] = cv2.imread( filename_y[fileIdx] )[:,:,0]>0
+```
+
+
+```python
+"""  Dataset augmentation """
+#
+# 이미지를 가로/세로/가로세로 반전시켜서 4배르 뻥튀기하기
+#
+x_aug = np.zeros( (x_raw.shape[0]*4, x_raw.shape[1], x_raw.shape[2] ), dtype='float32')
+y_aug = np.zeros( (y_raw.shape[0]*4, y_raw.shape[1], y_raw.shape[2] ), dtype='bool')
+
+imgIdx = 0
+for fileIdx in range(x_raw.shape[0]):
+  frame, mask = x_raw[fileIdx,], y_raw[fileIdx,]
+  frame = frame/255
+
+  # Appending original data
+  x_aug[imgIdx,:,:] = frame
+  y_aug[imgIdx,:,:] = mask
+  imgIdx+=1
+
+  # Flip x-axis
+  x_aug[imgIdx,:,:] = frame[::-1,:]
+  y_aug[imgIdx,:,:] = mask[::-1,:]
+  imgIdx+=1
+
+  # Flip y-axis
+  x_aug[imgIdx,:,:] = frame[:,::-1]
+  y_aug[imgIdx,:,:] = mask[:,::-1]
+  imgIdx+=1
+
+  # Flip x & y-axis
+  x_aug[imgIdx,:,:] = frame[::-1,::-1]
+  y_aug[imgIdx,:,:] = mask[::-1,::-1]
+  imgIdx+=1
+
+print(x_aug.shape)
+
+```
+
+    (400, 448, 448)
+
+
+
+```python
+""" 잘 import 되었는지 확인하기 위한 visualization """
+plt.style.use('ggplot')
+np.random.seed(20210404)
+for fIdx in np.random.randint(0,x_aug.shape[0],3):
+  print('Image number %s'%fIdx )
+  plt.figure(figsize=(8,4))
+  plt.subplot(121); plt.imshow(x_aug[fIdx,:,:],  cmap=cm.gray); plt.axis('off')
+  plt.title('Input (X)')
+  plt.subplot(122); plt.imshow(y_aug[fIdx,:,:], cmap=cm.gray); plt.axis('off')
+  plt.title('Mask (Y)')
+  plt.show()
+```
+
+    img idx = 182
+
+
+
+![png](readme_figures/output_8_1.png)
+
+
+    img idx = 239
+
+
+
+![png](readme_figures/output_8_3.png)
+
+
+    img idx = 306
+
+
+
+![png](readme_figures/output_8_5.png)
+
+
+#Part 2. CNN 모델 빌드 & 훈련 진행하기
+
+
+세부적인 파라미터 튜닝 필요
+
+
+1.   use_batch_norm => 각 레이어의 입/출력을 0-1 사이로 표준화.
+2.   filters => 필터 사이즈 (클수록 sparse하게 봄).
+3.   dropout => 랜덤하게 끊을 커넥션의 비율 (0-1).
+4.   output_activation => 활성 함수의 종류 (*relu*, *sigmoid*, *tanh*, etc.).
+5.   optimizer => *adam*으로 learning_rate = 1e-04 정도면 적당히 빨리 배움
+
+
+
+
+```python
+""" Train/Test 세트 나누기 """
+randseed = 20210404
+from sklearn.model_selection import train_test_split
+x_train, x_test, y_train, y_test = train_test_split(
+    np.expand_dims( x_aug, 3 ), np.expand_dims( y_aug, 3 ),
+    test_size=0.1, random_state=np.random.seed(randseed))
+
+print('Training set size => (%d,%d,%d,%d)'%x_train.shape)
+print('   Test set size => (%d,%d,%d,%d)'%x_test.shape)
+```
+
+    Training set size => (360,448,448,1)
+       Test set size => (40,448,448,1)
+
+
+
+```python
+""" CNN 네트워크 빌드하기 """
+from keras.callbacks import History;
+history = History(); histories = []
+from keras import backend as K; import gc
+gc.collect(); K.clear_session()
+from keras import optimizers
+
+model = custom_unet(input_shape=(shape[0],shape[1],1),
+    use_batch_norm=1, num_classes=y_train.shape[-1],
+    filters=16, dropout=0.20, output_activation='sigmoid')
+metric = 'binary_crossentropy'
+model.compile(optimizer = 'Adam', loss = metric, metrics = [metric])
+#model.summary()
+```
+
+
+```python
+""" Training """
+fitIdx, nFit = 1, 100
+while fitIdx < nFit:
+  history = model.fit(x_train,y_train,epochs=1,verbose=2,batch_size=32, validation_data=(x_test,y_test) )
+
+  # Sample visualization
+  if np.mod(fitIdx,10)==1:
+    print('Epoch => [~%3d] / %3d'%((fitIdx), nFit))
+    pred = model.predict(x_test)
+    for predIdx in range(3):
+      plt.figure(figsize=(6,3))
+      plt.subplot(1,3,1); plt.imshow(x_test[predIdx,:,:,0], cmap=cm.gray); plt.axis('off'); plt.title('input X')
+      plt.subplot(1,3,2); plt.imshow(y_test[predIdx,:,:,0], cmap=cm.gray); plt.axis('off'); plt.title('actual Y')
+      plt.subplot(1,3,3); plt.imshow(pred[predIdx,:,:,0], cmap=cm.gray); plt.axis('off'); plt.title('predicted Y')
+      plt.clim(0,1); plt.show()
+  fitIdx += 1
+
+```
+
+    12/12 - 43s - loss: 0.7374 - binary_crossentropy: 0.7374 - val_loss: 0.6141 - val_binary_crossentropy: 0.6141
+    Epoch => [~  1] / 100
+
+
+
+![png](readme_figures/output_12_1.png)
+
+
+
+![png](readme_figures/output_12_2.png)
+
+
+
+![png](readme_figures/output_12_3.png)
+
+
+    12/12 - 6s - loss: 0.6564 - binary_crossentropy: 0.6564 - val_loss: 0.3968 - val_binary_crossentropy: 0.3968
+    12/12 - 6s - loss: 0.6179 - binary_crossentropy: 0.6179 - val_loss: 0.4370 - val_binary_crossentropy: 0.4370
+    12/12 - 6s - loss: 0.5834 - binary_crossentropy: 0.5834 - val_loss: 0.4926 - val_binary_crossentropy: 0.4926
+    12/12 - 6s - loss: 0.5477 - binary_crossentropy: 0.5477 - val_loss: 0.4957 - val_binary_crossentropy: 0.4957
+    12/12 - 6s - loss: 0.5095 - binary_crossentropy: 0.5095 - val_loss: 1.3305 - val_binary_crossentropy: 1.3305
+    12/12 - 6s - loss: 0.4682 - binary_crossentropy: 0.4682 - val_loss: 0.3847 - val_binary_crossentropy: 0.3847
+    12/12 - 6s - loss: 0.4213 - binary_crossentropy: 0.4213 - val_loss: 0.7654 - val_binary_crossentropy: 0.7654
+    12/12 - 6s - loss: 0.3729 - binary_crossentropy: 0.3729 - val_loss: 0.2787 - val_binary_crossentropy: 0.2787
+    12/12 - 6s - loss: 0.3347 - binary_crossentropy: 0.3347 - val_loss: 0.7169 - val_binary_crossentropy: 0.7169
+    12/12 - 6s - loss: 0.3018 - binary_crossentropy: 0.3018 - val_loss: 0.3398 - val_binary_crossentropy: 0.3398
+    Epoch => [~ 11] / 100
+
+
+
+![png](readme_figures/output_12_5.png)
+
+
+
+![png](readme_figures/output_12_6.png)
+
+
+
+![png](readme_figures/output_12_7.png)
+
+
+    12/12 - 6s - loss: 0.2703 - binary_crossentropy: 0.2703 - val_loss: 0.1813 - val_binary_crossentropy: 0.1813
+    12/12 - 6s - loss: 0.2422 - binary_crossentropy: 0.2422 - val_loss: 0.1555 - val_binary_crossentropy: 0.1555
+    12/12 - 6s - loss: 0.2183 - binary_crossentropy: 0.2183 - val_loss: 0.1343 - val_binary_crossentropy: 0.1343
+    12/12 - 6s - loss: 0.1976 - binary_crossentropy: 0.1976 - val_loss: 0.1250 - val_binary_crossentropy: 0.1250
+    12/12 - 6s - loss: 0.1786 - binary_crossentropy: 0.1786 - val_loss: 0.1164 - val_binary_crossentropy: 0.1164
+    12/12 - 6s - loss: 0.1608 - binary_crossentropy: 0.1608 - val_loss: 0.1065 - val_binary_crossentropy: 0.1065
+    12/12 - 6s - loss: 0.1459 - binary_crossentropy: 0.1459 - val_loss: 0.1003 - val_binary_crossentropy: 0.1003
+    12/12 - 6s - loss: 0.1328 - binary_crossentropy: 0.1328 - val_loss: 0.0941 - val_binary_crossentropy: 0.0941
+    12/12 - 6s - loss: 0.1207 - binary_crossentropy: 0.1207 - val_loss: 0.0890 - val_binary_crossentropy: 0.0890
+    12/12 - 6s - loss: 0.1116 - binary_crossentropy: 0.1116 - val_loss: 0.0861 - val_binary_crossentropy: 0.0861
+    Epoch => [~ 21] / 100
+
+
+
+![png](readme_figures/output_12_9.png)
+
+
+
+![png](readme_figures/output_12_10.png)
+
+
+
+![png](readme_figures/output_12_11.png)
+
+
+    12/12 - 6s - loss: 0.1023 - binary_crossentropy: 0.1023 - val_loss: 0.0797 - val_binary_crossentropy: 0.0797
+    12/12 - 6s - loss: 0.0933 - binary_crossentropy: 0.0933 - val_loss: 0.0759 - val_binary_crossentropy: 0.0759
+    12/12 - 6s - loss: 0.0845 - binary_crossentropy: 0.0845 - val_loss: 0.0719 - val_binary_crossentropy: 0.0719
+    12/12 - 6s - loss: 0.0775 - binary_crossentropy: 0.0775 - val_loss: 0.0654 - val_binary_crossentropy: 0.0654
+    12/12 - 6s - loss: 0.0715 - binary_crossentropy: 0.0715 - val_loss: 0.0627 - val_binary_crossentropy: 0.0627
+    12/12 - 6s - loss: 0.0663 - binary_crossentropy: 0.0663 - val_loss: 0.0583 - val_binary_crossentropy: 0.0583
+    12/12 - 6s - loss: 0.0616 - binary_crossentropy: 0.0616 - val_loss: 0.0623 - val_binary_crossentropy: 0.0623
+    12/12 - 6s - loss: 0.0571 - binary_crossentropy: 0.0571 - val_loss: 0.0571 - val_binary_crossentropy: 0.0571
+    12/12 - 6s - loss: 0.0531 - binary_crossentropy: 0.0531 - val_loss: 0.0475 - val_binary_crossentropy: 0.0475
+    12/12 - 6s - loss: 0.0503 - binary_crossentropy: 0.0503 - val_loss: 0.0443 - val_binary_crossentropy: 0.0443
+    Epoch => [~ 31] / 100
+
+
+
+![png](readme_figures/output_12_13.png)
+
+
+
+![png](readme_figures/utput_12_14.png)
+
+
+
+![png](readme_figures/output_12_15.png)
+
+
+    12/12 - 6s - loss: 0.0469 - binary_crossentropy: 0.0469 - val_loss: 0.0424 - val_binary_crossentropy: 0.0424
+    12/12 - 6s - loss: 0.0438 - binary_crossentropy: 0.0438 - val_loss: 0.0411 - val_binary_crossentropy: 0.0411
+    12/12 - 6s - loss: 0.0411 - binary_crossentropy: 0.0411 - val_loss: 0.0386 - val_binary_crossentropy: 0.0386
+    12/12 - 6s - loss: 0.0388 - binary_crossentropy: 0.0388 - val_loss: 0.0358 - val_binary_crossentropy: 0.0358
+    12/12 - 6s - loss: 0.0368 - binary_crossentropy: 0.0368 - val_loss: 0.0337 - val_binary_crossentropy: 0.0337
+    12/12 - 6s - loss: 0.0348 - binary_crossentropy: 0.0348 - val_loss: 0.0328 - val_binary_crossentropy: 0.0328
+    12/12 - 6s - loss: 0.0330 - binary_crossentropy: 0.0330 - val_loss: 0.0318 - val_binary_crossentropy: 0.0318
+    12/12 - 6s - loss: 0.0312 - binary_crossentropy: 0.0312 - val_loss: 0.0310 - val_binary_crossentropy: 0.0310
+    12/12 - 6s - loss: 0.0297 - binary_crossentropy: 0.0297 - val_loss: 0.0295 - val_binary_crossentropy: 0.0295
+    12/12 - 6s - loss: 0.0283 - binary_crossentropy: 0.0283 - val_loss: 0.0289 - val_binary_crossentropy: 0.0289
+    Epoch => [~ 41] / 100
+
+
+
+![png](readme_figures/output_12_17.png)
+
+
+
+![png](readme_figures/output_12_18.png)
+
+
+
+![png](readme_figures/output_12_19.png)
+
+
+    12/12 - 6s - loss: 0.0271 - binary_crossentropy: 0.0271 - val_loss: 0.0281 - val_binary_crossentropy: 0.0281
+    12/12 - 6s - loss: 0.0259 - binary_crossentropy: 0.0259 - val_loss: 0.0264 - val_binary_crossentropy: 0.0264
+    12/12 - 6s - loss: 0.0249 - binary_crossentropy: 0.0249 - val_loss: 0.0270 - val_binary_crossentropy: 0.0270
+    12/12 - 6s - loss: 0.0238 - binary_crossentropy: 0.0238 - val_loss: 0.0248 - val_binary_crossentropy: 0.0248
+    12/12 - 6s - loss: 0.0229 - binary_crossentropy: 0.0229 - val_loss: 0.0238 - val_binary_crossentropy: 0.0238
+    12/12 - 6s - loss: 0.0219 - binary_crossentropy: 0.0219 - val_loss: 0.0233 - val_binary_crossentropy: 0.0233
+    12/12 - 6s - loss: 0.0212 - binary_crossentropy: 0.0212 - val_loss: 0.0233 - val_binary_crossentropy: 0.0233
+    12/12 - 6s - loss: 0.0205 - binary_crossentropy: 0.0205 - val_loss: 0.0219 - val_binary_crossentropy: 0.0219
+    12/12 - 6s - loss: 0.0197 - binary_crossentropy: 0.0197 - val_loss: 0.0202 - val_binary_crossentropy: 0.0202
+    12/12 - 6s - loss: 0.0190 - binary_crossentropy: 0.0190 - val_loss: 0.0209 - val_binary_crossentropy: 0.0209
+    Epoch => [~ 51] / 100
+
+
+
+![png](readme_figures/output_12_21.png)
+
+
+
+![png](readme_figures/output_12_22.png)
+
+
+
+![png](readme_figures/output_12_23.png)
+
+
+    12/12 - 6s - loss: 0.0182 - binary_crossentropy: 0.0182 - val_loss: 0.0207 - val_binary_crossentropy: 0.0207
+    12/12 - 6s - loss: 0.0178 - binary_crossentropy: 0.0178 - val_loss: 0.0209 - val_binary_crossentropy: 0.0209
+    12/12 - 6s - loss: 0.0173 - binary_crossentropy: 0.0173 - val_loss: 0.0194 - val_binary_crossentropy: 0.0194
+    12/12 - 6s - loss: 0.0166 - binary_crossentropy: 0.0166 - val_loss: 0.0189 - val_binary_crossentropy: 0.0189
+    12/12 - 6s - loss: 0.0161 - binary_crossentropy: 0.0161 - val_loss: 0.0195 - val_binary_crossentropy: 0.0195
+    12/12 - 6s - loss: 0.0156 - binary_crossentropy: 0.0156 - val_loss: 0.0186 - val_binary_crossentropy: 0.0186
+    12/12 - 6s - loss: 0.0153 - binary_crossentropy: 0.0153 - val_loss: 0.0175 - val_binary_crossentropy: 0.0175
+    12/12 - 6s - loss: 0.0149 - binary_crossentropy: 0.0149 - val_loss: 0.0162 - val_binary_crossentropy: 0.0162
+    12/12 - 6s - loss: 0.0149 - binary_crossentropy: 0.0149 - val_loss: 0.0157 - val_binary_crossentropy: 0.0157
+    12/12 - 6s - loss: 0.0149 - binary_crossentropy: 0.0149 - val_loss: 0.0153 - val_binary_crossentropy: 0.0153
+    Epoch => [~ 61] / 100
+
+
+
+![png](readme_figures/output_12_25.png)
+
+
+
+![png](readme_figures/output_12_26.png)
+
+
+
+![png](readme_figures/output_12_27.png)
+
+
+    12/12 - 6s - loss: 0.0144 - binary_crossentropy: 0.0144 - val_loss: 0.0177 - val_binary_crossentropy: 0.0177
+    12/12 - 6s - loss: 0.0140 - binary_crossentropy: 0.0140 - val_loss: 0.0153 - val_binary_crossentropy: 0.0153
+    12/12 - 6s - loss: 0.0135 - binary_crossentropy: 0.0135 - val_loss: 0.0150 - val_binary_crossentropy: 0.0150
+    12/12 - 6s - loss: 0.0129 - binary_crossentropy: 0.0129 - val_loss: 0.0162 - val_binary_crossentropy: 0.0162
+    12/12 - 6s - loss: 0.0126 - binary_crossentropy: 0.0126 - val_loss: 0.0155 - val_binary_crossentropy: 0.0155
+    12/12 - 6s - loss: 0.0122 - binary_crossentropy: 0.0122 - val_loss: 0.0156 - val_binary_crossentropy: 0.0156
+    12/12 - 6s - loss: 0.0120 - binary_crossentropy: 0.0120 - val_loss: 0.0159 - val_binary_crossentropy: 0.0159
+    12/12 - 6s - loss: 0.0118 - binary_crossentropy: 0.0118 - val_loss: 0.0149 - val_binary_crossentropy: 0.0149
+    12/12 - 6s - loss: 0.0114 - binary_crossentropy: 0.0114 - val_loss: 0.0148 - val_binary_crossentropy: 0.0148
+    12/12 - 6s - loss: 0.0111 - binary_crossentropy: 0.0111 - val_loss: 0.0150 - val_binary_crossentropy: 0.0150
+    Epoch => [~ 71] / 100
+
+
+
+![png](readme_figures/readme_figures/output_12_29.png)
+
+
+
+![png](readme_figures/output_12_30.png)
+
+
+
+![png](readme_figures/output_12_31.png)
+
+
+    12/12 - 6s - loss: 0.0109 - binary_crossentropy: 0.0109 - val_loss: 0.0155 - val_binary_crossentropy: 0.0155
+    12/12 - 6s - loss: 0.0107 - binary_crossentropy: 0.0107 - val_loss: 0.0145 - val_binary_crossentropy: 0.0145
+    12/12 - 6s - loss: 0.0105 - binary_crossentropy: 0.0105 - val_loss: 0.0149 - val_binary_crossentropy: 0.0149
+    12/12 - 6s - loss: 0.0103 - binary_crossentropy: 0.0103 - val_loss: 0.0151 - val_binary_crossentropy: 0.0151
+    12/12 - 6s - loss: 0.0101 - binary_crossentropy: 0.0101 - val_loss: 0.0138 - val_binary_crossentropy: 0.0138
+    12/12 - 6s - loss: 0.0099 - binary_crossentropy: 0.0099 - val_loss: 0.0143 - val_binary_crossentropy: 0.0143
+    12/12 - 6s - loss: 0.0098 - binary_crossentropy: 0.0098 - val_loss: 0.0157 - val_binary_crossentropy: 0.0157
+    12/12 - 6s - loss: 0.0097 - binary_crossentropy: 0.0097 - val_loss: 0.0145 - val_binary_crossentropy: 0.0145
+    12/12 - 6s - loss: 0.0094 - binary_crossentropy: 0.0094 - val_loss: 0.0157 - val_binary_crossentropy: 0.0157
+    12/12 - 6s - loss: 0.0093 - binary_crossentropy: 0.0093 - val_loss: 0.0153 - val_binary_crossentropy: 0.0153
+    Epoch => [~ 81] / 100
+
+
+
+![png](readme_figures/output_12_33.png)
+
+
+
+![png](readme_figures/output_12_34.png)
+
+
+
+![png](readme_figures/output_12_35.png)
+
+
+    12/12 - 6s - loss: 0.0091 - binary_crossentropy: 0.0091 - val_loss: 0.0143 - val_binary_crossentropy: 0.0143
+    12/12 - 6s - loss: 0.0089 - binary_crossentropy: 0.0089 - val_loss: 0.0159 - val_binary_crossentropy: 0.0159
+    12/12 - 6s - loss: 0.0088 - binary_crossentropy: 0.0088 - val_loss: 0.0148 - val_binary_crossentropy: 0.0148
+    12/12 - 6s - loss: 0.0086 - binary_crossentropy: 0.0086 - val_loss: 0.0140 - val_binary_crossentropy: 0.0140
+    12/12 - 6s - loss: 0.0088 - binary_crossentropy: 0.0088 - val_loss: 0.0136 - val_binary_crossentropy: 0.0136
+    12/12 - 6s - loss: 0.0087 - binary_crossentropy: 0.0087 - val_loss: 0.0116 - val_binary_crossentropy: 0.0116
+    12/12 - 6s - loss: 0.0084 - binary_crossentropy: 0.0084 - val_loss: 0.0133 - val_binary_crossentropy: 0.0133
+    12/12 - 6s - loss: 0.0083 - binary_crossentropy: 0.0083 - val_loss: 0.0134 - val_binary_crossentropy: 0.0134
+    12/12 - 6s - loss: 0.0081 - binary_crossentropy: 0.0081 - val_loss: 0.0150 - val_binary_crossentropy: 0.0150
+    12/12 - 6s - loss: 0.0080 - binary_crossentropy: 0.0080 - val_loss: 0.0138 - val_binary_crossentropy: 0.0138
+    Epoch => [~ 91] / 100
+
+
+
+![png](readme_figures/output_12_37.png)
+
+
+
+![png](readme_figures/output_12_38.png)
+
+
+
+![png](readme_figures/output_12_39.png)
+
+
+    12/12 - 6s - loss: 0.0079 - binary_crossentropy: 0.0079 - val_loss: 0.0145 - val_binary_crossentropy: 0.0145
+    12/12 - 6s - loss: 0.0078 - binary_crossentropy: 0.0078 - val_loss: 0.0132 - val_binary_crossentropy: 0.0132
+    12/12 - 6s - loss: 0.0077 - binary_crossentropy: 0.0077 - val_loss: 0.0131 - val_binary_crossentropy: 0.0131
+    12/12 - 6s - loss: 0.0075 - binary_crossentropy: 0.0075 - val_loss: 0.0150 - val_binary_crossentropy: 0.0150
+    12/12 - 6s - loss: 0.0074 - binary_crossentropy: 0.0074 - val_loss: 0.0134 - val_binary_crossentropy: 0.0134
+    12/12 - 6s - loss: 0.0074 - binary_crossentropy: 0.0074 - val_loss: 0.0133 - val_binary_crossentropy: 0.0133
+    12/12 - 6s - loss: 0.0074 - binary_crossentropy: 0.0074 - val_loss: 0.0118 - val_binary_crossentropy: 0.0118
+    12/12 - 6s - loss: 0.0072 - binary_crossentropy: 0.0072 - val_loss: 0.0141 - val_binary_crossentropy: 0.0141
+
+
+# Part 3. Non-training frames (Full video) 에 대해 모델 prediction 적용하기
+
+
+```python
+""" Video frame 읽어온 후 predict 하기 + 그림 파일로 save 하기 """
+from datetime import datetime, timedelta
+datestr = (datetime.now()+timedelta(hours=9)).strftime("%Y%m%d-%H%M%S")
+
+dir_import = 'content/data/frames/'
+dirList = glob(dir_import+'*sample*')
+dirList.sort()
+
+writedir = 'content/data/predicts/'
+#!rm -r content/data/predicts/
+os.system('mkdir %s'%writedir);
+for dirName in dirList:
+  print('Now processing [%s]..'%dirName)
+  predicts, frames = [], []
+
+  # set directory
+  dir_export = writedir+dirName.split('/')[-1]+'/'
+  if not os.path.isdir(dir_export): os.mkdir(dir_export)
+
+  # Get files
+  fileList = glob(dirName+'/frame*.jpg'); fileList.sort()
+  for fileName_load in fileList:
+    fileName_save = dir_export+'mask'+fileName_load.split('/')[-1][5:]
+    exist = len( glob(fileName_save) )>0
+
+    if True:#if not exist:
+      # Load raw frame
+      frame = cv2.imread(fileName_load)[:,:,0]/255
+      frame = np.swapaxes(np.expand_dims(np.array(frame),2),0,2)
+
+      # Predict
+      pred = np.squeeze(model.predict(frame))
+      #plt.imshow(255*pred); plt.show()
+
+      # Save mask
+      fileName_save = dir_export+'pred'+fileName_load.split('/')[-1][5:]
+      cv2.imwrite(fileName_save,pred*255)
+
+os.system('zip -r content/predicts-%s.zip content/data/predicts/'%datestr)
+files.download('content/predicts-%s.zip'%datestr)
+
+```
+
+    Now processing [content/data/frames/sample_01]..
+    Now processing [content/data/frames/sample_02]..
+    Now processing [content/data/frames/sample_03]..
+    Now processing [content/data/frames/sample_04]..
+
+
+
+    <IPython.core.display.Javascript object>
+
+
+
+    <IPython.core.display.Javascript object>
+
+
+
+```python
+""" 저장하기 """
+# 모델 파일 저장하기
+model_fname = 'content/model-%s.h5'%datestr
+model.save_weights(model_fname)
+
+# 구글드라이브에 백업하기
+os.system('zip -r content/predicts-%s.zip content/data/predicts/'%datestr)
+os.system("cp content/predicts-%s.zip content/gdrive/MyDrive/'Colab Notebooks'/tutorial_data/"%datestr)
+os.system("cp content/model-%s.h5 content/gdrive/MyDrive/'Colab Notebooks'/tutorial_data/"%datestr)
+
+# 로컬 컴퓨터에 다운로드 받기
+files.download('content/predicts-%s.zip'%datestr)
+files.download('content/model-%s.h5'%datestr)
+```
+
+
+    <IPython.core.display.Javascript object>
+
+
+
+    <IPython.core.display.Javascript object>
+
+
+
+    <IPython.core.display.Javascript object>
+
+
+
+    <IPython.core.display.Javascript object>