CNN의 주요 계층 - CNN 풀링 층(Pooling Layer)
2025. 2. 3. 13:10ㆍAI/딥러닝
CNN 풀링 층(Pooling Layer)
1. 풀링 층 개요
풀링 층은 CNN에서 특징 맵의 크기를 줄이고 중요한 정보를 보존하는 핵심 구성 요소입니다.
✅ 주요 기능
- 차원 축소: 특징 맵의 공간적 크기를 줄여 연산 효율성 향상
- 과적합 방지: 모델의 복잡도를 낮춰 일반화 성능 개선
- 특징 추출: 주요 특징을 보존하며 데이터 표현을 압축
2. 풀링 기법 구현
✅ 기본 설정
"""
CNN 풀링 층 구현
License: MIT
"""
import tensorflow as tf
from tensorflow.keras.layers import Layer, MaxPooling2D, AveragePooling2D
import logging
# 로깅 설정
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
✅ 최대 풀링 (Max Pooling)
class CustomMaxPool2D(Layer):
"""최대 풀링 층 구현
Args:
pool_size: 풀링 윈도우 크기
strides: 이동 간격
padding: 패딩 방식 ('valid' 또는 'same')
Raises:
ValueError: 잘못된 입력 형태나 파라미터 값
"""
def __init__(self, pool_size=(2,2), strides=None, padding='valid', **kwargs):
super().__init__(**kwargs)
if not isinstance(pool_size, (tuple, list)) or len(pool_size) != 2:
raise ValueError(f"pool_size는 2개의 정수를 가진 튜플이어야 합니다. 입력값: {pool_size}")
if padding not in ['valid', 'same']:
raise ValueError(f"padding은 'valid' 또는 'same'이어야 합니다. 입력값: {padding}")
self.pooling = MaxPooling2D(
pool_size=pool_size,
strides=strides,
padding=padding
)
def build(self, input_shape):
if len(input_shape) != 4:
raise ValueError(f"4차원 입력이 필요합니다. 입력 형태: {input_shape}")
super().build(input_shape)
def call(self, inputs, training=None):
try:
return self.pooling(inputs)
except tf.errors.InvalidArgumentError as e:
logger.error(f"풀링 연산 실패: {e}")
raise
✅ 평균 풀링 (Average Pooling)
class CustomAvgPool2D(Layer):
"""평균 풀링 층 구현
Args:
pool_size: 풀링 윈도우 크기
strides: 이동 간격
padding: 패딩 방식
Raises:
ValueError: 잘못된 파라미터
"""
def __init__(self, pool_size=(2,2), strides=None, padding='valid', **kwargs):
super().__init__(**kwargs)
if not isinstance(pool_size, (tuple, list)) or len(pool_size) != 2:
raise ValueError(f"pool_size는 2개의 정수를 가진 튜플이어야 합니다. 입력값: {pool_size}")
self.pooling = AveragePooling2D(
pool_size=pool_size,
strides=strides,
padding=padding
)
def call(self, inputs):
try:
return self.pooling(inputs)
except Exception as e:
logger.error(f"평균 풀링 연산 실패: {e}")
raise
✅ 공간 피라미드 풀링 (SPP)
class SpatialPyramidPooling(Layer):
"""공간 피라미드 풀링 층 구현
Args:
bin_sizes: 피라미드 레벨별 풀링 크기
Raises:
ValueError: 잘못된 bin_sizes 값
"""
def __init__(self, bin_sizes=[1, 2, 4], **kwargs):
super().__init__(**kwargs)
if not bin_sizes or not all(isinstance(x, int) and x > 0 for x in bin_sizes):
raise ValueError(f"bin_sizes는 양의 정수 리스트여야 합니다. 입력값: {bin_sizes}")
self.bin_sizes = bin_sizes
def call(self, inputs):
try:
if not tf.is_tensor(inputs):
raise ValueError("텐서 입력이 필요합니다")
pooled_outputs = []
for bin_size in self.bin_sizes:
h = tf.shape(inputs)[1] // bin_size
w = tf.shape(inputs)[2] // bin_size
if h == 0 or w == 0:
logger.warning(f"bin_size {bin_size}가 입력 크기보다 큽니다")
continue
pool = tf.nn.max_pool2d(
inputs,
ksize=[1, h, w, 1],
strides=[1, h, w, 1],
padding='VALID'
)
pooled_outputs.append(tf.reshape(pool, [tf.shape(pool)[0], -1]))
if not pooled_outputs:
raise ValueError("유효한 풀링 결과가 없습니다")
return tf.concat(pooled_outputs, axis=1)
except tf.errors.ResourceExhaustedError as e:
logger.error(f"메모리 부족: {e}")
raise
except Exception as e:
logger.error(f"예상치 못한 에러: {e}")
raise
✅ 학습 가능한 풀링 (Learnable Pooling)
class LearnablePooling(Layer):
"""학습 가능한 풀링 층
Args:
pool_size: 풀링 윈도우 크기
Raises:
ValueError: 잘못된 입력 형태
"""
def __init__(self, pool_size=(2,2), **kwargs):
super().__init__(**kwargs)
self.pool_size = pool_size
self.alpha = tf.Variable(0.5, trainable=True)
def call(self, inputs):
try:
max_pool = tf.nn.max_pool2d(inputs, self.pool_size, self.pool_size, 'VALID')
avg_pool = tf.nn.avg_pool2d(inputs, self.pool_size, self.pool_size, 'VALID')
return self.alpha * max_pool + (1 - self.alpha) * avg_pool
except Exception as e:
logger.error(f"학습 가능한 풀링 연산 실패: {e}")
raise
3. 하이퍼파라미터 설정 가이드
✅ 기본 설정
pooling_config = {
'standard': {
'pool_size': (2, 2),
'strides': (2, 2),
'padding': 'valid'
},
'high_resolution': {
'pool_size': (4, 4),
'strides': (4, 4)
},
'detail_preserve': {
'pool_size': (2, 2),
'strides': (1, 1),
'padding': 'same'
}
}
✅ 상황별 최적 설정
상황 | 권장 설정 | 이유 |
고해상도 이미지 | 큰 pool_size | 효율적인 다운샘플링 |
작은 객체 탐지 | 작은 stride | 세부 정보 보존 |
실시간 처리 | 큰 stride | 연산량 감소 |
메모리 제약 | 적은 SPP 레벨 | 메모리 사용량 감소 |
4. 사용 예시
✅ 기본 사용법
# 최대 풀링 사용
max_pool = CustomMaxPool2D(pool_size=(2, 2))
# 평균 풀링 사용
avg_pool = CustomAvgPool2D(pool_size=(2, 2))
# SPP 사용
spp = SpatialPyramidPooling(bin_sizes=[1, 2, 4])
# 학습 가능한 풀링 사용
learnable_pool = LearnablePooling(pool_size=(2, 2))
✅ 에러 처리
try:
output = max_pool(inputs)
except ValueError as e:
logger.error(f"입력 검증 실패: {e}")
# 에러 처리 로직
except tf.errors.ResourceExhaustedError as e:
logger.error(f"메모리 부족: {e}")
# 메모리 최적화 로직
except Exception as e:
logger.error(f"예상치 못한 에러: {e}")
# 일반 에러 처리
5. 참고문헌
- He, K. et al. (2014). "Spatial Pyramid Pooling in Deep CNNs." ECCV.
- Lin, M. et al. (2013). "Network In Network." arXiv:1312.4400.
- Simonyan, K., & Zisserman, A. (2014). "Very Deep CNNs for Large-Scale Image Recognition." arXiv:1409.1556.
'AI > 딥러닝' 카테고리의 다른 글
CNN의 주요 계층 - Fully Connected Layer (완전 연결 층) (0) | 2025.02.11 |
---|---|
CNN의 주요 계층 - 전개 층(Flatten Layer) (0) | 2025.02.03 |
CNN의 주요 계층 - Convolutional Layer (합성곱 층) 정리 (0) | 2025.02.01 |
CNN 이란? (0) | 2025.02.01 |
딥러닝 용어사전 사이트 (0) | 2024.07.23 |