【pytorch】学习笔记

pytorch学习笔记

  • Tensornumpy对象共享内存
  • torch.tensor()或者tensor.clone()总是会进行数据拷贝,新tensor和原来的数据不再共享内存。而torch.from_numpy()或者tensor.detach()可以新建一个tensor, 二者共享内存。当numpy的数据类型和Tensor的类型不一样的时候,数据会被复制,不会共享内存。
  • 要想使得Tensor使用autograd功能,只需要设置tensor.requries_grad=True.
  • tensor有data、grad、grad_fn
  • 没有参数的建议放在forward中使用nn.functional代替
  • rand/randn(*sizes) 均匀/标准分布
  • torch.Tensor()可以接受list,也可以tolist()
    在这里插入图片描述
  • tensor.view不会修改自身的数据,返回的新tensor与源tensor共享内存; 索引出来的结果也与原tensor共享内存,而高级索引操作的结果一般不和原始的Tensor共享内存。
a = t.arange(0, 6)
b = a.view(2, 3)
print(b)
b[0][0] = 3
print(a)
'''
tensor([[0, 1, 2],
        [3, 4, 5]])
tensor([3, 1, 2, 3, 4, 5])
'''

# 高级索引
x = t.arange(0,27).view(3,3,3)
x[[1, 2], [1, 2], [2, 0]] # x[1,1,2]和x[2,2,0]
x[[2, 1, 0], [0], [1]] # x[2,0,1],x[1,0,1],x[0,0,1]
x[[0, 2], ...] # x[0] 和 x[2]
  • gatherscatter_相对应,为互逆操作
# gather
out[i][j] = input[index[i][j]][j]  # dim=0
out[i][j] = input[i][index[i][j]]  # dim=1

在这里插入图片描述

  • tensor数据类型
    在这里插入图片描述

  • 归并操作
    在这里插入图片描述

  • 比较操作
    在这里插入图片描述

  • 矩阵的转置会导致存储空间不连续,需调用它的.contiguous方法将其转为连续

  • repeatexpand功能类似,但是repeat会把相同数据复制多份,因此会占用额外的空间,expand不会占用额外空间,只会在需要的时候才扩充,可极大节省内存。

  • id为在内存中的地址、.storage()、.data_ptr()返回tensor首元素的内存地址

  • torch.set_printoptions(precision=10)设置打印tensor时的数值精度和格式

  • torch.manual_seed(1000) 设置随机种子

  • 在反向传播过程中非叶子节点的导数计算完之后即被清空,可使用autograd.grad函数或者使用hook来保存。

torch.autograd.grad(z, y) # z对y的梯度,隐式调用backward()

# 第二种方法:使用hook
# hook是一个函数,输入是梯度,不应该有返回值
def variable_hook(grad):
    print('y的梯度:',grad)

x = t.ones(3, requires_grad=True)
w = t.rand(3, requires_grad=True)
y = x * w
# 注册hook
hook_handle = y.register_hook(variable_hook)
z = y.sum()
z.backward()

# 除非你每次都要用hook,否则用完之后记得移除hook
hook_handle.remove()
  • 不支持自动反向求导,就写一个Function
    在这里插入图片描述
  • torch.autograd.grad(y,x) 实现dy/dx
  • t.autograd.gradcheck(Sigmoid.apply, (test_input,), eps=1e-3) 返回bool 采用数值逼近方式检验计算梯度的公式
  • 赋值卷积核参数(初始化):
# 锐化卷积核
kernel = t.ones(3, 3)/-9.
kernel[1][1] = 1
conv = nn.Conv2d(1, 1, (3, 3), 1, bias=False)
conv.weight.data = kernel.view(1, 1, 3, 3)
out = conv(input)
  • Sequential、ModuleList、ParameterList
# Sequential的三种写法
net1 = nn.Sequential()
net1.add_module('conv', nn.Conv2d(3, 3, 3))
net1.add_module('batchnorm', nn.BatchNorm2d(3))
net1.add_module('activation_layer', nn.ReLU())

net2 = nn.Sequential(
        nn.Conv2d(3, 3, 3),
        nn.BatchNorm2d(3),
        nn.ReLU()
        )

from collections import OrderedDict
net3= nn.Sequential(OrderedDict([
          ('conv1', nn.Conv2d(3, 3, 3)),
          ('bn1', nn.BatchNorm2d(3)),
          ('relu1', nn.ReLU())
        ]))
'''
net1: Sequential(
  (conv): Conv2d(3, 3, kernel_size=(3, 3), stride=(1, 1))
  (batchnorm): BatchNorm2d(3, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (activation_layer): ReLU()
)
net2: Sequential(
  (0): Conv2d(3, 3, kernel_size=(3, 3), stride=(1, 1))
  (1): BatchNorm2d(3, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (2): ReLU()
)
net3: Sequential(
  (conv1): Conv2d(3, 3, kernel_size=(3, 3), stride=(1, 1))
  (bn1): BatchNorm2d(3, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (relu1): ReLU()
)
'''
  • 分组设置学习率
# 只为两个全连接层设置较大的学习率,其余层的学习率较小
special_layers = nn.ModuleList([net.classifier[0], net.classifier[3]])
special_layers_params = list(map(id, special_layers.parameters()))
base_params = filter(lambda p: id(p) not in special_layers_params, net.parameters())
optimizer = t.optim.SGD([
            {'params': base_params},
            {'params': special_layers.parameters(), 'lr': 0.01}
        ], lr=0.001 )
  • model.train()函数,它会将当前module及其子module中的所有training属性都设为True,相应的,model.eval()函数会把training属性都设为False。
  • nn.Module基类的构造函数
    在这里插入图片描述
  • 有一个预训练好的模型,需要提取模型的某一层(不是最后一层)的输出作为特征进行分类,但又不希望修改其原有的模型定义文件,这时就可以利用钩子函数
model = VGG()
features = t.Tensor()
def hook(module, input, output):
    '''把这层的输出拷贝到features中'''
    features.copy_(output.data)

handle = model.layer8.register_forward_hook(hook)
_ = model(input)
# 用完hook后删除
handle.remove()
  • result = obj.name会调用buildin函数getattr(obj, ‘name’),如果该属性找不到,会调用obj.getattr(‘name’)
  • obj.name = value会调用buildin函数setattr(obj, ‘name’, value),如果obj对象实现了__setattr__方法,setattr会直接调用obj.setattr(‘name’, value’)
  • nn.Module实现了自定义的__setattr__函数,当执行module.name=value时,会在__setattr__中判断value是否为Parameter或nn.Module对象,如果是则将这些对象加到_parameters和_modules两个字典中,而如果是其它类型的对象,如Variable、list、dict等,则调用默认的操作,将这个值保存在__dict__中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值