最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

關(guān)于PyTorch源碼解讀之torchvision.models

 更新時間:2019年08月17日 09:37:53   作者:AI之路  
今天小編就為大家分享一篇關(guān)于PyTorch源碼解讀之torchvision.models,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧

PyTorch框架中有一個非常重要且好用的包:torchvision,該包主要由3個子包組成,分別是:torchvision.datasets、torchvision.models、torchvision.transforms。

這3個子包的具體介紹可以參考官網(wǎng):

http://pytorch.org/docs/master/torchvision/index.html。

具體代碼可以參考github:

https://github.com/pytorch/vision/tree/master/torchvision。

這篇博客介紹torchvision.models。torchvision.models這個包中包含alexnet、densenet、inception、resnet、squeezenet、vgg等常用的網(wǎng)絡(luò)結(jié)構(gòu),并且提供了預(yù)訓(xùn)練模型,可以通過簡單調(diào)用來讀取網(wǎng)絡(luò)結(jié)構(gòu)和預(yù)訓(xùn)練模型。

使用例子:

import torchvision
model = torchvision.models.resnet50(pretrained=True)

這樣就導(dǎo)入了resnet50的預(yù)訓(xùn)練模型了。如果只需要網(wǎng)絡(luò)結(jié)構(gòu),不需要用預(yù)訓(xùn)練模型的參數(shù)來初始化,那么就是:

model = torchvision.models.resnet50(pretrained=False)

如果要導(dǎo)入densenet模型也是同樣的道理,比如導(dǎo)入densenet169,且不需要是預(yù)訓(xùn)練的模型:

model = torchvision.models.densenet169(pretrained=False)

由于pretrained參數(shù)默認(rèn)是False,所以等價于:

model = torchvision.models.densenet169()

不過為了代碼清晰,最好還是加上參數(shù)賦值。

接下來以導(dǎo)入resnet50為例介紹具體導(dǎo)入模型時候的源碼。運(yùn)行model = torchvision.models.resnet50(pretrained=True)的時候,是通過models包下的resnet.py腳本進(jìn)行的,源碼如下:

首先是導(dǎo)入必要的庫,其中model_zoo是和導(dǎo)入預(yù)訓(xùn)練模型相關(guān)的包,另外all變量定義了可以從外部import的函數(shù)名或類名。這也是前面為什么可以用torchvision.models.resnet50()來調(diào)用的原因。model_urls這個字典是預(yù)訓(xùn)練模型的下載地址。

import torch.nn as nn
import math
import torch.utils.model_zoo as model_zoo

__all__ = ['ResNet', 'resnet18', 'resnet34', 'resnet50', 'resnet101',
  'resnet152']

model_urls = {
 'resnet18': 'https://download.pytorch.org/models/resnet18-5c106cde.pth',
 'resnet34': 'https://download.pytorch.org/models/resnet34-333f7ec4.pth',
 'resnet50': 'https://download.pytorch.org/models/resnet50-19c8e357.pth',
 'resnet101': 'https://download.pytorch.org/models/resnet101-5d3b4d8f.pth',
 'resnet152': 'https://download.pytorch.org/models/resnet152-b121ed2d.pth',
}

接下來就是resnet50這個函數(shù)了,參數(shù)pretrained默認(rèn)是False。首先model = ResNet(Bottleneck, [3, 4, 6, 3], **kwargs)是構(gòu)建網(wǎng)絡(luò)結(jié)構(gòu),Bottleneck是另外一個構(gòu)建bottleneck的類,在ResNet網(wǎng)絡(luò)結(jié)構(gòu)的構(gòu)建中有很多重復(fù)的子結(jié)構(gòu),這些子結(jié)構(gòu)就是通過Bottleneck類來構(gòu)建的,后面會介紹。然后如果參數(shù)pretrained是True,那么就會通過model_zoo.py中的load_url函數(shù)根據(jù)model_urls字典下載或?qū)胂鄳?yīng)的預(yù)訓(xùn)練模型。最后通過調(diào)用model的load_state_dict方法用預(yù)訓(xùn)練的模型參數(shù)來初始化你構(gòu)建的網(wǎng)絡(luò)結(jié)構(gòu),這個方法就是PyTorch中通用的用一個模型的參數(shù)初始化另一個模型的層的操作。load_state_dict方法還有一個重要的參數(shù)是strict,該參數(shù)默認(rèn)是True,表示預(yù)訓(xùn)練模型的層和你的網(wǎng)絡(luò)結(jié)構(gòu)層嚴(yán)格對應(yīng)相等(比如層名和維度)。

