質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
CUDA

CUDAは並列計算プラットフォームであり、Nvidia GPU(Graphics Processing Units)向けのプログラミングモデルです。CUDAは様々なプログラミング言語、ライブラリ、APIを通してNvidiaにインターフェイスを提供します。

PyTorch

PyTorchは、オープンソースのPython向けの機械学習ライブラリ。Facebookの人工知能研究グループが開発を主導しています。強力なGPUサポートを備えたテンソル計算、テープベースの自動微分による柔軟なニューラルネットワークの記述が可能です。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Q&A

解決済

1回答

3927閲覧

pytorchでのgradcamの実装が出来ない

shujiu

総合スコア3

CUDA

CUDAは並列計算プラットフォームであり、Nvidia GPU(Graphics Processing Units)向けのプログラミングモデルです。CUDAは様々なプログラミング言語、ライブラリ、APIを通してNvidiaにインターフェイスを提供します。

PyTorch

PyTorchは、オープンソースのPython向けの機械学習ライブラリ。Facebookの人工知能研究グループが開発を主導しています。強力なGPUサポートを備えたテンソル計算、テープベースの自動微分による柔軟なニューラルネットワークの記述が可能です。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

0グッド

0クリップ

投稿2021/05/10 05:09

編集2021/05/10 12:46

前提・実現したいこと

初心者で申し訳ありません。
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()

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

toast-uz

2021/05/10 12:32

エラーメッセージは、スタックトレース部分が重要なので、メッセージ部分だけを切り出さず、全体を掲載ください
shujiu

2021/05/10 12:47

RuntimeError Traceback (most recent call last) <ipython-input-57-a8dff80bae72> in <module> 30 grad_cam = GradCAM(model, feature_layer=list(model.layer4.modules())[26]) 31 #画像をGradcamに入力 ---> 32 model_output = grad_cam.forward(test_image_tensor) 33 34 if len(model_output) == 1: <ipython-input-56-5b19a4a57393> in forward(self, x) 22 23 def forward(self, x): ---> 24 return self.model(x) 25 26 def backward_on_target(self, output, target): ~\anaconda3\envs\envtest2\lib\site-packages\torch\nn\modules\module.py in __call__(self, *input, **kwargs) 548 result = self._slow_forward(*input, **kwargs) 549 else: --> 550 result = self.forward(*input, **kwargs) 551 for hook in self._forward_hooks.values(): 552 hook_result = hook(self, input, result) ~\anaconda3\envs\envtest2\lib\site-packages\torchvision\models\resnet.py in forward(self, x) 218 219 def forward(self, x): --> 220 return self._forward_impl(x) 221 222 ~\anaconda3\envs\envtest2\lib\site-packages\torchvision\models\resnet.py in _forward_impl(self, x) 201 def _forward_impl(self, x): 202 # See note [TorchScript super()] --> 203 x = self.conv1(x) 204 x = self.bn1(x) 205 x = self.relu(x) ~\anaconda3\envs\envtest2\lib\site-packages\torch\nn\modules\module.py in __call__(self, *input, **kwargs) 548 result = self._slow_forward(*input, **kwargs) 549 else: --> 550 result = self.forward(*input, **kwargs) 551 for hook in self._forward_hooks.values(): 552 hook_result = hook(self, input, result) ~\anaconda3\envs\envtest2\lib\site-packages\torch\nn\modules\conv.py in forward(self, input) 347 348 def forward(self, input): --> 349 return self._conv_forward(input, self.weight) 350 351 class Conv3d(_ConvNd): ~\anaconda3\envs\envtest2\lib\site-packages\torch\nn\modules\conv.py in _conv_forward(self, input, weight) 344 _pair(0), self.dilation, self.groups) 345 return F.conv2d(input, weight, self.bias, self.stride, --> 346 self.padding, self.dilation, self.groups) 347 348 def forward(self, input): RuntimeError: Input type (torch.FloatTensor) and weight type (torch.cuda.FloatTensor) should be the same
shujiu

2021/05/10 12:48

申し訳ありません。Error messageについて追記しました. よろしくお願いいたします。
guest

回答1

0

ベストアンサー

手元で再現試験などしていないため、ソースコードとエラーメッセージのみからの判断になりますが、test_image_tensor がCPU上に置かれている一方で grad_cam (より正確には、初期化時に渡されているResNet50のモデル) がGPU上に転送済みになっている (=GradCAM() へ渡す前に model.to(device) している) ことによる、型の不一致が原因と思われます。

forward() の実行前に test_image_tensortest_image_tensor.to(device) として、GPUへデータを転送しておくと動くのではないかと思います。

ちなみに最初に添付いただいたエラーメッセージをよーく見ていただくと、

  • Input type (torch.FloatTensor)
  • weight type (torch. cuda .FloatTensor)

と、入力のデータ型と重みのデータ型が違うことが示されているので、注意深く見ていただくと良いかと思います。(といいつつ、見落として深みにハマりがちなので難しいところですが……)

投稿2021/05/12 13:52

lazykyama

総合スコア58

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shujiu

2021/05/18 05:16

上記の通り修正いたしましたところ、問題なく稼働いたしました。 ありがとうございました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問