torch学习——持续补充

重点1——numpy和torch的相互转换

torch和numpy互相转换的时候,内存是共享的!因此改一个,必将修改另一个

import numpy as np
a = np.random.rand(4,3)
print(a)
array([[0.53097097, 0.39967826, 0.2925655 ],
       [0.41214625, 0.85092555, 0.88813825],
       [0.74869623, 0.20646449, 0.83864256],
       [0.80688304, 0.89462968, 0.12394582]])
b = torch.from_numpy(a)
print(b)
0.5310  0.3997  0.2926
 0.4121  0.8509  0.8881
 0.7487  0.2065  0.8386
 0.8069  0.8946  0.1239
[torch.DoubleTensor of size 4x3]
b.mul_(2)
print(b)
print(a)
1.0619  0.7994  0.5851
 0.8243  1.7019  1.7763
 1.4974  0.4129  1.6773
 1.6138  1.7893  0.2479
[torch.DoubleTensor of size 4x3]
array([[1.06194194, 0.79935653, 0.58513101],
       [0.8242925 , 1.7018511 , 1.7762765 ],
       [1.49739246, 0.41292898, 1.67728512],
       [1.61376609, 1.78925936, 0.24789164]])

 

重点2——等号两边是两个完全不一样的变量

当一个变量(numpy和torch都是)被重新赋值的时候,其内存会被重新分配!不过像+=,-=都不会重新分配内存,因此为了内存,尽量多的使用覆盖操作吧~

a=np.random.rand(3,2)
print(id(a))
139997338436912
a*=2
print(id(a))
139997338436912
a=a*2
print(id(a))
139997338438112

 

重点3——少了一个逗号,元组就变为了普通变量

当使用torch.transform中的Normalize变换的时候,注意给定的参数是数据分布的均值(mean)和标准差(std),且一定注意的一点是,当你的图像只是一个通道的时候,传入的一定是一个元祖,而不是单个元素,代码如下

transform = transforms.Compose([transforms.ToTensor(),
                                transforms.Normalize((0.5,), (0.5,)),  # 一定不要少了这个点!!!
                              ])

如上所述,如果少了0.5后面的",",则算法认为你传入了一个数值,那么,随后再从dataloader中取数据的时候就会出现如下错误too many indices for tensor of dimension 0,而错误的定位就在取batch数据的地方。


 

重点4——行列操作

在numpy和torch中,跟行列有关的函数,dim(axis)=0表示按列操作,dim(axis)=1表示按行操作

a = np.random.rand(4, 2)
array([[0.84739963, 0.77991831],
       [0.10310179, 0.13808552],
       [0.92275984, 0.13912286],
       [0.6742185 , 0.32243499]])
''' 按行操作 '''
np.sum(a,axis=1)  
array([1.62731793, 0.24118731, 1.0618827 , 0.99665349])

''' 按列操作 '''
np.sum(a,axis=0)
array([2.54747976, 1.37956167])

 

重点5——reshape和permute操作

在torch中,reshape操作是按照行优先进行拉伸或者折叠的,而permute就相当于transpose的高级版,可以对任意多的维度进行转置,而transpose只能对两个维度进行翻转;

In [4]: import torch

In [5]: a=torch.Tensor([1,2,3,4,5,6,7,8,9,10,11,12])

In [6]: a
Out[6]: tensor([ 1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10., 11., 12.])

In [7]: a.shape
Out[7]: torch.Size([12])

In [8]: b=a.reshape((3,4))

In [9]: b
Out[9]: 
tensor([[ 1.,  2.,  3.,  4.],
        [ 5.,  6.,  7.,  8.],
        [ 9., 10., 11., 12.]])

In [10]: c=b.permute(1,0)

In [11]: c
Out[11]: 
tensor([[ 1.,  5.,  9.],
        [ 2.,  6., 10.],
        [ 3.,  7., 11.],
        [ 4.,  8., 12.]])

In [12]: d = c.reshape(12)

In [13]: d
Out[13]: tensor([ 1.,  5.,  9.,  2.,  6., 10.,  3.,  7., 11.,  4.,  8., 12.])

 

重点5——nn.ModuleList和nn.Sequential模块

在torch中,对一系列的操作而言,既可以用ModuleList,也可以用Sequential,两个模块很相近,但是也有不同的地方,此处做一个总结:

相同点
  1. 都可以使用迭代的方式对tensor进行操作,如下:
seq = nn.Sequential(
    nn.Conv2d(3, 64, 3, 1, 1),
    nn.ReLU(inplace=True),
    nn.Conv2d(64, 64, 3, 1, 1),
    nn.ReLU(inplace=True),
    nn.Conv2d(64, 64, 3, 1, 1),
    nn.ReLU(inplace=True)
)

mod = nn.ModuleList([
    nn.Conv2d(3, 64, 3, 1, 1),
    nn.ReLU(inplace=True),
    nn.Conv2d(64, 64, 3, 1, 1),
    nn.ReLU(inplace=True),
    nn.Conv2d(64, 64, 3, 1, 1),
    nn.ReLU(inplace=True)
])

input = torch.randn(1, 3, 10, 10)

x = input
for op in seq:
    x = op(x)
print(x.shape)

x = input
for op in mod:
    x = op(x)
print(x.shape)

输出为


torch.Size([1, 64, 10, 10])
torch.Size([1, 64, 10, 10])
  1. 都可以使用apply函数对内部子模块进行初始化
i = 0
def init_weight(m):
    global i
    if isinstance(m, nn.Conv2d):
        print('>>> time: {}'.format(i))
        init.normal_(m.weight.data)
        i += 1
i = 0
seq.apply(init_weight)
i = 0
mod.apply(init_weight)

输出为

>>> time: 0
>>> time: 1
>>> time: 2
>>> time: 0
>>> time: 1
>>> time: 2

 

不同点
  1. 初始化的方式不同,例如上面的两种情况:

    • nn.Sequential的初始化接收的是一个个操作,除此之外,还可以接受一个dict指定每个操作的名字,默认的话以序号命名;
    • nn.ModuleList的初始化接收的是一个列表,列表中包含所有要进行的操作,不接受指定每个操作的名字的方式,只能以序号命名;
  2. 添加操作的方式不同:

    • nn.ModuleList添加操作的方式有三种,append,extend,insert,基本和list的区别一样,不在赘述;
    • nn.Sequential添加操作的方式只有一种,add_module,接收两个参数,第一个是名字或者序号,第二个是操作;
  3. 操作的整体性不一样:

    • nn.Sequential虽然可以用迭代的方式进行,但是其整体是一个操作,亦即该操作与内置的操作一样,具有梯度等信息;
    • nn.ModuleList不是一个整体,且只能用迭代的方式进行,本身不具有梯度等信息;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值