def resnet50(pretrained=False, **kwargs):
 """Constructs a ResNet-50 model.

 Args:
 pretrained (bool): If True, returns a model pre-trained on ImageNet
 """
 model = ResNet(Bottleneck, [3, 4, 6, 3], **kwargs)
 if pretrained:
 model.load_state_dict(model_zoo.load_url(model_urls['resnet50']))
 return model

其他resnet18、resnet101等函數(shù)和resnet50基本類似,差別主要是在:

1、構(gòu)建網(wǎng)絡(luò)結(jié)構(gòu)的時候block的參數(shù)不一樣,比如resnet18中是[2, 2, 2, 2],resnet101中是[3, 4, 23, 3]。

2、調(diào)用的block類不一樣,比如在resnet50、resnet101、resnet152中調(diào)用的是Bottleneck類,而在resnet18和resnet34中調(diào)用的是BasicBlock類,這兩個類的區(qū)別主要是在residual結(jié)果中卷積層的數(shù)量不同,這個是和網(wǎng)絡(luò)結(jié)構(gòu)相關(guān)的,后面會詳細(xì)介紹。

3、如果下載預(yù)訓(xùn)練模型的話,model_urls字典的鍵不一樣,對應(yīng)不同的預(yù)訓(xùn)練模型。因此接下來分別看看如何構(gòu)建網(wǎng)絡(luò)結(jié)構(gòu)和如何導(dǎo)入預(yù)訓(xùn)練模型。

def resnet18(pretrained=False, **kwargs):
 """Constructs a ResNet-18 model.

 Args:
 pretrained (bool): If True, returns a model pre-trained on ImageNet
 """
 model = ResNet(BasicBlock, [2, 2, 2, 2], **kwargs)
 if pretrained:
 model.load_state_dict(model_zoo.load_url(model_urls['resnet18']))
 return model

def resnet101(pretrained=False, **kwargs):
 """Constructs a ResNet-101 model.

 Args:
 pretrained (bool): If True, returns a model pre-trained on ImageNet
 """
 model = ResNet(Bottleneck, [3, 4, 23, 3], **kwargs)
 if pretrained:
 model.load_state_dict(model_zoo.load_url(model_urls['resnet101']))
 return model

構(gòu)建ResNet網(wǎng)絡(luò)是通過ResNet這個類進(jìn)行的。首先還是繼承PyTorch中網(wǎng)絡(luò)的基類:torch.nn.Module,其次主要的是重寫初始化__init__和forward方法。在初始化__init__中主要是定義一些層的參數(shù)。forward方法中主要是定義數(shù)據(jù)在層之間的流動順序,也就是層的連接順序。另外還可以在類中定義其他私有方法用來模塊化一些操作,比如這里的_make_layer方法是用來構(gòu)建ResNet網(wǎng)絡(luò)中的4個blocks。_make_layer方法的第一個輸入block是Bottleneck或BasicBlock類,第二個輸入是該blocks的輸出channel,第三個輸入是每個blocks中包含多少個residual子結(jié)構(gòu),因此layers這個列表就是前面resnet50的[3, 4, 6, 3]。

_make_layer方法中比較重要的兩行代碼是:1、layers.append(block(self.inplanes, planes, stride, downsample)),該部分是將每個blocks的第一個residual結(jié)構(gòu)保存在layers列表中。2、 for i in range(1, blocks): layers.append(block(self.inplanes, planes)),該部分是將每個blocks的剩下residual 結(jié)構(gòu)保存在layers列表中,這樣就完成了一個blocks的構(gòu)造。這兩行代碼中都是通過Bottleneck這個類來完成每個residual的構(gòu)建,接下來介紹Bottleneck類。

