pytorch官方教程

疑问

  1. 官方说pytorch的高级功能:GPU加速的张量计算;自动求导系统(反向求导技术)。其实是相对于普通CPU网络说的,对于深度网络来说,这些东西可以忽略。
  2. pytorch是动态图,可以任意改变网络的行为,而且速度快。动态图和静态图有什么区别还是不清楚
    补充:1. 在预测的阶段,把output = output[:, -1, :].squeeze(dim=1)改为了output = output[:, -1, :].squeeze(),结果完全一致。
  3. 在autograd一节中,介绍了标量函数的求导方式,但是对于向量形式的求导,目前还不清楚如何设置求导参数如何设置。

记录

1. 什么是PyTorch

  1. torch是和Numpy类似的科学计算包,但是因为是小众语言Lua写的,所以不太流行。Pytorch是在torch基础上做的工作,然后最上层使用python封装了,所以叫pytroch。因此,pytorch可以作为numpy的替代品,而且支持GPU加速。同时,它也支持深度学习。当然,我们更重视后者。
  2. pytorch最核心的是autograd包,它为张量的所有操作提供了自动求导机制。
  3. Module里面定义的是各种layers,都包含可学习的参数;forword()函数定义的是整个网络完整的结构。

2. features相关

  1. 0.4版本之前Tensor是包装在Variable里面进行,

pytroch api

torch

  • 创建tensor
  • tensor的dtype

torch.randn(shape) 产生一个shape形状的tensor,其中的值是正太分布。

pytorch 60min入门

1. pytorch入门

创建tensor
import torch
torch.empty(*size, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False, pin_memory=False)
torch.rand(5, 3)
x = torch.zeros(5, 3, dtype=torch.long)
x = torch.randn(*size) # randn指的是随机产生正态分布的数据,均值为0,方差为1
x = torch.tensor([5.5, 3]) # 会根据入参自动推断,如果是[1,2]则,dtype是torch.int64;正常dtype是torch.float32
x = x.new_ones(5, 3, dtype=torch.double)   
x = torch.randn_like(x, dtype=torch.float)   

里面的requires_grad参数默认都是False,在网络中,只有parameters是需要grad的。
tensor.tensor(input)会根据input的数据类型,来判断输出的类型;tensor.Tensor()其实是tensor.FloatTensor(),底层调用的是tensor.tensor()

tensor自带方法
x = torch.tensor([1,2])
x.size() # 返回torch.Size([2])
x.numpy() # 获取numpy,底层numpy和tensor共享数据
## 可以自带一些操作
x.squeeze()
x.view()
x.mm(y)  # 矩阵的乘法
operations

同一个操作有很多种方式。

  • torch.add(x, y)
  • x.add_(y) # 把y加到x上面
  • x.view() # 相当于tf的reshape,不过第一个参数还是*args 可变参数

pytorch接口
可以看出torch和numpy的接口基本一致,而且两者共享底部数据

import numpy as np
a = np.ones(5)
b = torch.from_numpy(a)
np.add(a, 1, out=a)
print(a)
print(b)
  • torch.max(input, dim, keepdim=False, out=None) -> (Tensor, LongTensor) # 获取最大值
  • torch.argmax()
  • torch.clamp(input, min, max, out=None) 将input向量夹紧到[min, max]中
>>> x = torch.zeros(2, 1, 2, 1, 2)
>>> x.size()
torch.Size([2, 1, 2, 1, 2])
>>> y = torch.squeeze(x)
>>> y.size()
torch.Size([2, 2, 2])
>>> y = torch.squeeze(x, 0)
>>> y.size()
torch.Size([2, 1, 2, 1, 2])
>>> y = torch.squeeze(x, 1)
>>> y.size()
torch.Size([2, 2, 1, 2])
cuda tensor

不知道不同device上的数据相加,是如何处理的

if torch.cuda.is_available():
    device = torch.device("cuda")          # a CUDA device object,不进行编译,有没有cuda也可以执行,但是tensor.to(device)会失败
    y = torch.ones_like(x, device=device)  # directly create a tensor on GPU
    x = x.to(device)                       # or just use strings ``.to("cuda")``
    z = x + y
    print(z)
    print(z.to("cpu", torch.double))

输出如下:
tensor([0.5480], device='cuda:0')
tensor([0.5480], dtype=torch.float64)

2. AUTOGRAD

构建可求导tensor

torch.tensor(requires_grad=True)

创建了tensor,之后所有的operation产生的tensor,都会自带一个Function。
对tensor求grad,只需要调用out.backword(grad_variables)就可以了,但是grad_variables参数非常古怪,现在也不知道设置多少才合适?

detach求grad

两种方案:

  1. with torch.no_grad():
  2. x.detach()
  3. requires_grad_(False)

3. NEURAL NETWORKS

