PyTorch-torch04: Cov2d二维卷积和torch.nn

torch.nn

class torcn.nn.Parameter()
ParametersVariable的子类。
参数说明:

  • data(Tensor)->parameter tensor
  • requires_grad(bool,optional)

Containers:

class torch.nn.Module
所有神经网络模块的基类
你的模型也应该继承这个类
Modules还可以包含其他模块,允许将它们嵌套在树结构中.您可以将子模块分配为常规属性:

#导入nn包
import torch.nn as nn
#导入nn包的函数模块
import torch.nn.functional as F
class Model(nn.Module):
    def __init__(self):
        #调用父类构造方法
        super(Model,self).__init__()
        #super(nn.Module,self).__init__()
        #nn.Module.__init__()
        #调用父类中的卷积方法
        self.conv1 = nn.Conv2d(1,20,5)
        self.conv2 = nn.Conv2d(20,20,5)
    def forward(self,x):
        # 前向传播使用relu激活函数
        x = F.relu(self.conv1(x))
        return F.relu(self.conv2(x))

以这种方式分配的子模块将被注册,并且在调用.cuda()时候会转换GPU参数

import torch.nn as nn
class Model(nn.Module):
    def __init__(self):
        #super(Model,self).__init__()
        nn.Module.__init__(self)
        self.add_module("conv",nn.Conv2d(10,20,4))
        #self.conv = nn.Conv2d(10,20,4)和上面增加module的方式等价
model = Model()
print(model.conv)
Conv2d(10, 20, kernel_size=(4, 4), stride=(1, 1))

CLASS torch.nn.Linear(in_feature,out_feature,bias=True)
此为线性回归公式,也为DNN网络的输出公式,或全连接层的连接公式
Y = XA^{T}+b
参数解释:

  • in_feature:假设输入尺寸为[rowsize,columsize]则其为columsize
  • out_feature:输出尺寸大小或者下一层神经元的个数
L = nn.Linear(2,2)
print(L.weight)
print(L.bias.shape)
Parameter containing:
tensor([[-0.2078, -0.3180],
        [ 0.1222,  0.5744]], requires_grad=True)
torch.Size([2])
import torch
x = torch.randn(128, 20)  # 输入的维度是(128,20)
m = torch.nn.Linear(20, 30)  # 20,30是指维度
c = m(x)
print(m.weight.shape)
print(c.shape)
print(m.bias.shape)
#print(c.bias.shape)
#print(m.shape)
print(c)
#语法错误n = torch.nn.Linear(20,torch.tensor([20,20]))
#print(n.bias.shape)
torch.Size([30, 20])
torch.Size([128, 30])
torch.Size([30])
tensor([[-0.9075,  0.4658, -0.6769,  ...,  0.8770,  0.1963, -0.1634],
        [ 0.3249, -0.4842,  0.5415,  ..., -0.6922,  0.3830, -0.4454],
        [ 0.2934, -0.3098,  0.8307,  ..., -0.2225,  0.1665, -0.7599],
        ...,
        [ 1.3914, -0.4900,  1.7351,  ..., -0.4768,  0.1307, -2.4975],
        [-0.3248,  0.1314,  0.1383,  ..., -0.5789, -0.3377, -1.0821],
        [ 1.0866,  0.2304,  1.0595,  ..., -0.0817, -0.9459, -0.2057]],
       grad_fn=<AddmmBackward>)

apply(function)

递归调用函数应用到每个组成部分以及本身,典型应用为初始化模型参数

def init_weights(m):
    print(m)
    if type(m) == nn.Linear:
        m.weight.data.fill_(1.0)
        print(m.weight)
# Sequential中的单元按顺序执行
net = nn.Sequential(nn.Linear(2,2),nn.Linear(2,2))
net.apply(init_weights)
Linear(in_features=2, out_features=2, bias=True)
Parameter containing:
tensor([[1., 1.],
        [1., 1.]], requires_grad=True)
Linear(in_features=2, out_features=2, bias=True)
Parameter containing:
tensor([[1., 1.],
        [1., 1.]], requires_grad=True)
Sequential(
  (0): Linear(in_features=2, out_features=2, bias=True)
  (1): Linear(in_features=2, out_features=2, bias=True)
)





Sequential(
  (0): Linear(in_features=2, out_features=2, bias=True)
  (1): Linear(in_features=2, out_features=2, bias=True)
)

modules

返回所有模块的迭代器包括自身重复的模块只迭代一次

l = nn.Linear(2,2)
net = nn.Sequential(l,l)
#enumerate进行dict处理
for index,m in enumerate(net.modules()):
    print(index,'->',m)
0 -> Sequential(
  (0): Linear(in_features=2, out_features=2, bias=True)
  (1): Linear(in_features=2, out_features=2, bias=True)
)
1 -> Linear(in_features=2, out_features=2, bias=True)