class ResNet(nn.Module):

 def __init__(self, block, layers, num_classes=1000):
 self.inplanes = 64
 super(ResNet, self).__init__()
 self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3,
    bias=False)
 self.bn1 = nn.BatchNorm2d(64)
 self.relu = nn.ReLU(inplace=True)
 self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
 self.layer1 = self._make_layer(block, 64, layers[0])
 self.layer2 = self._make_layer(block, 128, layers[1], stride=2)
 self.layer3 = self._make_layer(block, 256, layers[2], stride=2)
 self.layer4 = self._make_layer(block, 512, layers[3], stride=2)
 self.avgpool = nn.AvgPool2d(7, stride=1)
 self.fc = nn.Linear(512 * block.expansion, num_classes)

 for m in self.modules():
  if isinstance(m, nn.Conv2d):
  n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels
  m.weight.data.normal_(0, math.sqrt(2. / n))
  elif isinstance(m, nn.BatchNorm2d):
  m.weight.data.fill_(1)
  m.bias.data.zero_()

 def _make_layer(self, block, planes, blocks, stride=1):
 downsample = None
 if stride != 1 or self.inplanes != planes * block.expansion:
  downsample = nn.Sequential(
  nn.Conv2d(self.inplanes, planes * block.expansion,
    kernel_size=1, stride=stride, bias=False),
  nn.BatchNorm2d(planes * block.expansion),
  )

 layers = []
 layers.append(block(self.inplanes, planes, stride, downsample))
 self.inplanes = planes * block.expansion
 for i in range(1, blocks):
  layers.append(block(self.inplanes, planes))

 return nn.Sequential(*layers)

 def forward(self, x):
 x = self.conv1(x)
 x = self.bn1(x)
 x = self.relu(x)
 x = self.maxpool(x)

 x = self.layer1(x)
 x = self.layer2(x)
 x = self.layer3(x)
 x = self.layer4(x)

 x = self.avgpool(x)
 x = x.view(x.size(0), -1)
 x = self.fc(x)

 return x

從前面的ResNet類可以看出,在構(gòu)造ResNet網(wǎng)絡(luò)的時候,最重要的是Bottleneck這個類,因為ResNet是由residual結(jié)構(gòu)組成的,而Bottleneck類就是完成residual結(jié)構(gòu)的構(gòu)建。同樣Bottlenect還是繼承了torch.nn.Module類,且重寫了__init__和forward方法。從forward方法可以看出,bottleneck就是我們熟悉的3個主要的卷積層、BN層和激活層,最后的out += residual就是element-wise add的操作。

class Bottleneck(nn.Module):
 expansion = 4

 def __init__(self, inplanes, planes, stride=1, downsample=None):
 super(Bottleneck, self).__init__()
 self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=1, bias=False)
 self.bn1 = nn.BatchNorm2d(planes)
 self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=stride,
    padding=1, bias=False)
 self.bn2 = nn.BatchNorm2d(planes)
 self.conv3 = nn.Conv2d(planes, planes * 4, kernel_size=1, bias=False)
 self.bn3 = nn.BatchNorm2d(planes * 4)
 self.relu = nn.ReLU(inplace=True)
 self.downsample = downsample
 self.stride = stride

 def forward(self, x):
 residual = x

 out = self.conv1(x)
 out = self.bn1(out)
 out = self.relu(out)

 out = self.conv2(out)
 out = self.bn2(out)
 out = self.relu(out)

 out = self.conv3(out)
 out = self.bn3(out)

 if self.downsample is not None:
  residual = self.downsample(x)

 out += residual
 out = self.relu(out)

 return out

BasicBlock類和Bottleneck類類似,前者主要是用來構(gòu)建ResNet18和ResNet34網(wǎng)絡(luò),因為這兩個網(wǎng)絡(luò)的residual結(jié)構(gòu)只包含兩個卷積層,沒有Bottleneck類中的bottleneck概念。因此在該類中,第一個卷積層采用的是kernel_size=3的卷積,如conv3x3函數(shù)所示。

