2021-05-10

zip

zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。

如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以将元组解压为列表

a = [1,2,3]
b = [4,5,6]
c = [4,5,6,7,8]
zipped = zip(a,b)     # 打包为元组的列表
输出 [(1, 4), (2, 5), (3, 6)]
zip(a,c)              # 元素个数与最短的列表一致
[(1, 4), (2, 5), (3, 6)]
zip(*zipped)    # 与 zip 相反,*zipped 可理解为解压,返回二维矩阵式
[(1, 2, 3), (4, 5, 6)]

python3以后,要想输出zip之后的具体内容,需要用list,如

from collections import OrderedDict
outputs = ['weight1', 'weight2','weight3']
train_outputs = OrderedDict([('layer1', []), ('layer2', []), ('layer3', [])])

print(list(zip(train_outputs.keys(), outputs)))
>>>[('layer1', 'weight1'), ('layer2', 'weight2'), ('layer3', 'weight3')]

加载别人预训练好的模型

例如加载wide_resnet50:

import torch
wide_resnet50_2 = torch.hub.load('pytorch/vision:v0.9.0', 'wide_resnet50_2', pretrained=True)

注意:加载模型这句话要跟在import torch之后,不然后面如果有import torchvision的话,可能就是从torchvision里面加载的,就找不到这个模型了

另一种trans的方式

trans = T.Compose([T.Resize(resize, Image.ANTIALIAS)])

这里这个Image.ANTIALIAS可以减少图片resize之后的噪声(有些图片resize之后会出现噪声)相当于一个滤镜的操作

查看pytorch的版本

import torch
print(torch.__version__)

hook函数

由于pytorch会自动舍弃计算图的中间梯度,所以用hook函数可以访问中间的特征或者是梯度
钩子函数包括Variable的钩子或者是nn.Module的钩子
钩子函数的使用场景有:

1 torch.autograd.Variable.register_hook 
2 torch.nn.Module.register_backward_hook 
3 torch.nn.Module.register_forward_hook

第一个是register_hook,是针对Variable对象的,
后面的两个:register_backward_hook和register_forward_hook是针对nn.Module这个对象的

hook的价值:
一个简单的例子:
计算如下的z的最小值:
x ∈ R 2 , y = 2 x + 2 , z = y 2 x\in R^2, y=2x+2,z=y^2 xR2,y=2x+2,z=y2
则很简单根据二次函数性质,可以求出当 x = − 1 x=-1 x=1时, z z z取得最小值
代码如下:

import torch
from torch.autograd import Variable
x = Variable(torch.randn(1), requires_grad=True)
optimizer = torch.optim.Adam([x], lr=0.01)
#注意1:params argument given to the optimizer should be an iterable of Tensors or dicts, but got torch.FloatTensor
#平时optimizer的参数给的是model.parameters,
for i in range(1000):
    y = 2*x+2
    z = torch.pow(y, 2)
    optimizer.zero_grad()
    z.backward()
    optimizer.step()
print(x.data)

执行1000个epoch之后x的输出为-1.

但是没法求中间y的变量,

print(y.grad)
报错:'NoneType' object is not callable

因为pytorch的机制是:对于中间变量,一旦它们完成了自身反传的使命,计算图就会被释放掉。
这个时候就可以用hook来把想求的中间变量的梯度“钩”起来,需要注意的是register_hook函数接收的是一个函数

import torch
from torch.autograd import Variable
x = Variable(torch.randn(1), requires_grad=True)
optimizer = torch.optim.Adam([x], lr=0.01)
grad_list = []
def print_grad(grad):
    grad_list.append(grad)

for i in range(1000):
    y = 2*x+2
    z = torch.pow(y, 2)
    y.register_hook(print_grad)
    print(x.grad)
    optimizer.zero_grad()
    z.backward()
    optimizer.step()
    #x.data -= lr*x.grad.data
print(x.data)
print(grad_list)

展示一下前几个x和y的输出:

z对x的梯度:
tensor([19.6492])
tensor([19.5692])
tensor([19.4892])
tensor([19.4093])
z对y的梯度:
[tensor([9.8246]), tensor([9.7846]), tensor([9.7446]), tensor([9.7046])

可以看出对x的梯度是对y的梯度的2倍,原因也很简单,根据微积分中的链式求导法则:
d z / d x = ( d z / d y ) ∗ ( d y / d x ) , d y / d x = 2 , 所 以 d z / d x = 2 ∗ ( d z / d y ) dz/dx=(dz/dy)*(dy/dx),dy/dx=2,所以dz/dx=2*(dz/dy) dz/dx=(dz/dy)(dy/dx),dy/dx=2,dz/dx=2(dz/dy)

利用hook还可以修改梯度

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这个数据可以使用Python进行解析和处理。可以按照以下步骤进行: 1. 将数据分割成每个数据项。 ``` data_items = data.split(',') ``` 2. 对于每个数据项,将其按#分割成四个小项,并存储到一个列表中。 ``` data_list = [] for item in data_items: item_list = item.split('#') data_list.append(item_list) ``` 3. 对于每个小项,进行相应的类型转换。 ``` for item in data_list: item[0] = int(item[0]) # 题号转换为整数 item[1] = datetime.datetime.strptime(item[1], '%Y-%m-%d %H:%M:%S') # 时间转换为datetime类型 if item[2] != '': # 操作类型转换为整数 item[2] = int(item[2]) item[3] = str(item[3]) # 科目转换为字符串类型 ``` 4. 可以按照需要对数据进行进一步处理,如按照题号、时间等进行排序、筛选等操作。 完整的Python代码如下: ``` import datetime data = '''1#2021-05-18 14:31:55##初级会计实务,2#2021-05-18 14:31:57#12#初级会计实务,2#2021-05-18 14:32:08##初级会计实务,3#2021-05-18 14:32:09#12#初级会计实务,4#2021-05-18 14:32:34#12#初级会计实务,4#2021-05-18 14:32:45##初级会计实务,5#2021-05-18 14:32:46#12#初级会计实务,5#2021-05-18 14:32:57##初级会计实务,6#2021-05-18 14:33:00#12#初级会计实务,7#2021-05-18 14:33:44#12#初级会计实务,7#2021-05-18 14:34:42##初级会计实务,8#2021-05-18 14:34:43#12''' # 将数据分割成每个数据项 data_items = data.split(',') # 对于每个数据项,将其按#分割成四个小项,并存储到一个列表中 data_list = [] for item in data_items: item_list = item.split('#') data_list.append(item_list) # 对于每个小项,进行相应的类型转换 for item in data_list: item[0] = int(item[0]) # 题号转换为整数 item[1] = datetime.datetime.strptime(item[1], '%Y-%m-%d %H:%M:%S') # 时间转换为datetime类型 if item[2] != '': # 操作类型转换为整数 item[2] = int(item[2]) item[3] = str(item[3]) # 科目转换为字符串类型 print(data_list) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值