named_children()->SonModuleIteration

返回子模块迭代器

for name,module in model.named_children():
    #if name in['conv2','conv2']:
        print(module)
print(model.named_children())
Conv2d(10, 20, kernel_size=(4, 4), stride=(1, 1))
<generator object Module.named_children at 0x000001ABCFDCD2C8>

named_modules()

返回网络中所有模块迭代器,同时产生模块的名称以及模块本身
重复的模块只返回一次

l = nn.Linear(2,2)
net = nn.Sequential(l,l)
for index,m in enumerate(net.named_modules()):
    print(index,'->',m)
0 -> ('', Sequential(
  (0): Linear(in_features=2, out_features=2, bias=True)
  (1): Linear(in_features=2, out_features=2, bias=True)
))
1 -> ('0', Linear(in_features=2, out_features=2, bias=True))

named_parameters(memo=None,prefix)

返回模块参数的迭代器,同时产生参数的名称和参数本身

for name,param in l.named_parameters():
    print(name,'->',param)
weight -> Parameter containing:
tensor([[ 0.3842,  0.3218],
        [ 0.1494, -0.4355]], requires_grad=True)
bias -> Parameter containing:
tensor([0.3653, 0.6474], requires_grad=True)

parameters()->ModuleParamIteration

这通常被传递个优化器

for param in l.parameters():
    print(type(param.data),param.size())
<class 'torch.Tensor'> torch.Size([2, 2])
<class 'torch.Tensor'> torch.Size([2])

register_backward_hook(hook)

在模块上注册一个向后的钩子这是用于记录反向传播时的梯度的
每当计算相对于模块输入的梯度时,将调用该钩子挂钩应
具有一下签名:

hook(module,grad_input,grad_output)->Variable or None

|-如果module如果module有多个输入输出的话,那么grad_input grad_output将会是个tuple。 hook不应该修改它的arguments,但是它可以选择性的返回关于输入的梯度,这个返回的梯度在后续的计算中会替代grad_input。
这个函数返回一个句柄(handle)。它有一个方法 handle.remove(),可以用这个方法将hook从module移除

register_forward_hook(hook)

在模块上注册一个forward hook,这是记录前向传播时的梯度的

hook(module,grad_input,grad_output)->Variable or None

class torch.nn.Sequential(* args)

这是一个时序容器.Modules会以他们传入的顺序添加到容器中当然也可以传入
一个顺序字典

model = nn.Sequential(nn.Conv2d(1,20,5),
                      nn.ReLU(),
                      nn.Conv2d(20,64,5),
                      nn.ReLU()
                     )
# 传入一个容器
model = nn.Sequential(OrderedDict([
          ('conv1', nn.Conv2d(1,20,5)),
          ('relu1', nn.ReLU()),
          ('conv2', nn.Conv2d(20,64,5)),
          ('relu2', nn.ReLU())
        ]))

class torch.nn.ModuleList(modules=None)

submodules保存在一个列表中

  • modules(list,optional):要添加的模块列表
