convnet_from_scratch_with_augmentation.keras
🔸 활용할 이미지(1장) 다운로드
# 이미지 다운로드
img = keras.utils.get_file(fname = 'cat.jpg', origin = 'https://img-datasets.s3.amazonaws.com/cat.jpg')
img
/root/.keras/datasets/cat.jpg
🔸 이미지 출력 함수, 이미지 텐서 저장
# 함수
def get_img_array(img, target_size):
# 이미지 로드
img = keras.utils.load_img(img, target_size=target_size)
# 이미지 배열화
array = keras.utils.img_to_array(img)
# 이미지 배치변환을 위한 차원 추가(samples,height,widht,channel)
array = np.expand_dims(array,axis=0)
return array
img_tensor = get_img_array(img, target_size=(180,180))
🔸 이미지 출력
keras.utils.load_img(img, target_size=(180,180))
# 이미지 출력
# img_tensor의 크기는(1,180,180,3)
# 1개의 sample만 가지고 있지만 항상 슬라이싱으로 한 개의 sample을 불러야 한다
import matplotlib.pyplot as plt
plt.axis('off')
plt.imshow(img_tensor[0].astype('uint8'))
plt.show()
🔸 각 층의 활성화(output)을 반환하는 모델 생성
# cat vs dog에 사용한 model 불러오기
model = keras.models.load_model('convnet_from_scratch_with_augmentation.keras')
# 층 활성화 반영하는 모델 생성
from keras import layers
layer_outputs = []
layer_names = []
for layer in model.layers:
# layer가 컨브넷층이나 풀링층일 경우, 그 layer의 output 리스트에 추가
if isinstance(layer, (layers.Conv2D, layers.MaxPool2D)):
layer_outputs.append(layer.output)
layer_names.append(layer.name)
activation_model = keras.Model(inputs = model.input, outputs=layer_outputs)
🔸 층 활성화 계산(적용,예측)
# 활성화 계산
# 층 활성화마다 배열 하나씩, 총 9개(컨브와 풀링층의 개수)의 배열을 가진 리스트 반환
activations= activation_model.predict(img_tensor)
🔸 모델의 첫번째 층 확인(5번째 필터)
# 첫번째 층의 5번째 피처 그리기
import matplotlib.pyplot as plt
print(activations[0].shape)
plt.matshow(activations[0][0,:,:,5],cmap='viridis')
plt.axis('off')
plt.show()
(1, 178, 178, 32)
🔸 모든 층의 활성화 확인
# 모든 층의 활성화에 있는 전체 채널 시각화
# 이미지그리드 행 개수
images_per_row = 16
for layer_name, layer_activation in zip(layer_names, activations):
# layer_activation(1,size,size,n_features)
n_features = layer_activation.shape[-1]
size = layer_activation.shape[1]
# 모든 피처를 그릴 그리드 준비
n_cols = n_features // images_per_row
display_grid = np.zeros(((size + 1) * n_cols - 1,
images_per_row * (size + 1) - 1))
for col in range(n_cols):
for row in range(images_per_row):
# 하나의 채널 이미지
channel_index = col * images_per_row + row
channel_image = layer_activation[0, :, :, channel_index].copy()
# 채널값 정규화[0,255], 모두 0인 채널은 그대로
if channel_image.sum() != 0:
channel_image -= channel_image.mean()
channel_image /= channel_image.std()
channel_image *= 64
channel_image += 128
channel_image = np.clip(channel_image, 0, 255).astype("uint8")
# 이미지그리드에 채널 행렬 밀어 넣기
display_grid[
col * (size + 1): (col + 1) * size + col,
row * (size + 1) : (row + 1) * size + row] = channel_image
# 이미지 그리드 출력
scale = 1. / size
plt.figure(figsize=(scale * display_grid.shape[1],
scale * display_grid.shape[0]))
plt.title(layer_name)
plt.grid(False)
plt.axis("off")
plt.imshow(display_grid, aspect="auto", cmap="viridis")