이건 convolution을 각 레이어 및 필터 마다 나오는 이미지 혹은 필터값을 특정하기 위해서 찾은 강의를 따라한 것이다.
This tutorial is divided into four parts; they are:
- Visualizing Convolutional Layers
- Pre-fit VGG Model
- How to Visualize Filters
- How to Visualize Feature Maps
환경 변수
tensorflow = 2.4.0
kereas = 2.4.3
1. Visualizing Convolutional Layers
신경망 모델은 일반적으로 불투명하다고합니다. 이것은 특정 결정이나 예측을 한 이유를 설명하는 데 부족하다는 것을 의미합니다.
컨볼 루션 신경망은 이미지 데이터와 함께 작동하도록 설계되었으며 그 구조와 기능은 다른 유형의 신경망보다 이해하기 어려운 측면이 있습니다.
특히, 모델은 작은 선형 필터와 활성화 맵 또는보다 일반적으로 기능 맵이라는 필터를 적용한 결과로 구성됩니다.
필터와 기능 맵을 모두 시각화 할 수 있습니다.
예를 들어, 라인 감지기와 같은 작은 필터를 설계하고 이해할 수 있습니다. 학습 된 컨볼 루션 신경망 내에서 필터를 시각화하면 모델 작동 방식에 대한 통찰력을 얻을 수 있습니다.
입력 이미지에 필터를 적용하고 이전 계층에서 출력 한 기능 맵에 생성 된 기능 맵은 모델의 특정 입력 지점에서 모델이 갖는 내부 표현에 대한 통찰력을 제공 할 수 있습니다.
이 튜토리얼에서는 컨볼 루션 신경망을 시각화하는 두 가지 접근 방식을 모두 살펴볼 것입니다.
2. Pre-fit VGG Model
시각화 해볼 모델은 VGG16입니다. keras에서 불러오기도 쉽고 사용하기도 쉬운데 성능이 좋기 때문입니다.
# load vgg model
from keras.applications.vgg16 import VGG16
# load the model
model = VGG16()
# summarize the model
model.summary()
# load vgg model
from keras.applications.vgg16 import VGG16
# load the model
model = VGG16()
# summarize the model
model.summary()
예제를 실행하면 모델 가중치가 메모리에로드되고로드 된 모델구조가 인쇄됩니다.
Model: "vgg16"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_1 (InputLayer) [(None, 224, 224, 3)] 0
_________________________________________________________________
block1_conv1 (Conv2D) (None, 224, 224, 64) 1792
_________________________________________________________________
block1_conv2 (Conv2D) (None, 224, 224, 64) 36928
_________________________________________________________________
block1_pool (MaxPooling2D) (None, 112, 112, 64) 0
_________________________________________________________________
block2_conv1 (Conv2D) (None, 112, 112, 128) 73856
_________________________________________________________________
block2_conv2 (Conv2D) (None, 112, 112, 128) 147584
_________________________________________________________________
block2_pool (MaxPooling2D) (None, 56, 56, 128) 0
_________________________________________________________________
block3_conv1 (Conv2D) (None, 56, 56, 256) 295168
_________________________________________________________________
block3_conv2 (Conv2D) (None, 56, 56, 256) 590080
_________________________________________________________________
block3_conv3 (Conv2D) (None, 56, 56, 256) 590080
_________________________________________________________________
block3_pool (MaxPooling2D) (None, 28, 28, 256) 0
_________________________________________________________________
block4_conv1 (Conv2D) (None, 28, 28, 512) 1180160
_________________________________________________________________
block4_conv2 (Conv2D) (None, 28, 28, 512) 2359808
_________________________________________________________________
block4_conv3 (Conv2D) (None, 28, 28, 512) 2359808
_________________________________________________________________
block4_pool (MaxPooling2D) (None, 14, 14, 512) 0
_________________________________________________________________
block5_conv1 (Conv2D) (None, 14, 14, 512) 2359808
_________________________________________________________________
block5_conv2 (Conv2D) (None, 14, 14, 512) 2359808
_________________________________________________________________
block5_conv3 (Conv2D) (None, 14, 14, 512) 2359808
_________________________________________________________________
block5_pool (MaxPooling2D) (None, 7, 7, 512) 0
_________________________________________________________________
flatten (Flatten) (None, 25088) 0
_________________________________________________________________
fc1 (Dense) (None, 4096) 102764544
_________________________________________________________________
fc2 (Dense) (None, 4096) 16781312
_________________________________________________________________
predictions (Dense) (None, 1000) 4097000
=================================================================
Total params: 138,357,544
Trainable params: 138,357,544
Non-trainable params: 0
_________________________________________________________________
Process finished with exit code 0
3. How to Visualize Filters
수행 할 가장 간단한 시각화는 학습 된 필터를 직접 플로팅하는 것입니다.
신경망 용어에서 학습 된 필터는 단순히 가중치이지만 필터의 특수한 2 차원 구조로 인해 가중치 값은 서로 공간적 관계를 가지며 각 필터를 2 차원 이미지로 플로팅하는 것은 의미가 있습니다
첫 번째 단계는 모델의 필터를 검토하여 작업해야하는 사항을 확인하는 것입니다.
이전 섹션에서 인쇄 된 모델 요약은 각 레이어의 출력 모양 (예 : 결과 피쳐 맵의 모양)을 요약합니다. 네트워크에서 필터 (가중치)의 모양에 대한 아이디어는 제공하지 않으며 레이어 당 총 가중치 수만 제공합니다.
model.layers 속성을 통해 모델의 모든 계층에 액세스 할 수 있습니다 .
각 레이어에는 layer.name 속성이 있습니다. 여기서 컨볼 루션 레이어에는 block # _conv # 와 같은 명명 컨볼 루션이 있습니다. 여기서 ' # '는 정수입니다. 따라서 각 레이어의 이름을 확인하고 ' conv ' 문자열이 포함되지 않은 레이어는 건너 뛸 수 있습니다.
# summarize filter shapes
for layer in model.layers:
# check for convolutional layer
if 'conv' not in layer.name:
continue
각 컨벌루션 계층에는 두 세트의 가중치가 있습니다.
하나는 필터 블록이고 다른 하나는 바이어스 값 블록입니다. layer.get_weights () 함수 를 통해 액세스 할 수 있습니다. 이러한 가중치를 검색 한 다음 그 모양을 요약 할 수 있습니다.
# get filter weights
filters, biases = layer.get_weights()
print(layer.name, filters.shape)
전체 코드 입니다.
# summarize filters in each convolutional layer
from keras.applications.vgg16 import VGG16
from matplotlib import pyplot
# load the model
model = VGG16()
# summarize filter shapes
for layer in model.layers:
# check for convolutional layer
if 'conv' not in layer.name:
continue
# get filter weights
filters, biases = layer.get_weights()
print(layer.name, filters.shape)
밑에는 그 결과 입니다.
block1_conv1 (3, 3, 3, 64)
block1_conv2 (3, 3, 64, 64)
block2_conv1 (3, 3, 64, 128)
block2_conv2 (3, 3, 128, 128)
block3_conv1 (3, 3, 128, 256)
block3_conv2 (3, 3, 256, 256)
block3_conv3 (3, 3, 256, 256)
block4_conv1 (3, 3, 256, 512)
block4_conv2 (3, 3, 512, 512)
block4_conv3 (3, 3, 512, 512)
block5_conv1 (3, 3, 512, 512)
block5_conv2 (3, 3, 512, 512)
block5_conv3 (3, 3, 512, 512)
모든 컨벌루션 레이어는 작고 해석하기 쉬운 3x3 필터를 사용한다는 것을 알 수 있습니다.
컨벌루션 신경망의 구조적 문제는 필터의 깊이가 필터에 대한 입력 깊이 (예 : 채널 수)와 일치해야한다는 것입니다.
빨강, 녹색 및 파랑에 대해 3 개의 채널이있는 입력 이미지의 경우 각 필터의 깊이가 3임을 알 수 있습니다 (여기서는 채널-마지막 형식으로 작업 함). 하나의 필터를 각 채널에 대해 하나씩 세 개의 이미지가있는 플롯으로 시각화하거나 세 개를 모두 단일 색상 이미지로 압축하거나 첫 번째 채널을보고 다른 채널이 동일하게 보일 것이라고 가정 할 수도 있습니다. 문제는 시각화하고 싶은 63 개의 다른 필터가 있다는 것입니다.
다음과 같이 첫 번째 레이어에서 필터를 검색 할 수 있습니다.
# retrieve weights from the second hidden layer
filters, biases = model.layers[1].get_weights()
가중치 값은 0.0을 중심으로하는 작은 양수 및 음수 값일 수 있습니다.
값을 쉽게 시각화 할 수 있도록 0-1 범위로 정규화 할 수 있습니다.(정규화에 대한 자세한 이야기는 다른 페이지에서 자세히 다루도록 하겠습니다.)
# normalize filter values to 0-1 so we can visualize them
f_min, f_max = filters.min(), filters.max()
filters = (filters - f_min) / (f_max - f_min)
이제 블록의 64 개 중 처음 6 개 필터를 열거하고 각 필터의 3 개 채널을 각각 플로팅 할 수 있습니다.
matplotlib 라이브러리를 사용하고 각 필터를 새로운 서브 플롯 행으로 플로팅하고 각 필터 채널 또는 깊이를 새 열로 플로팅합니다.
# plot first few filters
n_filters, ix = 6, 1
for i in range(n_filters):
# get the filter
f = filters[:, :, :, i]
# plot each channel separately
for j in range(3):
# specify subplot and turn of axis
ax = pyplot.subplot(n_filters, 3, ix)
ax.set_xticks([])
ax.set_yticks([])
# plot filter channel in grayscale
pyplot.imshow(f[:, :, j], cmap='gray')
ix += 1
# show the figure
pyplot.show()
아래는 전체 코드입니다
# cannot easily visualize filters lower down
from keras.applications.vgg16 import VGG16
from matplotlib import pyplot
# load the model
model = VGG16()
# retrieve weights from the second hidden layer
filters, biases = model.layers[1].get_weights()
# normalize filter values to 0-1 so we can visualize them
f_min, f_max = filters.min(), filters.max()
filters = (filters - f_min) / (f_max - f_min)
# plot first few filters
n_filters, ix = 6, 1
for i in range(n_filters):
# get the filter
f = filters[:, :, :, i]
# plot each channel separately
for j in range(3):
# specify subplot and turn of axis
ax = pyplot.subplot(n_filters, 3, ix)
ax.set_xticks([])
ax.set_yticks([])
# plot filter channel in grayscale
pyplot.imshow(f[:, :, j], cmap='gray')
ix += 1
# show the figure
pyplot.show()
예제를 실행하면 각 필터에 대해 한 행, 각 채널에 대해 한 열에 대해 18개의 이미지가 출력된다.
어떤 경우에는 필터가 채널(첫 번째 행)에서 동일하고 다른 경우(마지막 행)필터가 다르다는 것을 알 수 있습니다.
어두운 사각형은 weight 부분이 작은 부분이고 밝은 사각형은 큰 weight를 나타내는데 이 직관을 활용하면 첫 번째 행의 필터가 왼쪽 상단의 빛에서 오른쪽 하단의 어두운 곳으로의 그라디언트를 감지하는다는 것을 알 수 있습니다.
시각화가 있지만 첫 번째 컨볼 루션 레이어의 64 개 필터 중 처음 6 개만 볼 수 있습니다. 64 개의 모든 필터를 하나의 이미지로 시각화하는 것이 가능합니다.
두 번째 컨벌루션 레이어에서 필터를 살펴 보려면 다시 64 개의 필터가 있지만 각 필터에는 입력 특성 맵과 일치하는 64 개의 채널이 있음을 알 수 있습니다. 64 개 필터 모두에 대해 한 행에있는 모든 64 개 채널을 보려면 (64x64) 4,096 개의 서브 플롯이 필요하므로 세부 정보를 확인하기 어려울 수 있습니다.
'vison_study' 카테고리의 다른 글
Chap3. 신경망 (밑바닥부터 딥러닝) (0) | 2021.12.27 |
---|---|
2.1 퍼셉트론 (밑바닥부터 딥러닝) (0) | 2021.12.22 |
Torch tensor to numpy(in use Opencv) (0) | 2021.06.28 |
Vison Study #2 (0) | 2021.06.27 |