def conv3x3(in_planes, out_planes, stride=1):
 """3x3 convolution with padding"""
 return nn.Conv2d(in_planes, out_planes, kernel_size=3, stride=stride,
   padding=1, bias=False)

class BasicBlock(nn.Module):
 expansion = 1

 def __init__(self, inplanes, planes, stride=1, downsample=None):
 super(BasicBlock, self).__init__()
 self.conv1 = conv3x3(inplanes, planes, stride)
 self.bn1 = nn.BatchNorm2d(planes)
 self.relu = nn.ReLU(inplace=True)
 self.conv2 = conv3x3(planes, planes)
 self.bn2 = nn.BatchNorm2d(planes)
 self.downsample = downsample
 self.stride = stride

 def forward(self, x):
 residual = x

 out = self.conv1(x)
 out = self.bn1(out)
 out = self.relu(out)

 out = self.conv2(out)
 out = self.bn2(out)

 if self.downsample is not None:
  residual = self.downsample(x)

 out += residual
 out = self.relu(out)

 return out

介紹完如何構(gòu)建網(wǎng)絡(luò),接下來就是如何獲取預(yù)訓(xùn)練模型。前面提到這一行代碼:if pretrained: model.load_state_dict(model_zoo.load_url(model_urls['resnet50'])),主要就是通過model_zoo.py中的load_url函數(shù)根據(jù)model_urls字典導(dǎo)入相應(yīng)的預(yù)訓(xùn)練模型,models_zoo.py腳本的github地址:

https://github.com/pytorch/pytorch/blob/master/torch/utils/model_zoo.py。

load_url函數(shù)源碼如下。

首先model_dir是下載下來的模型的保存地址,如果沒有指定的話就會保存在項目的.torch目錄下,最好指定。cached_file是保存模型的路徑加上模型名稱。接下來的 if not os.path.exists(cached_file)語句用來判斷是否指定目錄下已經(jīng)存在要下載模型,如果已經(jīng)存在,就直接調(diào)用torch.load接口導(dǎo)入模型,如果不存在,則從網(wǎng)上下載,下載是通過_download_url_to_file(url, cached_file, hash_prefix, progress=progress)進(jìn)行的,不再細(xì)講。重點在于模型導(dǎo)入是通過torch.load()接口來進(jìn)行的,不管你的模型是從網(wǎng)上下載的還是本地已有的。

def load_url(url, model_dir=None, map_location=None, progress=True):
 r"""Loads the Torch serialized object at the given URL.

 If the object is already present in `model_dir`, it's deserialized and
 returned. The filename part of the URL should follow the naming convention
 ``filename-<sha256>.ext`` where ``<sha256>`` is the first eight or more
 digits of the SHA256 hash of the contents of the file. The hash is used to
 ensure unique names and to verify the contents of the file.

 The default value of `model_dir` is ``$TORCH_HOME/models`` where
 ``$TORCH_HOME`` defaults to ``~/.torch``. The default directory can be
 overriden with the ``$TORCH_MODEL_ZOO`` environment variable.

 Args:
 url (string): URL of the object to download
 model_dir (string, optional): directory in which to save the object
 map_location (optional): a function or a dict specifying how to remap storage locations (see torch.load)
 progress (bool, optional): whether or not to display a progress bar to stderr

 Example:
 >>> state_dict = torch.utils.model_zoo.load_url('https://s3.amazonaws.com/pytorch/models/resnet18-5c106cde.pth')

 """
 if model_dir is None:
 torch_home = os.path.expanduser(os.getenv('TORCH_HOME', '~/.torch'))
 model_dir = os.getenv('TORCH_MODEL_ZOO', os.path.join(torch_home, 'models'))
 if not os.path.exists(model_dir):
 os.makedirs(model_dir)
 parts = urlparse(url)
 filename = os.path.basename(parts.path)
 cached_file = os.path.join(model_dir, filename)
 if not os.path.exists(cached_file):
 sys.stderr.write('Downloading: "{}" to {}\n'.format(url, cached_file))
 hash_prefix = HASH_REGEX.search(filename).group(1)
 _download_url_to_file(url, cached_file, hash_prefix, progress=progress)
 return torch.load(cached_file, map_location=map_location)

