on
5장 합성곱 신경망Ⅰ(3) 실습 - 특성맵 시각화
5장 합성곱 신경망Ⅰ(3) 실습 - 특성맵 시각화
1. 새로운 모델 생성
합성곱층, 최대풀링층 쌍을 4개 쌓고, 완전연결층을 순차적으로 쌓음
model = tf.keras.models.Sequential([
tf.keras.layers.Conv2D(input_shape=( 100 , 100 , 3 ), activation=' relu ', kernel_size=( 5, 5 ), filters= 32 ),
tf.keras.layers.MaxPooling2D(),
tf.keras.layers.Conv2D(activation=' relu ', kernel_size=( 5 , 5 ), filters= 64 ),
tf.keras.layers.MaxPooling2D(),
tf.keras.layers.Conv2D(activation=' relu ', kernel_size=( 5, 5 ), filters= 64 ),
tf.keras.layers.MaxPooling2D(),
tf.keras.layers.Conv2D(activation=' relu ', kernel_size=( 5, 5 ), filters= 64 ),
tf.keras.layers.MaxPooling2D(),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense( 128 , activation=' relu '),
tf.keras.layers.Dense( 64 , activation=' relu '),
tf.keras.layers.Dense( 32 , activation=' relu '),
tf.keras.layers.Dense( 2 , activation=' softmax ')
])
ⓐ Conv2D : 합성곱층
- input_shape : (행, 열, 채널 수)
- activation = 'relu' : 은닉층에 주로 쓰이는 활성화 함수
* 활성화 함수 : 각 노드에 가중치를 곱하고 bias를 더한 값이 넘어갈때 특정 조건을 만족하면 활성화 함수에 의해 활성화 되었다는
신호를(활성화 함수를 거친 출력값) 다음 노드로 보내 활성화하고, 조건을 만족하지 못했으면 해당 노드를 비활성화함
- 가중치 : 커널 크기 × 필터 수 (예: (5 × 5) × 64 = 1600개)
ⓑ Dense : 밀집층, 완전연결층
- 첫번째 인자 : 출력 노드(뉴런)의 수
https://dsbook.tistory.com/59
2. 특성맵 정의
특성맵 = 합성곱층을 입력 이미지와 필터를 연산해서 얻은 결과
⇒ 합성곱층의 입력과 출력을 확인하면, 특성 맵에 대한 시각화가 가능할 것
ins = model.inputs #모델 입력으로 (None, 100, 100, 3)의 형태를 가짐(1에서 정의)
outs = model.layers[ 0 ].output # 첫번째 계층 에 대한 출력 형태 : (None, 96, 96, 32)
feature_map = Model(inputs=ins, outputs=outs) #ins, outs를 모델 입력과 출력으로 사용, 특성 맵을 정의
feature_map.summary()
첫번째 계층의 모델
- CNN의 output shape : (batch_size, height, width, depth(channel))
3. 이미지 전처리 및 특성맵 확인
img = plt.imread('../chap5/data/cat.jpg')
img = cv2.resize(img, (100, 100)) #이미지 크기 조정
input_img = np. expand_dims (img, axis=0) #이미지 차원 조정
print(input_img.shape) #입력 이미지 형태 출력
feature = feature_map.predict(input_img) #이미지를 모델에 적용
print(feature.shape) #특성 맵에 대한 형태 출력
fig = plt.figure(figsize=(50, 50))
for i in range(16): #이미지 16개 출력
ax = fig.add_subplot(8, 4, i+1) #subplot(m, n, p)는 , p로 지정된 위치에 좌표축을 만듦
ax.imshow(feature[0, :, :, i])
원본 이미지 첫번째 계층 출력 결과
→ 입력층과 가까운 계층으로 입력 이미지의 형태가 많이 유지되고 있음
ⓐ expand_dims()
nums = np.array([2, 5]) #nums.shape=(2, )
axis_0 = np. expand_dims (nums, axis= 0 )
axis_1 = np. expand_dims (nums, axis= 1 )
expand_dims 예시
4. 여섯 번째 계층에 대한 특성맵
ins = model.inputs //모델 입력으로 (None, 224, 224, 3)의 형태
outs = model.layers[ 6 ].output //여섯 번째 계층에 대한 출력으로 None, 1000)
feature_map = Model(inputs=ins, outputs=outs)
...
여섯번째 계층 출력 결과
원래 입력 이미지의 형태X
=> 출력층에 가까울 수록 원형은 사라지고 이미지 특징만 전달되는 것을 확인 가능
conv2D 참고 : https://tykimos.github.io/2017/01/27/CNN_Layer_Talk/conv
활성화 함수 참고 : https://dsbook.tistory.com/59
Q. 완전연결층(dense)을 여러개 쌓는 것은 출력노드를 점차적으로 줄이기 위한 것인가?(그렇다면 한번에 줄이는건 안되나?)
from http://markme-inur.tistory.com/36 by ccl(A) rewrite - 2021-08-08 21:00:38