如何训练一个神经网络,下面的流程可以说是很清晰了:

  1. Define the neural network that has some learnable parameters (or weights)
    第一种方式就是定义一个类,继承nn.Module;另一种就是直接使用nn.Sequential()。直观感受,第一种方式定制化能力更强一些。
    第一种方式:
class Net(nn.Module):
  def __init__(self):
    # define layers
  
  def forword(input):
    # define network

第二种方式:

model = nn.Sequential(
    nn.Linear(D_in, H),
    nn.ReLU(),
    nn.Linear(H, D_out),
)
  1. Iterate over a dataset of inputs
  2. Process input through the network
net = Net()
output = net(input)
  1. Compute the loss (how far is the output from being correct)
    所有的loss也都存放在了torch.nn包里面,接收一个(output, target)pair,产生一个loss tensor
criterion = nn.MSELoss()
loss = criterion(output, target)
  1. Propagate gradients back into the network’s parameters
loss.backward()
  1. Update the weights of the network, typically using a simple update rule: weight = weight - learning_rate * gradient
optimizer = optim.SGD(net.parameters(), lr=0.01)
optimizer.zero_grad()   # zero the gradient buffers
output = net(input)
loss = criterion(output, target)
loss.backward()
optimizer.step()    # Does the update

tips

  • nn.Module. 神经网络模型,直接作为定义神经网络的父类。
  • torch.optim 这个包包含了所有的optim函数
  • net.parameters() 返回的是Parameter对象,如果想获取值,需要使用list(Parameters)

4. TRAINING A CLASSIFIER

前面定义网络,定义loss和optim的阶段省略了,只记录下面计算loss和更新参数的部分:

for epoch in range(2):  # loop over the dataset multiple times

    running_loss = 0.0
    for i, data in enumerate(trainloader, 0):
        # get the inputs; data is a list of [inputs, labels]
        inputs, labels = data

        # zero the parameter gradients
        optimizer.zero_grad()

        # forward + backward + optimize
        outputs = net(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        # print statistics
        running_loss += loss.item()
        if i % 2000 == 1999:    # print every 2000 mini-batches
            print('[%d, %5d] loss: %.3f' %
                  (epoch + 1, i + 1, running_loss / 2000))
            running_loss = 0.0

print('Finished Training')

其中loss和optim的定义如下:

criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)

可以看出,loss不依赖参数;optim是参数以来的,它的目的是更新所有的parameter。

save model & load model

torch.save(net.state_dict(), PATH)

state_dict 是一个python的字典格式,以字典的格式存储,然后以字典的格式被加载,而且只加载key匹配的项

net = Net()
net.load_state_dict(torch.load(PATH))

我们在加载的时候,可以只加载我们需要的层,不需要的层不加载。

https://www.jianshu.com/p/6287a2c85e57

predict

在进行predict的时候,需要把predict的代码放到with torch.no_grad():里面

training on GPU

不知道为什么,默认不是GPU,需要把两类数据送到目标device中:

  1. Net的parameters
  2. 数据集的data

优化器的基类

class torch.optim.Optimizer(params, defaults)
包含的方法:
1、load_state_dict(state_dict)
optimizer的状态。是一个调用state_dict()所返回的对象。和state_dict()配合使用,先保存吗, 再加载。
2、state_dict()
以dict返回optimizer的状态。和model的state_dict相似,一般在保存模型参数的时候可以把优化器的参数一起保存。
3、step(closure)
单步优化
4、zero_grad()
清空所有被优化过的Variable的梯度. 在写的时候也可以用model.zero_grad()

极好的例子

https://www.jianshu.com/p/d8926a2b9e76

optimizer.zero_grad() # 来清空model参数的grad
loss.backward() # 进行反向传播
optimizer.step() # 进行梯度更新

torch.nn与torch.nn.functional之间的区别和联系

所有需要参数的实现都是nn.Module(),torch.nn.Module的底层实现也是nn.functioncal。
有些nn的实现需要参数,比如 nn.functioncal的入参需要传入这些模型参数,让用户去定义会比较麻烦,所以构建了torch.nn.Module,在init里面构建了这些参数,就不用用户自己定义了。
同时有保留了nn.functional的接口,保留这种灵活性。
但是不需要参数的layer就可以直接使用nn.functional()
【但是也有例外,比如nn.Softmax() 这个明明没有参数,但是还是构建了Module】

1. Numpy

https://blog.csdn.net/u012300744/article/details/80423135
点乘:

  • m * n
  • np.multiply(m, n)

矩阵乘法:

  • np.matmul(b, a)
  • np.dot(a,a)
  • a.dot(a)

pytorch和tensorflow的区别

个人感觉,pytorch比tensorflow好用多了,优势如下:

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

推荐阅读更多精彩内容