이미지를 로드하고 전처리하는 코드입니다.
import cv2
import matplotlib.pyplot as plt
%matplotlib inline
# 자신의 이미지 파일 경로로 변경 가능합니다
img_path = 'images/udacity_sdc.png'
# 컬러 이미지 로드
bgr_img = cv2.imread(img_path)
# 그레이스케일로 변환
gray_img = cv2.cvtColor(bgr_img, cv2.COLOR_BGR2GRAY)
# 값을 [0,1] 범위로 정규화
gray_img = gray_img.astype("float32") / 255
# 이미지 출력
plt.imshow(gray_img, cmap='gray')
plt.show()
필터 정의 및 시각화
import numpy as np
# 필터 값을 자유롭게 수정할 수 있습니다
filter_vals = np.array([[-1, -1, 1, 1],
[-1, -1, 1, 1],
[-1, -1, 1, 1],
[-1, -1, 1, 1]])
print('Filter shape: ', filter_vals.shape)
Filter shape: (4, 4)
# 기본 필터의 선형 조합으로 4개 필터 생성
filter_1 = filter_vals
filter_2 = -filter_1
filter_3 = filter_1.T
filter_4 = -filter_3
filters = np.array([filter_1, filter_2, filter_3, filter_4])
print('Filter 1: \n', filter_1)
합성곱 레이어 및 풀링 레이어 정의
정의된 필터들을 가중치로 가지는 합성곱 레이어와 (4,4) 크기의 최대 풀링 레이어를 생성합니다.
import torch
import torch.nn as nn
import torch.nn.functional as F
class Net(nn.Module):
def __init__(self, weight):
super(Net, self).__init__()
k_height, k_width = weight.shape[2:]
# 4개의 그레이스케일 필터를 사용하는 합성곱 레이어
self.conv = nn.Conv2d(1, 4, kernel_size=(k_height, k_width), bias=False)
self.conv.weight = torch.nn.Parameter(weight)
# 최대 풀링 레이어 (4x4)
self.pool = nn.MaxPool2d(4, 4)
def forward(self, x):
# 합성곱 레이어 출력 (활성화 전)
conv_x = self.conv(x)
# ReLU 활성화 적용
activated_x = F.relu(conv_x)
# 풀링 레이어 적용
pooled_x = self.pool(activated_x)
return conv_x, activated_x, pooled_x
# 필터를 텐서로 변환하여 모델 초기화
weight = torch.from_numpy(filters).unsqueeze(1).type(torch.FloatTensor)
model = Net(weight)
print(model)
Net( (conv): Conv2d(1, 4, kernel_size=(4, 4), stride=(1, 1), bias=False) (pool): MaxPool2d(kernel_size=4, stride=4, padding=0, dilation=1, ceil_mode=False) )
각 필터 출력 시각화
레이어 출력을 시각화하기 위한 헬퍼 함수를 정의합니다.
def viz_layer(layer, n_filters=4):
fig = plt.figure(figsize=(20, 20))
for i in range(n_filters):
ax = fig.add_subplot(1, n_filters, i+1, xticks=[], yticks=[])
ax.imshow(np.squeeze(layer[0,i].data.numpy()), cmap='gray')
ax.set_title('Output %s' % str(i+1))
ReLU 활성화 이후의 합성곱 레이어 출력을 확인합니다.
# 원본 이미지 출력
plt.imshow(gray_img, cmap='gray')
# 모든 필터 시각화
fig = plt.figure(figsize=(12, 6))
fig.subplots_adjust(left=0, right=1.5, bottom=0.8, top=1, hspace=0.05, wspace=0.05)
for i in range(4):
ax = fig.add_subplot(1, 4, i+1, xticks=[], yticks=[])
ax.imshow(filters[i], cmap='gray')
ax.set_title('Filter %s' % str(i+1))
# 이미지를 텐서로 변환
gray_img_tensor = torch.from_numpy(gray_img).unsqueeze(0).unsqueeze(1)
# 모든 레이어 출력 계산
conv_layer, activated_layer, pooled_layer = model(gray_img_tensor)
# 활성화된 합성곱 레이어 출력 시각화
viz_layer(activated_layer)
풀링 레이어 출력 시각화
풀링 레이어는 합성곱 레이어의 특성 맵을 입력으로 받아, 각 커널 영역 내 최대값만 유지하여 차원을 축소합니다.
# 풀링 레이어 출력 시각화
viz_layer(pooled_layer)