前提・実現したいこと
初心者で申し訳ありません。
pytorch用いresnet50で転移学習を行い、gradcamにて特徴領域の可視化を試みています。下記のようなエラーメッセージが繰り返し出力されます。
どなたか解決法等御教示願えませんでしょうか。
よろしくお願いいたします。
発生している問題・エラーメッセージ
RuntimeError: Input type (torch.FloatTensor) and weight type (torch.cuda.FloatTensor) should be the same
python
1import torch 2import torch.nn as nn 3import torch.optim as optim 4from torch.utils.data import DataLoader, sampler, random_split 5import numpy as np 6import pandas as pd 7import torchvision 8from torchvision import datasets, models, transforms 9import matplotlib.pyplot as plt 10from PIL import Image 11import time 12import os 13import copy 14import cv2 15device = torch.device("cuda" if torch.cuda.is_available() else "cpu") 16 17image_transforms = { 18 'train': transforms.Compose([ 19 transforms.RandomResizedCrop(224), 20 transforms.RandomHorizontalFlip(), 21 transforms.ToTensor(), 22 transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) 23 ]), 24 'val': transforms.Compose([ 25 transforms.Resize(256), 26 transforms.CenterCrop(224), 27 transforms.ToTensor(), 28 transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) 29 ]), 30 'test': 31 transforms.Compose([ 32 transforms.Resize(size=256), 33 transforms.CenterCrop(size=224), 34 transforms.ToTensor(), 35 transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) 36 ]), 37} 38 39batch_size = 32 40 41all_data = datasets.ImageFolder(root='/Users/ora/Desktop/CNNdataset3') 42train_data_len = int(len(all_data)*0.8) 43valid_data_len = int((len(all_data) - train_data_len)/2) 44test_data_len = int(len(all_data) - train_data_len - valid_data_len) 45train_data, val_data, test_data = random_split(all_data, [train_data_len, valid_data_len, test_data_len]) 46train_data.dataset.transform = image_transforms['train'] 47val_data.dataset.transform = image_transforms['val'] 48test_data.dataset.transform = image_transforms['test'] 49print(len(train_data), len(val_data), len(test_data)) 50 51train_loader = DataLoader(train_data, batch_size=batch_size, shuffle=True) 52val_loader = DataLoader(val_data, batch_size=batch_size, shuffle=True) 53test_loader = DataLoader(test_data, batch_size=batch_size, shuffle=True) 54 55model = models.resnet50(pretrained=True) 56model = model.to("cuda") 57# Freeze early layers 58for param in model.parameters(): 59 param.requires_grad = False 60n_classes = 2 61# n_futures = model.fc.in_features 62num_ftrs = model.fc.in_features 63model.fc = nn.Linear(num_ftrs, n_classes)# n_inputs will be 4096 for this case 64 65# model.classifier 66criterion = nn.CrossEntropyLoss() 67optimizer = optim.Adam(model.parameters(), lr=0.001) 68 69model.class_to_idx = all_data.class_to_idx 70model.idx_to_class = { 71 idx: class_ 72 for class_, idx in model.class_to_idx.items() 73} 74 75def train(model, 76 criterion, 77 optimizer, 78 train_loader, 79 val_loader, 80 save_location, 81 early_stop=3, 82 n_epochs=50, 83 print_every=2): 84 85 #Initializing some variables 86 valid_loss_min = np.Inf 87 stop_count = 0 88 valid_max_acc = 0 89 history = [] 90 model.epochs = 0 91 92 #Loop starts here 93 for epoch in range(n_epochs): 94 train_loss = 0 95 valid_loss = 0 96 train_acc = 0 97 valid_acc = 0 98 model.train() 99 ii = 0 100 101 for data, label in train_loader: 102 ii += 1 103 data, label = data.cuda(), label.cuda() 104 optimizer.zero_grad() 105 output = model(data) 106 107 loss = criterion(output, label) 108 loss.backward() 109 optimizer.step() 110 111 # Track train loss by multiplying average loss by number of examples in batch 112 train_loss += loss.item() * data.size(0) 113 114 # Calculate accuracy by finding max log probability 115 _, pred = torch.max(output, dim=1) # first output gives the max value in the row(not what we want), second output gives index of the highest val 116 correct_tensor = pred.eq(label.data.view_as(pred)) # using the index of the predicted outcome above, torch.eq() will check prediction index against label index to see if prediction is correct(returns 1 if correct, 0 if not) 117 accuracy = torch.mean(correct_tensor.type(torch.FloatTensor)) #tensor must be float to calc average 118 train_acc += accuracy.item() * data.size(0) 119 if ii%15 == 0: 120 print(f'Epoch: {epoch}\t{100 * (ii + 1) / len(train_loader):.2f}% complete.') 121 122 model.epochs += 1 123 with torch.no_grad(): 124 model.eval() 125 for data, label in val_loader: 126 data, label = data.cuda(), label.cuda() 127 output = model(data) 128 loss = criterion(output, label) 129 valid_loss += loss.item() * data.size(0) 130 131 _, pred = torch.max(output, dim=1) 132 correct_tensor = pred.eq(label.data.view_as(pred)) 133 accuracy = torch.mean(correct_tensor.type(torch.FloatTensor)) 134 valid_acc += accuracy.item() * data.size(0) 135 136 train_loss = train_loss / len(train_loader.dataset) 137 valid_loss = valid_loss / len(val_loader.dataset) 138 139 train_acc = train_acc / len(train_loader.dataset) 140 valid_acc = valid_acc / len(val_loader.dataset) 141 142 history.append([train_loss, valid_loss, train_acc, valid_acc]) 143 144 if (epoch + 1) % print_every == 0: 145 print(f'\nEpoch: {epoch} \tTraining Loss: {train_loss:.4f} \tValidation Loss: {valid_loss:.4f}') 146 print(f'\t\tTraining Accuracy: {100 * train_acc:.2f}%\t Validation Accuracy: {100 * valid_acc:.2f}%') 147 148 if valid_loss < valid_loss_min: 149 torch.save(model.state_dict(), save_location) 150 stop_count = 0 151 valid_loss_min = valid_loss 152 valid_best_acc = valid_acc 153 best_epoch = epoch 154 155 else: 156 stop_count += 1 157 158class GradCAM: 159 def __init__(self, model, feature_layer): 160 self.model = model 161 self.feature_layer = feature_layer 162 self.model.eval() 163 self.feature_grad = None 164 self.feature_map = None 165 self.hooks = [] 166 167 # 最終層逆伝播時の勾配を記録する 168 def save_feature_grad(module, in_grad, out_grad): 169 self.feature_grad = out_grad[0] 170 self.hooks.append(self.feature_layer.register_backward_hook(save_feature_grad)) 171 # 最終層の出力 Feature Map を記録する 172 def save_feature_map(module, inp, outp): 173 self.feature_map = outp[0] 174 self.hooks.append(self.feature_layer.register_forward_hook(save_feature_map)) 175 176 def forward(self, x): 177 return self.model(x) 178 179 def backward_on_target(self, output, target): 180 self.model.zero_grad() 181 one_hot_output = torch.zeros([1, output.size()[-1]]) 182 one_hot_output[0][target] = 1 183 output.backward(gradient=one_hot_output, retain_graph=True) 184 185 def clear_hook(self): 186 for hook in self.hooks: 187 hook.remove() 188 189path = "/Users/ora/Desktop/2019_33 ①.jpg" 190VISUALIZE_SIZE = (300, 200) 191image = Image.open(path) 192image.thumbnail(VISUALIZE_SIZE, Image.ANTIALIAS) 193 194plt.imshow(image) 195 196image_orig_size = image.size # (W, H) 197 198test_image_tensor = image_transforms['test'](image) 199test_image_tensor = test_image_tensor.unsqueeze(0) 200device = torch.device("cuda") 201model = models.resnet50(pretrained=False) 202n_classes = 2 203num_ftrs = model.fc.in_features 204model.fc = nn.Linear(num_ftrs, n_classes) 205model.to(device) 206model.eval() 207 208from collections import OrderedDict 209import torch 210checkpoint=torch.load('./natural_images_resnet.pt') 211 212state_dict=checkpoint 213new_state_dict=OrderedDict() 214 215model.load_state_dict(state_dict) 216 217#############GradCamによる可視化 218grad_cam = GradCAM(model, feature_layer=list(model.layer4.modules())[26]) 219#画像をGradcamに入力 220model_output = grad_cam.forward(test_image_tensor) 221 222if len(model_output) == 1: 223 target = model_output.argmax(1).item() 224 grad_cam.backward_on_target(model_output, target) 225 226# Get feature gradient 227feature_grad = grad_cam.feature_grad.data.numpy()[0] 228 229# Get weights from gradient 230weights = np.mean(feature_grad, axis=(1, 2)) # Take averages for each gradient 231# Get features outputs 232feature_map = grad_cam.feature_map.data.numpy() 233grad_cam.clear_hook() 234 235cam = np.sum((weights * feature_map.T), axis=2).T 236cam = np.maximum(cam, 0) # apply ReLU to cam 237 238cam = cv2.resize(cam, VISUALIZE_SIZE) 239cam = (cam - np.min(cam)) / (np.max(cam) - np.min(cam)) # Normalize between 0-1 240cam = np.uint8(cam * 255) # Scale between 0-255 to visualize 241activation_heatmap = np.uint8(cv2.applyColorMap(cam, cv2.COLORMAP_JET)) 242activation_heatmap = cv2.cvtColor(activation_heatmap, cv2.COLOR_BGR2RGB) #色反転 243 244plt.imshow(activation_heatmap) 245 246org_img = np.asarray(image.resize(VISUALIZE_SIZE)) 247intensity = 0.4 248img_with_heatmap = cv2.addWeighted(activation_heatmap, intensity, org_img, 1, 0) 249org_img = cv2.resize(org_img, image_orig_size) 250img_with_heatmap = cv2.resize(img_with_heatmap, image_orig_size) 251 252plt.figure(figsize=(10,5)) 253 254plt.subplot(1,2,1) 255plt.imshow(org_img) 256plt.xticks(color="None") 257plt.yticks(color="None") 258plt.tick_params(length=0) 259plt.subplot(1,2,2) 260plt.imshow(img_with_heatmap) 261plt.xticks(color="None") 262plt.yticks(color="None") 263plt.tick_params(length=0) 264plt.show()
回答1件
あなたの回答
tips
プレビュー