Book/실전! 프로젝트로 배우는 딥러닝 컴퓨터비전

Part1-2. CNN

aifornature 2025. 1. 12. 03:11

* 모든 실습은 mac의 환경에 맞게 수정하며 clone된 파일 외에는 직접 작성해보며 실습해 실제 실습파일 구조나 코드가 다를 수 있습니다.  

* 해당 글은 실전! 프로젝트로 배우는 딥러닝 컴퓨터비전을 토대로 정리한 글이므로 꼭 해당 책을 구매해 읽어보길 권장한다.


 

합성곱 심층 신경망 (= CNN, Convolution Neural Network)

  • 영상의 특징을 매우 정확하게 추출하여 영상 분석에 아주 성공적으로 활용할 수 있는 방법론
  • 합성곱 + 딥러닝
    • 합성곱 (= Convolution)
      • 이미지 프로세싱 분야에서 매우 일반적인 기술
      • 입력을 목적에 따라 가공해서 원하는 출력을 얻기 위해 사용하는 연산 [1]
  • 입력 데이터가 3차원 데이터의 경우, 커널의 크기의 마지막 차원이 항상 입력 데이터의 색상 차원과 동일해야 한다.
    • ex) 흑백 이미지일때, 마지막 차원 = 1 / 컬러 이미지일때, 마지막 차원 = 3
  • 특징 맵 (=Feature Map) : 원본 이미지의 특징을 추출해 가지고 있는 활성화 맵
    • In 1 layer, 커널을 다수 사용 => 커널의 개수와 동일한 활성화 맵 산출 => 특징 맵 (Feature Map) 생성
    • 도입부 : 큰 사이즈, 윤곽선 등의 특징 보유
    • 중반부 : 중간 사이즈, 얼룩무늬 등 패턴 특징 보유
    • 후반부 : 작은 사이즈, 눈/바퀴 등 구체적인 특징 보유

 

 FC layer (= Fully Connected layer, Affine layer)

  • 여러 층으로 중첩된 행렬곱의 식
  • y=Wx+
  • 입력 데이터와 출력 데이터는 모두 1차원이여야 한다. 
  • 문제점 : 데이터의 형상 무시한다. 즉, 이미지 데이터의 경우 공간적 정보를 살릴 수 없다.
    • 이미지 데이터의 경우 공간적 정보를 살릴 수 없다 = 공간적으로 가까운 픽셀은 값이 비슷하거나, RGB의 각 채널은 서로 밀접하게 관련되어 있거나, 거리가 먼 픽셀끼리는 별 연관이 없는 등 3차원 속에서 의미를 갖는 본질적인 패턴이 숨어있는데 이를 살릴 수 없다. [2]

Conv layer

  • 콘볼루션 계산을 하는 레이어
  • 목적 : 이미지의 공간 정보를 잃지 않고 이미지의 특징을 추출해 대상을 인지할 수 있는 인공지능 = 인간의 눈 역할
  • 이미지 데이터 뿐만 아니라 다양한 형태의 데이터에서 원하는 특성을 추출하는데 탁월함. => 신호처리나 음성인식 분야에서도 활용
  • 연산 방식 
    • 입력 크기 : (H,W)
    • 출력 크기 : (OH, OW)
    • 필터(=커널) 크기 : (FH, FW)
    • 패딩 : P
    • 스트라이드(=커널이 공간 이동하는 사이즈) : S  

합성곱 층 연산 [3]

  • 산출물 : 활성화 맵
    • 활성화 맵(=Activation Map) : 컨볼루션 연산을 하는 과정에서 'Dot Product'가 생성되고, 커널이 위치 이동하며 여러 번의 컨볼루션 연산을 해 생성된 'Dot Product'들의 집합.
    • 연산 방식 
      • 활성화 맵 : (W2,H2)
      • 입력 : (W1,H1)
      • 커널 : F
      • 스트라이드 : S
      • 패딩 : P

활성화 맵 생성 과정

Pooling layer

  • 계산없이 사이즈를 줄이는 것 (=다운샘플링)
  • 활성화 맵에서 독립적으로 작동
  • 종류 : 최소, 최대(=주로 이용), 평균 등
최대 풀링 과정

 

LeNet(CNN) MNIST 실습

class Net(nn.Module): # 2개 conv layer, 2개 fc layer
    def __init__(self):
        super().__init__()
        self.conv1=nn.Conv2d(1,10,kernel_size=5)
        self.conv2=nn.Conv2d(10,20,kernel_size=5)
        self.conv2_drop=nn.Dropout2d()
        self.fc1=nn.Linear(320,50)
        self.fc2=nn.Linear(50,10)
        
    def forward(self,x):
        x=F.relu(F.max_pool2d(self.conv1(x),2))
        x=F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)),2))
        x=x.view(-1,320)
        x=F.relu(self.fc1(x))
        x=self.fc2(x)
        return F.log_softmax(x,dim=1)
    
device = torch.device('mps' if torch.backends.mps.is_available() else "cpu") # gpu 사용

model=Net().to(device) # 네트워크 정의

optimizer=optim.SGD(model.parameters(),lr=0.01) # 최적화 함수 # 경사하강법 사용, 학습률 0.01

data, target=next(iter(train_loader)) # 훈련 배치 데이터 로드 및 변수 준비

def fit(epoch, model, data_loader, phase='training',volatile=False):
    if phase=='training':
        model.train()
    if phase=='validation':
        model.eval()
        volatile=True # 역전파 계산 x # torch.no_grad() 로 대체됨.
        
    running_loss=0.0
    running_correct=0
    for batch_idx, (data,target) in enumerate(data_loader):
        if device:
            data, target = data.to(device), target.to(device)
        data, target=Variable(data,volatile), Variable(target)
        if phase=='training':
            optimizer.zero_grad()
            
        output=model(data)
        loss=F.nll_loss(output,target) # nll 손실함수 사용 # 로그확률을 입력으로 받음. 
        running_loss+=F.nll_loss(output,target,reduction='sum').item()
        preds=output.data.max(dim=1,keepdim=True)[1]
        running_correct+=preds.eq(target.data.view_as(preds)).cpu().sum()
        
        if phase=='training':
            loss.backward()
            optimizer.step()
                
    loss=running_loss/len(data_loader.dataset)
    accuracy=100. * running_correct/len(data_loader.dataset)
    
    print(f'{phase} loss is {loss:{5}.{2}} and {phase} accuracy is {running_correct}/{len(data_loader.dataset)}{accuracy:{10}.{4}}')
    return loss,accuracy
훈련, 검증 데이터의 손실, 정확도 그래프

Reference

[1] https://people-analysis.tistory.com/264

[2] "밑바닥부터 시작하는 딥러닝", 사이토 고키, p229

[3] https://www.datamaker.io/blog/posts/33