활성화 함수 (Activation Function)

step function (계단 함수)

$$ h(x) = \begin{cases} 1 & (x > 0) \\ 0 & (x \leqq 0) \end{cases} $$

import numpy as np

def step_function(x):
    return np.array(x > 0, dtype=np.int)

계단 함수의 그래프

import matplotlib.pylab as plt

x = np.arange(-5.0, 5.0, 0.1)
y = step_function(x)
plt.plot(x, y)
plt.ylim(-0.1, 1.1)
plt.show()

sigmoid (시그모이드)

d

$$ h(x) = \frac{1}{1 + e^{-x}} $$

def sigmoid(x):
    return 1 / (1 + np.exp(-x))
x = np.arange(-5.0, 5.0, 0.1)
y = sigmoid(x)
plt.plot(x, y)
plt.ylim(-0.1, 1.1)
plt.show()

dd

ReLU (Rectified Linear Unit, 렐루)

$$ h(x) = \begin{cases} x & (x > 0) \\ 0 & (x \leqq 0) \end{cases} $$

def relu(x):
    return np.maximum(0, x)
x = np.arange(-5.0, 5.0, 0.1)
y = relu(x)
plt.plot(x, y)
plt.ylim(-1.0, 5.0)
plt.show()

Keras GPU 사용하기

쿠버네티스(kubernetes) 위에서 Jupyter를 사용하고 있다. Jupyter Notebook 에서 텐서플로-케라스를 사용하고 있고, GPU 4개를 할당하였다. 주피터에서 노트북을 1개 더 생성해서 작업 할 경우 OOM 에러가 발생하였다.

ResourceExhaustedError (see above for traceback): OOM when allocating tensor with shape[3,3,128,128] and type float on /job:localhost/replica:0/task:0/device:GPU:0 by allocator GPU_0_bfc
	 [[node conv2d_3/kernel/Initializer/random_uniform/RandomUniform (defined at <ipython-input-2-355421ac90ac>:1) ]]
Hint: If you want to see a list of allocated tensors when OOM happens, add report_tensor_allocations_upon_oom to RunOptions for current allocation info.

양쪽 노트북에서 모드 GPU:0을 사용해서 생긴 문제인거 같다. 첫번째 노트북에서 GPU:0의 메모리를 거의 풀로 사용해버린 상태에서, 두번째 노트북에서 GPU:0을 사용하려니 메모리가 부족한 상태가 발생한것이다

서버에서 nvidia-smi을 실행해보면, 프로세스는 생성되었지만, 할당된 메모리가 작다는것을 알 수 있다.

Every 2.0s: nvidia-smi                                                                                         Thu Aug  8 10:09:46 2019

Thu Aug  8 08:09:46 2019
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 418.67       Driver Version: 418.67       CUDA Version: 10.1     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  Tesla M40           Off  | 00000000:02:00.0 Off |                    0 |
| N/A   35C    P0    63W / 250W |  11302MiB / 11448MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   1  Tesla M40           Off  | 00000000:82:00.0 Off |                    0 |
| N/A   37C    P0    62W / 250W |    212MiB / 11448MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   2  Tesla M40           Off  | 00000000:85:00.0 Off |                    0 |
| N/A   35C    P0    62W / 250W |    212MiB / 11448MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   3  Tesla M40           Off  | 00000000:86:00.0 Off |                    0 |
| N/A   37C    P0    62W / 250W |    212MiB / 11448MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|    0     81475      C   /opt/conda/bin/python                      11060MiB |
|    0     93847      C   /opt/conda/bin/python                        229MiB |
|    1     81475      C   /opt/conda/bin/python                         99MiB |
|    1     93847      C   /opt/conda/bin/python                         99MiB |
|    2     81475      C   /opt/conda/bin/python                         99MiB |
|    2     93847      C   /opt/conda/bin/python                         99MiB |
|    3     81475      C   /opt/conda/bin/python                         99MiB |
|    3     93847      C   /opt/conda/bin/python                         99MiB |
+-----------------------------------------------------------------------------+

알아서 노는 GPU를 사용하면 좋으련만… 어쩔수 없이 GPU 디바이스를 직접 지정하여서 사용핬다.

디바이스 목록 보기

from tensorflow.python.client import device_lib
print(device_lib.list_local_devices())

특정 디바이스를 지정해서 모델 처리하기

텐서플로우에서는 tf.device('/gpu:0') 구문으로 특정 GPU 디바이스를 지정해서 모델을 처리할 수 있다.

import tensorflow as tf

with tf.device('/gpu:0'):
    model = keras.models.Sequential()
    model.add(keras.layers.Conv2D(32, (3, 3), activation='relu', input_shape=(150, 150, 3)))
    model.add(keras.layers.MaxPool2D((2, 2)))
    model.add(keras.layers.Conv2D(64, (3, 3), activation='relu'))
    model.add(keras.layers.MaxPool2D((2, 2)))
    model.add(keras.layers.Conv2D(128, (3, 3), activation='relu'))
    model.add(keras.layers.MaxPool2D((2, 2)))
    model.add(keras.layers.Conv2D(128, (3, 3), activation='relu'))
    model.add(keras.layers.MaxPool2D((2, 2)))
    model.add(keras.layers.Flatten())
    model.add(keras.layers.Dense(512, activation='relu'))
    model.add(keras.layers.Dense(1, activation='sigmoid'))
    
    model.compile(loss='binary_crossentropy', optimizer=keras.optimizers.RMSprop(lr=1e-4), metrics=['acc'])
    
    
    train_datagen = keras.preprocessing.image.ImageDataGenerator(rescale=1./255)
    validation_datagen = keras.preprocessing.image.ImageDataGenerator(rescale=1./255)
    
    train_generator = train_datagen.flow_from_directory(train_dir, target_size=(150, 150), batch_size=20, class_mode='binary')
    validation_generator = validation_datagen.flow_from_directory(validation_dir, target_size=(150, 150), batch_size=20, class_mode='binary')
    
    
    history = model.fit_generator(train_generator, steps_per_epoch=100, epochs=30, validation_data=validation_generator, validation_steps=50)

기타 : 멀티 GPU 사용하기

keras.utils을 사용하면, 모델을 처리할 때 GPU를 사용할 수 있게 지정할 수 있다.

model = ...
model = keras.utils.multi_gpu_model(model, gpus=4)
model.compile(loss='binary_crossentropy', optimizer=keras.optimizers.RMSprop(lr=1e-4), metrics=['acc'])
...

Your CPU supports instructions that this TensorFlow binary was not compiled to use: SSE4.1 SSE4.2 AVX AVX2 FMA

경고 메시지

텐서플로(TensorFlow) 라이브러리를 사용해서, 머신러닝 코드를 실행하다 보면 아래와 같은 경고 메시지가 출력되는 경우가 있다.

I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: SSE4.1 SSE4.2 AVX AVX2 FMA

굳이 직역을 해보자면, ‘이 텐서플로 바이너리는 당신의 CPU가 제공하는 명령어(instruction)들을 사용하도록 컴파일되어 있지 않습니다.’ 라는 뜻일 것이다.

해결 방법

해결 방법은 옵션을 추가해서 텐서플로를 다시 빌드 하면 된다.

예를 들어 SSE4.1을 지원하는 CPU라면 --copt=-msse4.1을 추가하면 된다.

참고 자료