합성곱 연산 심화: Stride & Zero Padding

Hot potato·2025년 1월 24일

AI 비전 컴퓨팅

목록 보기
9/13

1. Stride

합성곱 연산의 핵심 개념 중 하나로, 출력 크기, feature map의 크기 조정, 경계 처리 방식에 영향을 미친다!

📌 Stride

stride란 커널(필터)이 입력 데이터를 얼마나 건너뛰면서 이동하는지를 정하는 값이다.
예를 들어, stride=1: 커널이 한 칸씩 이동 / stride=2: 커널이 두 칸씩 이동❗❗

위에 예시는 stride가 2일 때이고, 파란색 영역(ROI)를 보면 커널이 한 번 연산을 한 뒤 두 칸씩 이동하는 걸 확인할 수 있다👀

❔❕❓ 이게 왜 필요하냐면 (필요성 및 목적)
강아지 귀 한쪽의 feature를 추출한다고 했을 때, 귀랑 관련된 필터를 가지고 모든 feature를 탐색하기 보다 듬성듬성 탐색하면서 연산 속도도 올리고, 데이터 크기도 줄여 효율성을 위한 것이다..!!

2. Zero Padding

📌 Zero Padding

Zero Padding은 합성곱 연산을 수행하기 전에 입력 데이터의 경계(가장자리)에 0을 추가하여 입력 크기를 늘리는 기법

❔❕❓ 이게 왜 필요하냐면 (필요성 및 목적)
1. 출력 크기 유지

6x6 이미지가 있고, 3x3 커널(필터)로 convolution하고 난 아웃풋의 이미지는 4x4가 될 것이다. 문제는 이걸 반복하다보면 아웃풋 이미지가 너무 작아져버리게 되고 그만큼 추출할 수 있는 정보의 양도 적어진다.

그래서 1만큼의 패딩을 주고 난 후 이미지 사이즈는 8x8이 되고, 이걸 다시 3x3 커널(필터)로 convolution하게 되면 이미지 사이즈를 6x6으로 유지할 수 있게 되는 것임!


Code💻💡

from google.colab.patches import cv2_imshow  # Colab 전용 함수
import cv2
import numpy as np

# 이미지 파일 경로
img_file = '/content/sample_data/flower.jpg'
img = cv2.imread(img_file, cv2.IMREAD_GRAYSCALE)

# 커널 정의 (드라마틱한 변화 유도)
kernel = np.array([[-1, -1, -1],
                   [-1,  8, -1],
                   [-1, -1, -1]])  # 엣지 검출 필터

# Conv2D 함수 정의
def Conv2D(img, kernel, stride=1, padding=0):
    # 패딩 추가
    padded_img = cv2.copyMakeBorder(img, padding, padding, padding, padding, cv2.BORDER_CONSTANT, value=0)
    # 필터 적용
    output = cv2.filter2D(padded_img, -1, kernel)
    return output, padded_img

# Conv2D 실행: stride=1, padding=0
output_stride1_padding0, padded_img1 = Conv2D(img, kernel=kernel, stride=1, padding=0)

# Conv2D 실행: stride=2, padding=1
output_stride2_padding1, padded_img2 = Conv2D(img, kernel=kernel, stride=2, padding=1)

# 이미지 크기 비교 출력
print("원본 이미지 크기:", img.shape)
print("stride=1, padding=0 결과 크기:", output_stride1_padding0.shape)
print("stride=2, padding=1 결과 크기:", output_stride2_padding1.shape)

# 이미지 출력
print("원본 이미지")
cv2_imshow(img)

print("stride=1, padding=0 결과")
cv2_imshow(output_stride1_padding0)

print("stride=2, padding=1 결과")
cv2_imshow(output_stride2_padding1)

Colab에서 위 코드를 바탕으로 원본 이미지, stride랑 padding이 적용된 이미지를 시각화 하면 아래와 같이 결과를 얻을 수 있다. (난 중간에 결과를 가로로 배치하게끔 추가 코딩을 해줬는데, 굳이 필요없는 부분이라 위 코드를 쓰면 세로로 나오는게 정상!)

👀 결과해석

  1. 원본이미지랑 stride = 1일 땐 동일함
  2. stride = 2를 적용하면 이미지를 축소하는 효과를 가져옴, padding = 1은 잘 안 보여서 엣지를 강조하는 필터를 넣어줬다.

✍ 정리

1. 6x6 이미지와 3x3 커널(필터) 사용 시

  • 원본 6x6 이미지에 3x3 커널을 적용하면, 출력 이미지 크기는 다음과 같이 계산
    - 출력크기 = (입력크기 - 커널크기) + 1 = (6-3) + 1 = 4
    - 결과적으로 출력 크기가 4x4로 줄어들게 된다
    - 문제점: 이걸 여러번 반복하면 이미지가 계속 작아저 유용한 정보가 손실될 수 있음

2. Zero Padding을 활용한 해결

  • 1만큼의 패딩을 주면, 입력 이미지의 가장자리에 0을 추가하여 크기가 8x8로 확장됨
  • 이 확장된 8x8 이미지에 3x3 커널을 적용하면 출력 크기:
    - 출력크기 = (입력크기 - 커널크기) + 1 = (8-3) + 1 = 6
  • 결과적으로 출력 이미지의 크기가 6x6으로 유지

3. 결론

Zero Padding은 합성곱 연산에서 출력 크기를 입력 크기와 동일하게 유지할 수 있도록 도와준다~!~!

이를 통해 정보 손실을 방지하고 더 많은 특징을 학습할 수 있단 말씀~~

profile
결국 난 잘될사람🍀 아자아자🥔

0개의 댓글