1.5.2 GPU(쿠파이)
* 딥러닝의 계산은 대량의 곱하기 연산으로 구성됩니다.
이 대량의 곱하기 연산은 병렬로 계산할 수 있는데, 이 점에서 CPU보다 GPU가 유리합니다.
- 쿠파이를 사용하면 엔비디아 GPU를 사용해 간단하게 병렬 계산을 수행할 수 있습니다.
(쿠파이는 넘파이와 호환되는 API를 제공합니다.)
import cupy as cp
x = cp.arange(6).reshape(2, 3).astype('f')
x
→ array([[0., 1., 2.],
[3., 4., 5.]], dtype=float32)
x.sum(axis=1)
→ array([ 3., 12.], dtype=float32)
위와 같이 쿠파이의 사용법은 기본적으로 넘파이와 같습니다.
※ config
GPU = True
※ np
from common.config import GPU
if GPU:
import cupy as np
np.cuda.set_allocator(np.cuda.MemoryPool().malloc)
np.add.at = np.scatter_add
print('\033[92m' + '-' * 60 + '\033[0m')
print(' ' * 23 + '\033[92mGPU Mode (cupy)\033[0m')
print('\033[92m' + '-' * 60 + '\033[0m\n')
else:
import numpy as np
※ layers
from common.np import * # import numpy as np
from common.config import GPU
from common.functions import softmax, cross_entropy_error
class MatMul:
def __init__(self, W):
self.params = [W]
self.grads = [np.zeros_like(W)]
self.x = None
def forward(self, x):
W, = self.params
out = np.dot(x, W)
self.x = x
return out
def backward(self, dout):
W, = self.params
dx = np.dot(dout, W.T)
dW = np.dot(self.x.T, dout)
self.grads[0][...] = dW
return dx
class Affine:
def __init__(self, W, b):
self.params = [W, b]
self.grads = [np.zeros_like(W), np.zeros_like(b)]
self.x = None
def forward(self, x):
W, b = self.params
out = np.dot(x, W) + b
self.x = x
return out
def backward(self, dout):
W, b = self.params
dx = np.dot(dout, W.T)
dW = np.dot(self.x.T, dout)
db = np.sum(dout, axis=0)
self.grads[0][...] = dW
self.grads[1][...] = db
return dx
class Softmax:
def __init__(self):
self.params, self.grads = [], []
self.out = None
def forward(self, x):
self.out = softmax(x)
return self.out
def backward(self, dout):
dx = self.out * dout
sumdx = np.sum(dx, axis=1, keepdims=True)
dx -= self.out * sumdx
return dx
class SoftmaxWithLoss:
def __init__(self):
self.params, self.grads = [], []
self.y = None # softmax의 출력
self.t = None # 정답 레이블
def forward(self, x, t):
self.t = t
self.y = softmax(x)
# 정답 레이블이 원핫 벡터일 경우 정답의 인덱스로 변환
if self.t.size == self.y.size:
self.t = self.t.argmax(axis=1)
loss = cross_entropy_error(self.y, self.t)
return loss
def backward(self, dout=1):
batch_size = self.t.shape[0]
dx = self.y.copy()
dx[np.arange(batch_size), self.t] -= 1
dx *= dout
dx = dx / batch_size
return dx
class Sigmoid:
def __init__(self):
self.params, self.grads = [], []
self.out = None
def forward(self, x):
out = 1 / (1 + np.exp(-x))
self.out = out
return out
def backward(self, dout):
dx = dout * (1.0 - self.out) * self.out
return dx
class SigmoidWithLoss:
def __init__(self):
self.params, self.grads = [], []
self.loss = None
self.y = None # sigmoid의 출력
self.t = None # 정답 데이터
def forward(self, x, t):
self.t = t
self.y = 1 / (1 + np.exp(-x))
self.loss = cross_entropy_error(np.c_[1 - self.y, self.y], self.t)
return self.loss
def backward(self, dout=1):
batch_size = self.t.shape[0]
dx = (self.y - self.t) * dout / batch_size
return dx
class Dropout:
'''
http://arxiv.org/abs/1207.0580
'''
def __init__(self, dropout_ratio=0.5):
self.params, self.grads = [], []
self.dropout_ratio = dropout_ratio
self.mask = None
def forward(self, x, train_flg=True):
if train_flg:
self.mask = np.random.rand(*x.shape) > self.dropout_ratio
return x * self.mask
else:
return x * (1.0 - self.dropout_ratio)
def backward(self, dout):
return dout * self.mask
class Embedding:
def __init__(self, W):
self.params = [W]
self.grads = [np.zeros_like(W)]
self.idx = None
def forward(self, idx):
W, = self.params
self.idx = idx
out = W[idx]
return out
def backward(self, dout):
dW, = self.grads
dW[...] = 0
np.add.at(dW, self.idx, dout)
return None
'Deep learning > Computer vision(영상처리)' 카테고리의 다른 글
책(밑바닥부터 시작하는 딥러닝 2) 4 (0) | 2020.02.13 |
---|---|
BoW(이미지관련) (0) | 2020.02.12 |
GAN(이론) (0) | 2020.02.12 |
책(밑바닥부터 시작하는 딥러닝 2) 2 (0) | 2020.02.10 |
책(밑바닥부터 시작하는 딥러닝 2) (0) | 2020.02.06 |