<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
torchvision.models預定義了很多公開的模型結構
如果pretrained引數設定為False,那麼僅僅設定模型結構;如果設定為True,那麼會啟動一個下載流程,下載預訓練引數
如果只想呼叫模型,不想訓練,那麼設定model.eval()和model.requires_grad_(False)
想檢視模型引數可以使用modules和named_modules,其中named_modules是一個長度為2的tuple,第一個變數是name,第二個變數是module本身。
# -*- coding: utf-8 -*- from torch import nn from torchvision import models # load model. If pretrained is True, there will be a downloading process model = models.vgg19(pretrained=True) model.eval() model.requires_grad_(False) # get model component features = model.features modules = features.modules() named_modules = features.named_modules() # print modules for module in modules: if isinstance(module, nn.Conv2d): weight = module.weight bias = module.bias print(module, weight.shape, bias.shape, weight.requires_grad, bias.requires_grad) elif isinstance(module, nn.ReLU): print(module) print() for named_module in named_modules: name = named_module[0] module = named_module[1] if isinstance(module, nn.Conv2d): weight = module.weight bias = module.bias print(name, module, weight.shape, bias.shape, weight.requires_grad, bias.requires_grad) elif isinstance(module, nn.ReLU): print(name, module)
使用opencv和pil讀圖都可以使用transforms.ToTensor()把原本[H, W, 3]的資料轉成[3, H, W]的tensor。但opencv要注意把資料改成RGB順序。
vgg系列模型需要做normalization,建議配合torchvision.transforms來實現。
mini-batches of 3-channel RGB images of shape (3 x H x W), where H and W are expected to be at least 224. The images have to be loaded in to a range of [0, 1] and then normalized using mean = [0.485, 0.456, 0.406] and std = [0.229, 0.224, 0.225].
參考:https://pytorch.org/hub/pytorch_vision_vgg/
# -*- coding: utf-8 -*- from PIL import Image import cv2 import torch from torchvision import transforms # transforms for preprocess preprocess = transforms.Compose([ transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) ]) # load image using cv2 image_cv2 = cv2.imread('lena_std.bmp') image_cv2 = cv2.cvtColor(image_cv2, cv2.COLOR_BGR2RGB) image_cv2 = preprocess(image_cv2) # load image using pil image_pil = Image.open('lena_std.bmp') image_pil = preprocess(image_pil) # check whether image_cv2 and image_pil are same print(torch.all(image_cv2 == image_pil)) print(image_cv2.shape, image_pil.shape)
如果只提取單層特徵圖,可以把模型截斷,以節省算力和視訊記憶體消耗。
下面索引之所以有+1是因為pytorch預訓練模型裡面第一個索引的module總是完整模組結構,第二個才開始子模組。
# -*- coding: utf-8 -*- from PIL import Image from torchvision import models from torchvision import transforms # load model. If pretrained is True, there will be a downloading process model = models.vgg19(pretrained=True) model = model.features[:16 + 1] # 16 = conv3_4 model.eval() model.requires_grad_(False) model.to('cuda') print(model) # load and preprocess image preprocess = transforms.Compose([ transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), transforms.Resize(size=(224, 224)) ]) image = Image.open('lena_std.bmp') image = preprocess(image) inputs = image.unsqueeze(0) # add batch dimension inputs = inputs.cuda() # forward output = model(inputs) print(output.shape)
第一種方式:逐層執行model,如果碰到了需要儲存的feature map就存下來。
第二種方式:使用register_forward_hook,使用這種方式需要用一個類把feature map以成員變數的形式快取下來。
兩種方式的執行效率差不多
第一種方式簡單直觀,但是隻能處理類似VGG這種沒有跨層連線的網路;第二種方式更加通用。
# -*- coding: utf-8 -*- from PIL import Image import torch from torchvision import models from torchvision import transforms # load model. If pretrained is True, there will be a downloading process model = models.vgg19(pretrained=True) model = model.features[:16 + 1] # 16 = conv3_4 model.eval() model.requires_grad_(False) model.to('cuda') # check module name for named_module in model.named_modules(): name = named_module[0] module = named_module[1] print('-------- %s --------' % name) print(module) print() # load and preprocess image preprocess = transforms.Compose([ transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), transforms.Resize(size=(224, 224)) ]) image = Image.open('lena_std.bmp') image = preprocess(image) inputs = image.unsqueeze(0) # add batch dimension inputs = inputs.cuda() # forward - 1 layers = [2, 7, 8, 9, 16] layers = sorted(set(layers)) feature_maps = {} feature = inputs for i in range(max(layers) + 1): feature = model[i](feature) if i in layers: feature_maps[i] = feature for key in feature_maps: print(key, feature_maps.get(key).shape) # forward - 2 class FeatureHook: def __init__(self, module): self.inputs = None self.output = None self.hook = module.register_forward_hook(self.get_features) def get_features(self, module, inputs, output): self.inputs = inputs self.output = output layer_names = ['2', '7', '8', '9', '16'] hook_modules = [] for named_module in model.named_modules(): name = named_module[0] module = named_module[1] if name in layer_names: hook_modules.append(module) hooks = [FeatureHook(module) for module in hook_modules] output = model(inputs) features = [hook.output for hook in hooks] for feature in features: print(feature.shape) # check correctness for i, layer in enumerate(layers): feature1 = feature_maps.get(layer) feature2 = features[i] print(torch.all(feature1 == feature2))
使用第二種方式(register_forward_hook),resnet特徵圖也可以順利拿到。
而由於resnet的model已經不可以用model[i]的形式索引,所以無法使用第一種方式。
# -*- coding: utf-8 -*- from PIL import Image from torchvision import models from torchvision import transforms # load model. If pretrained is True, there will be a downloading process model = models.resnet18(pretrained=True) model.eval() model.requires_grad_(False) model.to('cuda') # check module name for named_module in model.named_modules(): name = named_module[0] module = named_module[1] print('-------- %s --------' % name) print(module) print() # load and preprocess image preprocess = transforms.Compose([ transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), transforms.Resize(size=(224, 224)) ]) image = Image.open('lena_std.bmp') image = preprocess(image) inputs = image.unsqueeze(0) # add batch dimension inputs = inputs.cuda() class FeatureHook: def __init__(self, module): self.inputs = None self.output = None self.hook = module.register_forward_hook(self.get_features) def get_features(self, module, inputs, output): self.inputs = inputs self.output = output layer_names = [ 'conv1', 'layer1.0.relu', 'layer2.0.conv1' ] hook_modules = [] for named_module in model.named_modules(): name = named_module[0] module = named_module[1] if name in layer_names: hook_modules.append(module) hooks = [FeatureHook(module) for module in hook_modules] output = model(inputs) features = [hook.output for hook in hooks] for feature in features: print(feature.shape)
問題來了,resnet這種型別的網路結構怎麼截斷?
使用如下命令就可以,print檢視需要截斷到哪裡,然後用nn.Sequential重組即可。
需注意重組後網路的module_name會發生變化。
print(list(model.children()) model = torch.nn.Sequential(*list(model.children())[:6])
以上就是利用Pytorch實現獲取特徵圖的方法詳解的詳細內容,更多關於Pytorch獲取特徵圖的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45