인공지능/공부

CAM 실습 - MNIST, TensorFlow

이게될까 2023. 12. 14. 14:48
728x90
728x90
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
from tensorflow.keras.datasets import mnist
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, GlobalAveragePooling2D, Dense
from tensorflow.keras.utils import to_categorical

# MNIST 데이터셋 불러오기
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()

# 데이터 전처리
train_images = np.expand_dims(train_images, -1).astype('float32') / 255.0
test_images = np.expand_dims(test_images, -1).astype('float32') / 255.0
train_labels = to_categorical(train_labels, 10)
test_labels = to_categorical(test_labels, 10)

# 모델 구성
input_tensor = Input(shape=(28, 28, 1))
x = Conv2D(32, (3, 3), padding='same')(input_tensor)
x = BatchNormalization()(x)
x = Activation('relu')(x)
x = Conv2D(64, (3, 3), padding='same')(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
x = Conv2D(128, (3, 3), padding='same')(x)
x = BatchNormalization()(x)
x = Activation('relu')(x)
x = GlobalAveragePooling2D()(x)
output_tensor = Dense(10, activation='softmax')(x)

model = Model(input_tensor, output_tensor)

# 모델 컴파일
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

# 모델 학습 (실제 사용시에는 epochs를 더 늘려야 함)
model.fit(train_images, train_labels, batch_size=64, epochs=1, validation_split=0.1)

여기는 어태까지 했던 CNN이랑 큰 다를바는 없습니다. maxpooling을 사용하지 않아 피쳐맵의 크기를 그대로 가져왔습니다.

728x90
gap_weights = model.layers[-1].get_weights()[0] # 피쳐 특성 가지고오기 (각 맵마다 몇을 곱한지)
cam_model = Model(inputs=model.input, outputs=(model.layers[-3].output, model.output)) # 결과가 특성 맵, 예측 값 둘다 나온다.

# 테스트 이미지 여러 개 선택 (예: 처음 5개)
test_images_subset = test_images[:5] 
features, results = cam_model.predict(test_images_subset) # 결과 저장

# 클래스별 CAM 계산 및 시각화
for i in range(len(test_images_subset)):
    cam = (features[i] @ gap_weights[:, np.argmax(results[i])]).reshape((28, 28))# 실제 CAM을 계산합니다. 이는 각 특성 맵에 대한 가중치(해당 이미지가 속한다고 예측된 클래스에 대한)와 특성 맵을 곱한 것의 합으로, 이미지의 중요한 영역을 강조합니다.
    plt.figure(figsize=(12, 6))

    plt.subplot(1, 3, 1)
    plt.imshow(test_images_subset[i, :, :, 0], cmap='gray') # 실제 값 그리기 
    plt.title("Original Image")

    plt.subplot(1, 3, 2)
    plt.imshow(cam, cmap='jet') # 중요한 부분 그리기
    plt.title("Class Activation Map")

    plt.subplot(1, 3, 3)
    plt.imshow(test_images_subset[i, :, :, 0], cmap='gray', alpha=0.5) # 실제 값과 같이그려 확실하게 보기
    plt.imshow(cam, cmap='jet', alpha=0.5)
    plt.title(f"Overlay CAM for Class {np.argmax(results[i])}")

    plt.show()

 

결과를 보면 이렇게 나옵니다. 이를 통해 CAM의 개념보단 좀 더 확실하게 알 수 있었씁니다.

CAM 기본 개념은 밑에 남겨 두겠습니다.

2023.12.14 - [인공지능/공부] - 인공지능 CAM - 개념

 

인공지능 CAM - 개념

기존 CNN, FCN은 설명이 불가능하다.(출력만 나온다. API) CNN에서 중요한 부분은 높은 가중치를 받는다. -> 이걸 확인하면 우린 네트워크를 설명할 수 있다. CLASS ACTIVATION MAP - CAM 우린 이러한 이유로 C

yoonschallenge.tistory.com

max pooling에 대해선 여쭤봐야겠네요...

728x90