Pytorch 容器

1. nn.Sequential(*layers)

类似于torch7中的Sequential,将每一个模块按照他们的顺序送入到nn.Sequential中 ,输入可以是一些列有顺序的模块

conv1=nn.FractionalMaxPool2d(2,output_ratio=(scaled,scaled))
conv2=nn.Conv2d(D,D,kernel_size= 3,stride=1,padding=1,bias=True)
conv3=nn.Upsample(size=(inputRes,inputRes),mode='bilinear')
return nn.Sequential(conv1,conv2,conv3)

输入也可以是一个orderDict

# Example of using Sequential with OrderedDict
model = nn.Sequential(OrderedDict([           #orderdict按照建造时候的顺序进行存储
          ('conv1', nn.Conv2d(1,20,5)),
          ('relu1', nn.ReLU()),
          ('conv2', nn.Conv2d(20,64,5)),
          ('relu2', nn.ReLU())
        ]))

orderdict示例

#orderdict部分源代码来自https://www.cnblogs.com/gide/p/6370082.html,稍有改动
import collections
print "Regular dictionary"
d={}
d['a']='A'
d['b']='B'
d['c']='C'
for k,v in d.items():
    print k,v

print "\nOrder dictionary"
d1 = collections.OrderedDict()
d1['a'] = 'A'
d1['b'] = 'B'
d1['c'] = 'C'
d1['2'] = '2'
d1['1'] = '1'
for k,v in d1.items():
    print k,v

Pytorch 容器_第1张图片

输入也可以是list,然后输入的时候用*来引用

 layers = []
 layers.append(block(inplanes, outplanes,inputRes,baseWidth=9,cardinality=4,stride=1,preact=preact))
 return nn.Sequential(*layers)  # 不加*号,会报错 TypeError: list is not a Module subclass

因为从nn.Sequential的定义来看
Pytorch 容器_第2张图片
输入要么事orderdict,要么事一系列的模型,遇到上述的list,必须用*号进行转化

Sequential好处是啥呢?

    def _make_fc(self, inplanes, outplanes):
        bn = nn.BatchNorm2d(inplanes)
        conv = nn.Conv2d(inplanes, outplanes, kernel_size=1, bias=True)
        return nn.Sequential(
                conv,
                bn,
                self.relu,
            )

在前传forward的时候,一步完成,而不需要conv,bn,relu在forward函数里都写一遍

2. torch.nn.ModuleList

存储一系列模型的module list,操作类似于标准的python list

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

代码中的[nn.Linear(10, 10) for i in range(10)]是一个python列表,必须要把它转换成一个module list列表才可以被pytorch使用,否则在运行的时候会报错,什么错呢?RuntimeError: Input type (CUDAFloatTensor) and weight type (CPUFloatTensor) should be the same,如果这部分不转成modulelist(gpu),那么只是pythonlist(cpu) 来承载这些模型,定造成cpu和gpu的冲突。

3 python *号

单个星号代表这个位置接收任意多个非关键字参数,并转化成元表。也就是b 会接受除了a之外的剩下的非关键字参数,需要注意的是加在形参面前代表的是收集参数,如果*号加在了是实参上(例如第十四行),代表的是将输入迭代器拆成一个个元素

d1 = collections.OrderedDict()
d1['a'] = 'A'
d1['b'] = 'B'
d1['c'] = 'C'
d1['2'] = '2'
d1['1'] = '1'

def one(a,*b):
    print(b)
def two(*b):
    print(b)
c = [6,7,8,9]
one(1,2,3,4,5,6)
one(*c)    #传入实参的时候,加上*号,可以将列表中的元素拆成一个个的元素
one(*d1)   #传入实参的时候,加上*号,可以将字典中的元素拆成一个个的元素
one(c)
one(d1)
two(c)
two(d1)

Pytorch 容器_第3张图片

** 双星号代表这个位置接收任意多个关键字参数,并按照关键字转化成字典
用双星号传入实参的时候,一定是所有的实参必须带有关键字

def three1(**b):
    print(b)

three(a=1,b=2,c=3,d=4,e=5,f=6)

4. torch CMul CAdd在pytorch中消失了,代以* , +

CMul : component-wise multiplication

CAdd: component-wise addition

你可能感兴趣的:(Pytorch 容器)