PyTorch 특정 레이어 시각화 방법

이미지를 로드하고 전처리하는 코드입니다.

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)

태그: PyTorch CNN 레이어 시각화 합성곱 신경망 MaxPooling

5월 21일 02:42에 게시됨