Notice
Recent Posts
Recent Comments
Link
«   2025/08   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
Tags
more
Archives
Today
Total
관리 메뉴

kang's study

19일차 : 합성곱 신경망 시각화 본문

[학습 공간]/[혼공머신러닝]

19일차 : 합성곱 신경망 시각화

보끔밥0302 2022. 3. 3. 07:00

합성곱 신경망의 시각화

 

가중치 시각화

이미지를 입력하고 필터를 통해 특성맵을 만든다.
필터로 이미지와 관련된 부분은 가중치가 높은 영역으로 높은 출력값을 나타낸다.
필터로 배경과 관련된 부분은 가중치가 낮은 영역으로 낮은 출력값을 나타낸다.
In [1]:
from tensorflow import keras
In [26]:
# 코랩에서 실행하는 경우에는 다음 명령을 실행하여 best-cnn-model.h5 파일을 다운로드
# !wget https://github.com/rickiepark/hg-mldl/raw/master/best-cnn-model.h5
In [3]:
model = keras.models.load_model('best-cnn-model.h5')
 
층의 가중치 분포
In [4]:
model.layers
Out[4]:
[<keras.layers.convolutional.Conv2D at 0x281956c3490>,
 <keras.layers.pooling.MaxPooling2D at 0x281956c3b80>,
 <keras.layers.convolutional.Conv2D at 0x28195807100>,
 <keras.layers.pooling.MaxPooling2D at 0x28195807190>,
 <keras.layers.core.flatten.Flatten at 0x2819580e7f0>,
 <keras.layers.core.dense.Dense at 0x28195807bb0>,
 <keras.layers.core.dropout.Dropout at 0x281957c53a0>,
 <keras.layers.core.dense.Dense at 0x281956c3cd0>]
In [5]:
conv = model.layers[0]

print(conv.weights[0].shape, conv.weights[1].shape) 
# 합섭공 층을 만들 때 지정했던 필터와 가중치가 들어있다.
# cov2d가 3차원 데이터를 입력받으려함
 
(3, 3, 1, 32) (32,)
In [6]:
conv_weights = conv.weights[0].numpy()

print(conv_weights.mean(), conv_weights.std())
 
-0.025233138 0.26420444
In [7]:
import matplotlib.pyplot as plt
In [8]:
plt.hist(conv_weights.reshape(-1, 1)) # 2번째 차원이 1이 되도록 하나의 열 벡터로 만듬
plt.xlabel('weight')
plt.ylabel('count')
plt.show()
# 배열의 개수 3*3*1*32 개이다.
# 0이 많다 -> 어떤 특성을 방지하기위한 학습으로 보인다.
 
 
층의 가중치 시각화
In [9]:
fig, axs = plt.subplots(2, 16, figsize=(15,2))

for i in range(2):
    for j in range(16):
        axs[i, j].imshow(conv_weights[:,:,0,i*16 + j], vmin=-0.5, vmax=0.5)
        axs[i, j].axis('off')

plt.show()
# 3by3의 32개 그림
# 가중치의 최소와 최대 범위가 동일한 범위를 갖도록 지정
# 음수값일 수록 짙어진다. -> 어두운 부분일거라 예측
 
In [10]:
no_training_model = keras.Sequential()

no_training_model.add(keras.layers.Conv2D(32, kernel_size=3, activation='relu', 
                                          padding='same', input_shape=(28,28,1)))
In [11]:
no_training_conv = no_training_model.layers[0]

print(no_training_conv.weights[0].shape)
 
(3, 3, 1, 32)
In [12]:
no_training_weights = no_training_conv.weights[0].numpy()

print(no_training_weights.mean(), no_training_weights.std())
 
-0.0046144626 0.08000212
In [13]:
plt.hist(no_training_weights.reshape(-1, 1))
plt.xlabel('weight')
plt.ylabel('count')
plt.show()
 
In [14]:
fig, axs = plt.subplots(2, 16, figsize=(15,2))

for i in range(2):
    for j in range(16):
        axs[i, j].imshow(no_training_weights[:,:,0,i*16 + j], vmin=-0.5, vmax=0.5)
        axs[i, j].axis('off')

plt.show()
 
 

함수형 API

합성곱층의 활성화 순서 파악
sequential()는 add메서드를 사용해서 순차적으로 층을 추가하였다.
funtional()는 층의 출력과 입력을 자유롭게 조합해서 좀 더 복잡한 모델을 만들 수 있다.
 
sequential()은 InputLayer클래스를 자동으로 추가해준다.
In [15]:
print(model.input)
 
KerasTensor(type_spec=TensorSpec(shape=(None, 28, 28, 1), dtype=tf.float32, name='conv2d_input'), name='conv2d_input', description="created by layer 'conv2d_input'")
 

특성 맵 시각화

In [16]:
conv_acti = keras.Model(model.input, model.layers[0].output)
# model.layers[0]는 Conv2D이다
In [17]:
(train_input, train_target), (test_input, test_target) = keras.datasets.fashion_mnist.load_data()
In [18]:
plt.imshow(train_input[0], cmap='gray_r')
plt.show()
 
 
첫 번째 특성 맵 시각화
In [19]:
inputs = train_input[0:1].reshape(-1, 28, 28, 1)/255.0
# 훈련데이터의 첫 번째 원소를 넣어봤다

feature_maps = conv_acti.predict(inputs)
In [20]:
print(feature_maps.shape)
 
(1, 28, 28, 32)
In [21]:
fig, axs = plt.subplots(4, 8, figsize=(15,8))

for i in range(4):
    for j in range(8):
        axs[i, j].imshow(feature_maps[0,:,:,i*8 + j])
        axs[i, j].axis('off')

plt.show()
# 가중치 시각화 부분의 실제 이미지를 볼 수 있다
# 각 가중치가 어떤 패턴을 학습하여 출력을 만들어내는지 짐작가능하다
 
 
두 번째 특성 맵 시각화
In [22]:
conv2_acti = keras.Model(model.input, model.layers[2].output)
# 64개
# 맥스풀링을 지나 가로세로 크기 줄어듬
In [23]:
feature_maps = conv2_acti.predict(train_input[0:1].reshape(-1, 28, 28, 1)/255.0)
In [24]:
print(feature_maps.shape)
 
(1, 14, 14, 64)
In [25]:
fig, axs = plt.subplots(8, 8, figsize=(12,12))

for i in range(8):
    for j in range(8):
        axs[i, j].imshow(feature_maps[0,:,:,i*8 + j])
        axs[i, j].axis('off')

plt.show()
# 층이 깊어질수록 고수준 특성을 학습하여 추상적으로 표현되어 직접 보고 이해하기는 어려워진다.
 

출처 : 박해선, 『혼자공부하는머신러닝+딥러닝』, 한빛미디어(2021), p444-460

'[학습 공간] > [혼공머신러닝]' 카테고리의 다른 글

21일차 : LSTM과 GRU  (0) 2022.03.03
20일차 : 순환 신경망  (0) 2022.03.03
18일차 : 합성곱 신경망  (0) 2022.03.03
17일차 : 신경망 모델  (0) 2022.03.03
16일차 : 심층 신경망  (0) 2022.03.03
Comments