Deep CNN Models

dwlee·2022년 11월 14일
0

개요

이전 포스트에서는 간단한 CNN 모델로 MNIST 이미지를 분류했다. 사실 MNIST 데이터셋은 이미지가 크지않기 때문에 간단한 모델로도 높은 정확도를 얻을 수 있다. 그러나 이미지의 크기가 커지면 간단한 모델로는 일정 수준 이상의 정확도를 달성하기 어려워지기 때문에 layer를 많이 추가하여 모델의 크기를 키운 CNN 기반의 모델이 등장하게 된다. 이번 포스트에서는 깊은 CNN 기반 모델 중 하나인 ResNet을 알아보고 모델의 학습 속도를 높일 수 있는 방법을 살펴보자.

1. ResNet

1) Effects of Deep Layers

2010년부터 실시했던 이미지 인식기술 대회인 ILSVRC에서 딥러닝이 큰 주목을 받기 시작했다. 특히 2012년부터 layer의 개수를 늘리면서 정확도가 크게 좋아졌고 2015년에 ResNet이 96%가 넘는 정확도를 기록하면서 대회의 종지부를 찍었다.
layer가 깊어지면서 생기는 장점은 바로 모델의 매개변수 개수가 줄어드는 것이다. 예를 들어, kernel의 크기가 5 ×\times 5와 3 ×\times 3일 때를 생각해보자. 아래 그림과 같이 kernel이 5 ×\times 5일 때 1번의 convolution으로 얻은 1개의 데이터는 3 ×\times 3 kernel로 2회 convolution을 수행한 결과와 같다. 이 때 매개변수의 개수는 5 ×\times 5 kernel을 사용했을 때는 25개이지만, 3 ×\times 3 kernel을 사용했을 때는 233=18개밖에 되지 않는다. 따라서 큰 kernel로 적게 convolution하는 것보다 작은 kernel로 여러 번 convolution 연산을 수행하는 것이 모델의 매개변수 개수를 줄일 수 있다.

2) Structure

2. Deep Learning with GPU

딥러닝 모델을 학습하거나 테스트할 때는 주로 NVIDIA GPU를 많이 사용한다. GPU는 CPU에 비해 병렬 연산을 수행하는데 최적화되어 있고, 메모리가 내장되어 있어 RAM에서 데이터를 끌어다써야 하는 CPU에 비해 처리 속도가 빠르다.
예를 들어, 28 ×\times 28 이미지를 학습할 때 모든 픽셀은 동일한 연산을 반복하게 된다. 만약 이를 CPU에서 학습한다면 픽셀 하나씩 순차적으로 연산을 수행하게 되지만 GPU에서는 모든 픽셀에 대해 동시에 연산을 수행하므로 CPU에 비해 훨씬 빠르게 처리할 수 있다.

3. Batch size

Batch는 GPU에서 한 이미지 내 모든 픽셀에 대해 동일한 연산을 병렬적으로 처리할 수 있다는 점에 착안하여 한 이미지가 아닌 여러 이미지에 대해 병렬적으로 처리하기 위해 도입되었다.
딥러닝에서는 학습할 이미지가 한 장이 아닌데다가 각 이미지는 모두 동일한 연산을 수행하므로 여러 이미지에 대해 동시에 연산을 수행하면 학습 속도를 높일 수 있다. 그래서 PyTorch에서는 DataLoader 클래스에서 데이터 샘플을 가져올 때 batch_size 값을 조정하여 1회 학습 시 여러 개의 데이터 샘플을 일괄적으로 처리할 수 있다.

train_dataloader = DataLoader(
        training_dataset, batch_size=100, shuffle=True, num_workers=16, pin_memory=True
    )

이처럼 batch_size 값을 크게 하면 더 많은 데이터 샘플을 동시에 처리할 수 있기에 학습 속도가 빨라지지만 무작정 값을 크게 할 수는 없다. 그 이유는 병렬 연산을 수행하는 GPU의 메모리 공간에 한계가 있기 때문이다. 만약 이 메모리 공간보다 더 큰 용량의 데이터 샘플이 입력된다면 GPU에서는 이를 처리하지 못하고 다음과 같은 오류 메세지를 출력하게 된다.

>> ...
torch.cuda.OutOfMemoryError: CUDA out of memory. Tried to allocate 3.74 GiB (GPU 0; 8.00 GiB total capacity; 3.80 GiB already allocated; 2.30 GiB free; 3.80 GiB reserved in total by PyTorch) 
If reserved memory is >> allocated memory try setting max_split_size_mb to avoid fragmentation.  See documentation for Memory Management and PYTORCH_CUDA_ALLOC_CONF

이때는 batch_size 값을 줄여 오류가 발생하지 않게 해야 한다. GPU에 내장된 메모리 용량은 GPU 모델에 따라 상이하기 때문에 적절한 값의 batch_size를 설정할 필요가 있다.

4. Data transfer to GPU memory

앞서 언급했듯이 GPU는 CPU와 달리 자체 메모리 공간을 갖고 있다. 그래서 RAM과 지속적으로 데이터를 주고받지 않기 때문에 데이터 처리 시간을 단축할 수 있다.
GPU를 이용해 딥러닝 실행 속도를 높이기 위해서는 딥러닝 실행에 필요한 구성 요소들을 미리 GPU의 메모리 공간에 옮겨놓아야 실행 시간 단축의 효과를 볼 수 있다. Pytorch에서는 텐서 타입의 데이터를 GPU의 메모리 공간으로 이동할 수 있도록 torch.Tensor.to() 메소드를 제공하고 있다.

device = "cuda" if torch.cuda.is_available() else "cpu"

model = nn.Linear(in_features=100, out_features=10)
model = model.to(device)
...
# In the training loop
for image, label in train_dataloader:
	image, label = image.to(device), label.to(device)

이처럼 병렬 연산이 가능한 모델의 가중치 행렬, 이미지, 레이블 데이터는 device로 전송하여 처리 속도를 높일 수 있다. PyTorch에서 GPU의 메모리를 사용하기 위해서는 반드시 NVIDIA GPU가 장착되어 있어야 하며, GPU 내에서 병렬 연산을 가능하게 하는 CUDA Toolkit, CUDNN 등이 설치되어 있어야 한다. 이를 설치하는 방법은 NVIDIA 공식 홈페이지를 참고하기 바란다.

profile
Deep Learning developer

0개의 댓글