class MyModule(nn.Module):
    def __init__(self):
        super(MyModule, self).__init__()
        self.linears = nn.ModuleList([nn.Linear(10, 10) for i in range(10)])

    def forward(self, x):
        # ModuleList can act as an iterable, or be indexed using ints
        for i, l in enumerate(self.linears):
            x = self.linears[i // 2](x) + l(x)
        return x

append(module):追加一个给定模块

extend(modules):追加一个模块列表

class torch.nn.ParameterList(parameters=None)

在列表中保存参数

class MyModule(nn.Module):
    def __init__(self):
        super(MyModule, self).__init__()
        self.params = nn.ParameterList([nn.Parameter(torch.randn(10, 10)) for i in range(10)])
        print(self.params)
    def forward(self, x):
        # ModuleList can act as an iterable, or be indexed using ints
        for i, p in enumerate(self.params):
            x = self.params[i // 2].mm(x) + p.mm(x)
        return x
    
Lmodule = MyModule()
ParameterList(
    (0): Parameter containing: [torch.FloatTensor of size 10x10]
    (1): Parameter containing: [torch.FloatTensor of size 10x10]
    (2): Parameter containing: [torch.FloatTensor of size 10x10]
    (3): Parameter containing: [torch.FloatTensor of size 10x10]
    (4): Parameter containing: [torch.FloatTensor of size 10x10]
    (5): Parameter containing: [torch.FloatTensor of size 10x10]
    (6): Parameter containing: [torch.FloatTensor of size 10x10]
    (7): Parameter containing: [torch.FloatTensor of size 10x10]
    (8): Parameter containing: [torch.FloatTensor of size 10x10]
    (9): Parameter containing: [torch.FloatTensor of size 10x10]
)

class torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True)

二维卷积:
输入形式input[ batch_size, channels, height_1, width_1 ]

  • batch_size 一个batch中样例的个数
  • channels 通道数,也就是当前层的深度
  • height_1, 图片的高
  • width_1, 图片的宽
    Conv2d参数:
  • in_channels:输入通道数
  • out_channels:输出feature map数即核的数量
  • kerner_size: 核的尺寸大小可以是元组
  • stride:卷积移动步长
  • padding: 填充数目
  • dilation: 相当于卷积上采样填充零dilation相当于卷积元素之间隔的0个数
  • groups:
通道分组比如说6个in_channels和6个out_channels(6个核设每个核的大小为3x3)分成两组记为in1,in2(都为三个通道),out1,out2(都为三个通道),(in1,out1)为一组,(in2,out2)为一组,这时候每个out1,out2的核都分别处理in1,in2的三个通道,也就是说out1,out2中的每个核的通道数为3,(这时候的参数为6个核x每个核对应的三个通道滤波器x每个滤波器对应的尺寸(长x宽) =  6x3x3x3这比远啦分成1组的时候6x6x3x3减少了一半的参数,分组的前提是,
in_channels must be divisible by groups 
out_channels must be divisible by groups
  • bias:有无偏置量
conv = nn.Conv2d(in_channels=6, out_channels=6, kernel_size=1, groups=3)
conv.weight.data.size()
---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

<ipython-input-44-ce31f9a7d10b> in <module>
----> 1 conv = nn.Conv2d(in_channels=2, out_channels=6, kernel_size=1, groups=3)
      2 conv.weight.data.size()


D:\Anaconda\envs\pytorch_gpu\lib\site-packages\torch\nn\modules\conv.py in __init__(self, in_channels, out_channels, kernel_size, stride, padding, dilation, groups, bias, padding_mode)
    325         super(Conv2d, self).__init__(
    326             in_channels, out_channels, kernel_size, stride, padding, dilation,
--> 327             False, _pair(0), groups, bias, padding_mode)
    328 
    329     @weak_script_method


D:\Anaconda\envs\pytorch_gpu\lib\site-packages\torch\nn\modules\conv.py in __init__(self, in_channels, out_channels, kernel_size, stride, padding, dilation, transposed, output_padding, groups, bias, padding_mode)
     20         super(_ConvNd, self).__init__()
     21         if in_channels % groups != 0:
---> 22             raise ValueError('in_channels must be divisible by groups')
     23         if out_channels % groups != 0:
     24             raise ValueError('out_channels must be divisible by groups')


ValueError: in_channels must be divisible by groups
conv = nn.Conv2d(in_channels=6, out_channels=3, kernel_size=3, groups=2)
conv.weight.data.size()
---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

<ipython-input-53-57b2a67b159f> in <module>
----> 1 conv = nn.Conv2d(in_channels=6, out_channels=3, kernel_size=3, groups=2)
      2 conv.weight.data.size()


D:\Anaconda\envs\pytorch_gpu\lib\site-packages\torch\nn\modules\conv.py in __init__(self, in_channels, out_channels, kernel_size, stride, padding, dilation, groups, bias, padding_mode)
    325         super(Conv2d, self).__init__(
    326             in_channels, out_channels, kernel_size, stride, padding, dilation,
--> 327             False, _pair(0), groups, bias, padding_mode)
    328 
    329     @weak_script_method


D:\Anaconda\envs\pytorch_gpu\lib\site-packages\torch\nn\modules\conv.py in __init__(self, in_channels, out_channels, kernel_size, stride, padding, dilation, transposed, output_padding, groups, bias, padding_mode)
     22             raise ValueError('in_channels must be divisible by groups')
     23         if out_channels % groups != 0:
---> 24             raise ValueError('out_channels must be divisible by groups')
     25         self.in_channels = in_channels
     26         self.out_channels = out_channels


ValueError: out_channels must be divisible by groups
conv = nn.Conv2d(in_channels=6, out_channels=6, kernel_size=3, groups=2)
conv.weight.data.size()
torch.Size([6, 3, 3, 3])
conv = nn.Conv2d(in_channels=6, out_channels=6, kernel_size=3, groups=2)
conv.weight.data.size()
torch.Size([6, 3, 3, 3])
conv = nn.Conv2d(in_channels=6, out_channels=6, kernel_size=3, groups=3)
conv.weight.data.size()
torch.Size([6, 2, 3, 3])

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,393评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,790评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,391评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,703评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,613评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,003评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,507评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,158评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,300评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,256评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,274评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,984评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,569评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,662评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,899评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,268评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,840评论 2 339

推荐阅读更多精彩内容