import torch
from fastai.vision.all import *
import cv2
import numpy as np
import os
'CUDA_LAUNCH_BLOCKING'] = "1"
os.environ["CUDA_VISIBLE_DEVICES"] = "0"
os.environ[import cv2
import numpy as np
import matplotlib.pyplot as plt
from PIL import ImageDraw
from PIL import ImageFont
from PIL import ImageFile
from PIL import Image
= True
ImageFile.LOAD_TRUNCATED_IMAGES from torchvision.utils import save_image
import os
[CAM]Grad CAM(Original, Randombox)
CAM
https://github.com/jacobgil/pytorch-grad-cam
https://hygradcam.blogspot.com/2020/11/blog-post.html
https://haystar.tistory.com/72
import
def label_func(f):
if f[0].isupper():
return 'cat'
else:
return 'dog'
=Path('original_pet')
path=get_image_files(path)
files=ImageDataLoaders.from_name_func(path,files,label_func,item_tfms=Resize(512)) dls
=Path('random_pet_one') #랜덤박스넣은사진
path_r=get_image_files(path_r)
files_r=ImageDataLoaders.from_name_func(path_r,files_r,label_func,item_tfms=Resize(512)) dls_r
학습
=cnn_learner(dls,resnet34,metrics=error_rate)
lrnr1) lrnr.fine_tune(
/home/csy/anaconda3/envs/temp_csy/lib/python3.8/site-packages/fastai/vision/learner.py:288: UserWarning: `cnn_learner` has been renamed to `vision_learner` -- please update your code
warn("`cnn_learner` has been renamed to `vision_learner` -- please update your code")
/home/csy/anaconda3/envs/temp_csy/lib/python3.8/site-packages/torchvision/models/_utils.py:208: UserWarning: The parameter 'pretrained' is deprecated since 0.13 and may be removed in the future, please use 'weights' instead.
warnings.warn(
/home/csy/anaconda3/envs/temp_csy/lib/python3.8/site-packages/torchvision/models/_utils.py:223: UserWarning: Arguments other than a weight enum or `None` for 'weights' are deprecated since 0.13 and may be removed in the future. The current behavior is equivalent to passing `weights=ResNet34_Weights.IMAGENET1K_V1`. You can also use `weights=ResNet34_Weights.DEFAULT` to get the most up-to-date weights.
warnings.warn(msg)
epoch | train_loss | valid_loss | error_rate | time |
---|---|---|---|---|
0 | 0.151488 | 0.016599 | 0.006089 | 30:31 |
0.00% [0/1 00:00<?]
epoch | train_loss | valid_loss | error_rate | time |
---|
81.52% [75/92 39:47<09:01 0.0289]
=lrnr.model[0]
net1=lrnr.model[1] net2
= torch.nn.Sequential(
net2 =1),
torch.nn.AdaptiveAvgPool2d(output_size
torch.nn.Flatten(),512,out_features=2,bias=False)) torch.nn.Linear(
=torch.nn.Sequential(net1,net2) net
=Learner(dls,net,metrics=accuracy) lrnr2
5) lrnr2.fine_tune(
0.00% [0/1 00:00<?]
epoch | train_loss | valid_loss | accuracy | time |
---|
10.87% [10/92 05:33<45:32 0.3704]
= ClassificationInterpretation.from_learner(lrnr2)
interp interp.plot_confusion_matrix()
=cnn_learner(dls_r,resnet34,metrics=error_rate)
lrnr_r1) lrnr_r.fine_tune(
=lrnr_r.model[0]
net1_r=lrnr_r.model[1] net2_r
= torch.nn.Sequential(
net2_r =1),
torch.nn.AdaptiveAvgPool2d(output_size
torch.nn.Flatten(),512,out_features=2,bias=False)) torch.nn.Linear(
=torch.nn.Sequential(net1_r,net2_r) net_r
=Learner(dls_r,net_r,metrics=accuracy) lrnr2_r
5) lrnr2_r.fine_tune(
= ClassificationInterpretation.from_learner(lrnr2_r)
interp_r interp_r.plot_confusion_matrix()
def compute_gradcam(learn, img):
with hook_output(learn.model[0]) as hook_a, hook_output(learn.model[0], grad=True) as hook_g:
= learn.model.eval()(x) # 모델 평가 모드 전환 -> 활성화 맵과 그레디언트를 변수로 저장하자.
preds 0, preds.argmax()].backward() # 모델이 평가 모드로 전환되면, 드롭아웃이 비활성화되고 배치 정규화의 이동 평균과 이동 분산이 업데이트되지 않는다.
preds[# 이 과정은 그레디언트 계산할 층 선택하는 과정
= hook_a.stored[0].cpu() # shape = torch.Size([1, 512, 16, 16]) -> torch.Size([512, 16, 16])
activation = hook_g.stored[0][0].cpu() # 값, 빈 값 -> 값의 shape = torch.Size([1, 512, 16, 16]) -> torch.Size([512, 16, 16])
gradient
= (activation * gradient).mean(0) # shape = torch.Size([16, 16]) 0번 축에 따라 mean 값 계산
grad_cam = np.maximum(grad_cam, 0) # shape = torch.Size([16, 16]) 0과 grad_cam 중 큰 것을 구별
grad_cam /= grad_cam.max() # \=은 나눗셈 후에 결과를 원래 변수에 할당하는 축약형 연산자, [0,1] 범위로 정규화하기 위함
grad_cam
return grad_cam
Original
= first(dls.test_dl([PILImage.create(get_image_files(path)[7])])) x,
= compute_gradcam(lrnr2,x) grad_cam
= plt.subplots(1,1)
fig, (ax1) 0].squeeze().show(ax=ax1)
dls.train.decode((x,))["cpu").detach(),alpha=0.5,extent=(0,511,511,0),interpolation='spline36',cmap='magma')
ax1.imshow((grad_cam).to(8)
fig.set_figwidth(8)
fig.set_figheight( fig.tight_layout()
= plt.subplots(5,5)
fig, ax =0
kfor i in range(5):
for j in range(5):
= first(dls.test_dl([PILImage.create(get_image_files(path)[k])]))
x, = compute_gradcam(lrnr2,x)
grad_cam 0].squeeze().show(ax=ax[i][j])
dls.train.decode((x,))["cpu").detach(),alpha=0.5,extent=(0,511,511,0),interpolation='spline36',cmap='magma')
ax[i][j].imshow((grad_cam).to(=k+1
k16)
fig.set_figwidth(16)
fig.set_figheight( fig.tight_layout()
Random box
= first(dls_r.test_dl([PILImage.create(get_image_files(path_r)[7])])) x_r,
= compute_gradcam(lrnr2_r,x_r) grad_cam_r
= plt.subplots(1,1)
fig, (ax1) 0].squeeze().show(ax=ax1)
dls_r.train.decode((x_r,))["cpu").detach(),alpha=0.5,extent=(0,511,511,0),interpolation='spline36',cmap='magma')
ax1.imshow((grad_cam_r).to(8)
fig.set_figwidth(8)
fig.set_figheight( fig.tight_layout()
= plt.subplots(5,5)
fig, ax =0
kfor i in range(5):
for j in range(5):
= first(dls_r.test_dl([PILImage.create(get_image_files(path_r)[k])]))
x, = compute_gradcam(lrnr2_r,x)
grad_cam_r 0].squeeze().show(ax=ax[i][j])
dls_r.train.decode((x,))["cpu").detach(),alpha=0.5,extent=(0,511,511,0),interpolation='spline36',cmap='magma')
ax[i][j].imshow((grad_cam_r).to(=k+1
k16)
fig.set_figwidth(16)
fig.set_figheight( fig.tight_layout()
Step by step
Original
CAT
= first(dls.test_dl([PILImage.create(get_image_files(path)[2])])) x,
= compute_gradcam(lrnr2,x) grad_cam
= plt.subplots(1,2)
fig, (ax1,ax2) #
0].squeeze().show(ax=ax1)
dls_r.train.decode((x,))["Input image")
ax1.set_title(#
0].squeeze().show(ax=ax2)
dls_r.train.decode((x,))["cpu").detach(),alpha=0.5,extent=(0,511,511,0),interpolation='bilinear',cmap='cool')
ax2.imshow((grad_cam).to("CAT PART")
ax2.set_title(#
# dls_r.train.decode((x,))[0].squeeze().show(ax=ax3)
# ax3.imshow((ybar_threshed2).to("cpu").detach(),alpha=0.5,extent=(0,511,511,0),interpolation='bilinear',cmap='cool')
# ax3.set_title("DOG PART")
#
12)
fig.set_figwidth(12)
fig.set_figheight( fig.tight_layout()
- 판단 근거가 강할 수록 파란색 -> 보라색
= net(x).tolist()[0] a,b
/ (np.exp(a)+np.exp(b)) , np.exp(b)/ (np.exp(a)+np.exp(b)) np.exp(a)
(0.9999999910101288, 8.989871077326127e-09)
DOG
= first(dls.test_dl([PILImage.create(get_image_files(path)[12])])) x,
= compute_gradcam(lrnr2,x) grad_cam
= plt.subplots(1,2)
fig, (ax1,ax3) #
0].squeeze().show(ax=ax1)
dls_r.train.decode((x,))["Input image")
ax1.set_title(#
# dls_r.train.decode((x,))[0].squeeze().show(ax=ax2)
# ax2.imshow((ybar_threshed).to("cpu").detach(),alpha=0.5,extent=(0,511,511,0),interpolation='bilinear',cmap='cool')
# ax2.set_title("CAT PART")
#
0].squeeze().show(ax=ax3)
dls_r.train.decode((x,))["cpu").detach(),alpha=0.5,extent=(0,511,511,0),interpolation='bilinear',cmap='cool')
ax3.imshow((grad_cam).to("DOG PART")
ax3.set_title(#
12)
fig.set_figwidth(12)
fig.set_figheight( fig.tight_layout()
- 판단 근거가 강할 수록 파란색 -> 보라색
= net(x).tolist()[0] a,b
/ (np.exp(a)+np.exp(b)) , np.exp(b)/ (np.exp(a)+np.exp(b)) np.exp(a)
(6.72737421709701e-06, 0.9999932726257829)
Random Box
CAT
= first(dls_r.test_dl([PILImage.create(get_image_files(path_r)[2])])) x,
= compute_gradcam(lrnr2_r,x) grad_cam
= plt.subplots(1,2)
fig, (ax1,ax2) #
0].squeeze().show(ax=ax1)
dls_r.train.decode((x,))["Input image")
ax1.set_title(#
0].squeeze().show(ax=ax2)
dls_r.train.decode((x,))["cpu").detach(),alpha=0.5,extent=(0,511,511,0),interpolation='bilinear',cmap='cool')
ax2.imshow((grad_cam).to("CAT PART")
ax2.set_title(#
# dls_r.train.decode((x,))[0].squeeze().show(ax=ax3)
# ax3.imshow((ybar_threshed2).to("cpu").detach(),alpha=0.5,extent=(0,511,511,0),interpolation='bilinear',cmap='cool')
# ax3.set_title("DOG PART")
#
12)
fig.set_figwidth(12)
fig.set_figheight( fig.tight_layout()
- 판단 근거가 강할 수록 파란색 -> 보라색
= net_r(x).tolist()[0] a,b
/ (np.exp(a)+np.exp(b)) , np.exp(b)/ (np.exp(a)+np.exp(b)) np.exp(a)
(0.9999999956844526, 4.315547465228285e-09)
DOG
= first(dls_r.test_dl([PILImage.create(get_image_files(path_r)[12])])) x,
= compute_gradcam(lrnr2_r,x) grad_cam
= plt.subplots(1,2)
fig, (ax1,ax3) #
0].squeeze().show(ax=ax1)
dls_r.train.decode((x,))["Input image")
ax1.set_title(#
# dls_r.train.decode((x,))[0].squeeze().show(ax=ax2)
# ax2.imshow((ybar_threshed).to("cpu").detach(),alpha=0.5,extent=(0,511,511,0),interpolation='bilinear',cmap='cool')
# ax2.set_title("CAT PART")
#
0].squeeze().show(ax=ax3)
dls_r.train.decode((x,))["cpu").detach(),alpha=0.5,extent=(0,511,511,0),interpolation='bilinear',cmap='cool')
ax3.imshow((grad_cam).to("DOG PART")
ax3.set_title(#
12)
fig.set_figwidth(12)
fig.set_figheight( fig.tight_layout()
- 판단 근거가 강할 수록 파란색 -> 보라색
= net_r(x).tolist()[0] a,b
/ (np.exp(a)+np.exp(b)) , np.exp(b)/ (np.exp(a)+np.exp(b)) np.exp(a)
(1.3188068250511113e-08, 0.9999999868119317)