以上這篇關(guān)于PyTorch源碼解讀之torchvision.models就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 我在七夕佳節(jié)用Python制作的表白神器,程序員也應(yīng)該擁有愛情!建議收藏

    我在七夕佳節(jié)用Python制作的表白神器,程序員也應(yīng)該擁有愛情!建議收藏

    這篇文章主要介紹了我在七夕佳節(jié)用Python制作的表白神器,建議收藏,程序員也該擁有愛情,感興趣的小伙伴快來看看吧
    2021-08-08
  • Python實現(xiàn)棧的方法

    Python實現(xiàn)棧的方法

    這篇文章主要介紹了Python實現(xiàn)棧的方法,實例分析了Python實現(xiàn)棧的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-05-05
  • 使用PyQt5實現(xiàn)圖片查看器的示例代碼

    使用PyQt5實現(xiàn)圖片查看器的示例代碼

    這篇文章主要介紹了使用PyQt5實現(xiàn)圖片查看器的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-04-04
  • python 限制函數(shù)執(zhí)行時間,自己實現(xiàn)timeout的實例

    python 限制函數(shù)執(zhí)行時間,自己實現(xiàn)timeout的實例

    今天小編就為大家分享一篇python 限制函數(shù)執(zhí)行時間,自己實現(xiàn)timeout的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-01-01
  • python中partial()基礎(chǔ)用法說明

    python中partial()基礎(chǔ)用法說明

    這篇文章主要給大家介紹了關(guān)于python中partial()基礎(chǔ)用法的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用python具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起看看吧
    2018-12-12
  • 開源Web應(yīng)用框架Django圖文教程

    開源Web應(yīng)用框架Django圖文教程

    Python下有許多款不同的 Web 框架。Django是重量級選手中最有代表性的一位。許多成功的網(wǎng)站和APP都基于Django。Django是一個開放源代碼的Web應(yīng)用框架,由Python寫成。下面我們來一步步學(xué)習(xí)下吧
    2017-03-03
  • Python?isdigit()函數(shù)判斷字符串是否全都是數(shù)字字符示例

    Python?isdigit()函數(shù)判斷字符串是否全都是數(shù)字字符示例

    這篇文章主要為大家介紹了Python判斷字符串是否全都是數(shù)字字符示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-01-01
  • Python3中在Anaconda環(huán)境下安裝basemap包

    Python3中在Anaconda環(huán)境下安裝basemap包

    今天小編就為大家分享一篇關(guān)于Python3中在Anaconda環(huán)境下安裝basemap包的文章,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-10-10
  • Python3.10.4激活venv環(huán)境失敗解決方法

    Python3.10.4激活venv環(huán)境失敗解決方法

    這篇文章主要介紹了Python3.10.4激活venv環(huán)境失敗解決方法的相關(guān)資料,需要的朋友可以參考下
    2023-01-01
  • 使用Python FastAPI構(gòu)建Web服務(wù)的實現(xiàn)

    使用Python FastAPI構(gòu)建Web服務(wù)的實現(xiàn)

    這篇文章主要介紹了使用Python FastAPI構(gòu)建Web服務(wù)的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06

最新評論

太仓市| 阿克| 黄龙县| 宣威市| 阿合奇县| 台湾省| 紫金县| 伊宁县| 壶关县| 福鼎市| 开原市| 栾城县| 杭锦旗| 仲巴县| 德格县| 襄城县| 体育| 巴青县| 田东县| 抚松县| 太保市| 喜德县| 肇州县| 湛江市| 中超| 安阳县| 房山区| 通许县| 措美县| 蚌埠市| 和田市| 阿鲁科尔沁旗| 八宿县| 长白| 余庆县| 克拉玛依市| 景泰县| 汨罗市| 凤山县| 鹤山市| 东平县|