ResNet 모델 + gradCAM

공부·2022년 11월 3일
0

층이 깊어질 수록 특징을 잘 뽑아주나
미분 값은 작아지기 때문에 값이 없어짐.

conv1_bn (BatchNormalization)

배치 노멀라이제이션 방법
: 다 전달하는 게 아니라 배치사이즈를 임의로 뽑을 때 값들을 정규화시키면 기울기 소멸문제를 해결할 수 있음. (drop out을 중간 중간에 넣어주듯이)

avg_pool (GlobalAveragePooling (None, 2048) 0 ['conv5_block3_out[0][0]']
2D)

heap맵을 생성 후 이미지에 씌움.

img=image.load_img(image_path,target_size=(224,224))

224x224로 로드

x=image.img_to_array(img)
x=np.expand_dims(x,axis=0)
x=resnet50.preprocess_input(x) # 정규화 하는 함수

:숫자로 다 바꿔서 삽입해야 함 (이미지 -> array)
:동일하게 225로 나눠주는 것보다 그 값들을 정규화할 수 있는 값들로 만듦.

preds=model.predict(x)
print("예측 결과:", resnet50.decode_predictions(preds,top=5)[0])

예측 결과: [('n01833805', 'hummingbird', 0.9998385), ('n01843065', 'jacamar', 0.0001058815), ('n02280649', 'cabbage_butterfly', 1.0400288e-05), ('n01806143', 'peacock', 8.702704e-06), ('n02190166', 'fly', 4.189648e-06)]

:ResNet 모델을 예측
1000개 카테고리를 예측하기 때문에 1000개의 각각 가능성이 뭔지 보여주기 때문에, 그 결과를 다 보기 힘드므로 가장 가능성 높은 5개를 보여줌.

last_conv_layer=model.get_layer("conv5_block3_out")

model_1=keras.Model(model.inputs,last_conv_layer.output)
  • 맨 마지막 컨볼루션 층. (AveragePooling의 바로 전층_smmary에서 확인)
  • 컨볼루션 -> 마지막까지 학습시킨 곳
input_2=keras.Input(shape=last_conv_layer.output.shape[1:])
x_2=model.get_layer("avg_pool")(input_2)
x_2=model.get_layer("predictions")(x_2) 
model_2=keras.Model(input_2,x_2)
  • 모델2
with tf.GradientTape() as tape:
    output_1=model_1(x)
    tape.watch(output_1) # 마지막 층으로 미분하기 위한 준비
    preds=model_2(output_1)
    class_id=tf.argmax(preds[0])
    output_2=preds[:,class_id]
  • 모델 1을 모델2로 미분하는 함수
grads=tape.gradient(output_2,output_1) # 그레이디언트 계산
pooled_grads=tf.reduce_mean(grads,axis=(0,1,2)) # 식 (12.5) 적용
  • 그 미분 값에 특징맵들을 다 곱해줌
output_1=output_1.numpy()[0]
pooled_grads=pooled_grads.numpy()
for i in range(pooled_grads.shape[-1]): # 식 (12.6) 적용
    output_1[:,:,i]*=pooled_grads[i]
heatmap=np.mean(output_1,axis=-1)

heatmap=np.maximum(heatmap,0)/np.max(heatmap) # [0,1]로 정규화
plt.matshow(heatmap)

  • heap 맵
# 열지도를 입력 영상에 덧씌움
img=image.load_img(image_path) # 입력 영상을 다시 받아옴

img=image.img_to_array(img)
heatmap=np.uint8(255*heatmap) # [0,255]로 변환

color_heatmap=keras.preprocessing.image.array_to_img(color_heatmap)
color_heatmap=color_heatmap.resize((img.shape[1],img.shape[0]))
color_heatmap=keras.preprocessing.image.img_to_array(color_heatmap)

overlay_img=color_heatmap*0.4+img # 덧씌움
overlay_img=keras.preprocessing.image.array_to_img(overlay_img)
plt.matshow(overlay_img)

  • 최종 heap 맵을 이미지에 씌움 (원본 이미지에 씌우기 위해서 변화시킬 수 있어야함_원본이미지로 다시 만든 후 heap맵에 씌움.)
profile
리액트

0개의 댓글