PyTorch入门笔记一

张量

引入pytorch,生成一个随机的5x3张量

1>>> from __future__ import print_function 2>>> import torch 3>>> x = torch.rand(5, 3) 4>>> print(x) 5tensor([[0.5555, 0.7301, 0.5655], 6 [0.9998, 0.1754, 0.7808], 7 [0.5512, 0.8162, 0.6148], 8 [0.8618, 0.3293, 0.6236], 9 [0.2787, 0.0943, 0.2074]])

声明一个5x3的张量,张量中所有元素初始化为0

>>> x = torch.zeros(5, 3, dtype=torch.long)

从数据直接构造张量,这里的数据一般是python数组

1>>> x = torch.tensor([5.5, 3]) 2>>> print(x) 3tensor([5.5000, 3.0000])

从一个已有的tensor上类似创建新的张量,新、旧张量的形状和数据类型相同,除非对dtype进行了覆盖声明

1>>> x = x.new_ones(5, 3, dtype=torch.double) 2>>> print(x) 3tensor([[1., 1., 1.], 4 [1., 1., 1.], 5 [1., 1., 1.], 6 [1., 1., 1.], 7 [1., 1., 1.]], dtype=torch.float64) 8>>> y = torch.rand_like(x, dtype=torch.float) 9>>> print(y) 10tensor([[0.6934, 0.9637, 0.0594], 11 [0.0863, 0.6638, 0.4728], 12 [0.3416, 0.0892, 0.1761], 13 [0.6831, 0.6404, 0.8307], 14 [0.6254, 0.4180, 0.2174]])

张量的size,numpy里是shape

1>>> print(x.size()) 2torch.Size([5, 3])

张量的操作

张量相加

1>>> x=torch.rand(5, 3) 2>>> y = torch.zeros(5, 3) 3>>> print(x + y) 4tensor([[0.8991, 0.9222, 0.2050], 5 [0.2478, 0.7688, 0.4156], 6 [0.4055, 0.9526, 0.2559], 7 [0.9481, 0.8576, 0.4816], 8 [0.0767, 0.3346, 0.0922]]) 9 10>>> print(torch.add(x, y)) 11tensor([[0.8991, 0.9222, 0.2050], 12 [0.2478, 0.7688, 0.4156], 13 [0.4055, 0.9526, 0.2559], 14 [0.9481, 0.8576, 0.4816], 15 [0.0767, 0.3346, 0.0922]]) 16 17>>> result = torch.empty(5, 3) 18>>> torch.add(x, y, out=result) 19tensor([[0.8991, 0.9222, 0.2050], 20 [0.2478, 0.7688, 0.4156], 21 [0.4055, 0.9526, 0.2559], 22 [0.9481, 0.8576, 0.4816], 23 [0.0767, 0.3346, 0.0922]]) 24 25>>> y.add_(x) 26tensor([[0.8991, 0.9222, 0.2050], 27 [0.2478, 0.7688, 0.4156], 28 [0.4055, 0.9526, 0.2559], 29 [0.9481, 0.8576, 0.4816], 30 [0.0767, 0.3346, 0.0922]])

张量内元素访问形式和numpy保持一致,如输出张量y的第二维度上下标是1的所有元素

1>>> print(y[:, 1]) 2tensor([0.9222, 0.7688, 0.9526, 0.8576, 0.3346])

iew函数改变tensor的形状,类似numpy的reshape

1>>> x = torch.randn(4, 4) 2>>> y = x.view(16) # 变成1x16的张量 3>>> z = x.view(-1, 8) # 变成第二维度是8,第一维度自动计算的张量,结果是2x8的张量 4>>> print(x.size(), y.size(), z.size()) 5torch.Size([4, 4]) torch.Size([16]) torch.Size([2, 8])

只有一个元素的向量,取这个元素

1>>> x = torch.randn(1) 2>>> print(x) 3tensor([0.8542]) 4>>> print(x.item()) 50.8541867136955261

转换成numpy数组

1>>> x = torch.rand(5, 3) 2>>> x.numpy() 3array([[0.9320856 , 0.473859 , 0.6787642 ], 4 [0.14365482, 0.1112923 , 0.8280207 ], 5 [0.4609589 , 0.51031697, 0.15313298], 6 [0.18854082, 0.4548 , 0.49709243], 7 [0.8351501 , 0.6160053 , 0.61391556]], dtype=float32)

除CharTensor外,所有的cpu张量从numpy转换成tensor

1import numpy as np 2a = np.ones(5) 3b = torch.from_numpy(a) 4np.add(a, 1, out=a) 5print(a) 6print(b)

在cpu和gpu之间移动tensor,

1if torch.cuda.is_available(): 2 device = torch.device("cuda") # a CUDA device object 3 y = torch.ones_like(x, device=device) # 直接在GPU设备上创建 4 x = x.to(device) # or just use strings ``.to("cuda")`` 5 z = x + y 6 print(z) 7 print(z.to("cpu", torch.double)) # ``.to`` can also change dtype together!

构建网络和损失函数

损失函数用来衡量输入和目标之间的距离

1from __future__ import print_function 2import torch 3import torch.nn as nn 4import torch.nn.functional as F 5 6class Net(nn.Module): 7 ## 定义了网络的结构 8 def __init__(self): 9 super(Net, self).__init__() 10 ## input is channel 1, output 6 channels with 3x3 convulutionanl kernel 11 self.conv1 = nn.Conv2d(1, 6, 3) 12 self.conv2 = nn.Conv2d(6, 16, 3) 13 # an affine operation: y = Wx + b, # 6*6 from image dimension 14 self.fc1 = nn.Linear(16*6*6, 120) 15 self.fc2 = nn.Linear(120, 84) 16 self.fc3 = nn.Linear(84, 10) 17 18 ## 前向传播,函数名必须是forward 19 def forward(self, x): 20 # Max pooling over a (2, 2) window 21 x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2)) 22 # If the size is a square you can only specify a single number 23 x = F.max_pool2d(F.relu(self.conv2(x)), 2) 24 x = x.view(-1, self.num_flat_features(x)) 25 x = F.relu(self.fc1(x)) 26 x = F.relu(self.fc2(x)) 27 x = self.fc3(x) 28 return x 29 30 def num_flat_features(self, x): 31 size = x.size()[1:] # all dimensions except the batch dimension 32 num_features = 1 33 for s in size: 34 num_features *= s 35 return num_features 36 37## 新建一个Net对象 38net = Net() 39print(net) 40params = list(net.parameters()) 41print(len(params)) 42print(params[0].size()) # conv1's .weight 43 44# 声明一个1x1x32x32的4维张量作为网络的输入 45input = torch.randn(1, 1, 32, 32) 46# input = torch.randn(1, 1, 32, 32) 47output = net(input) 48 49# net.zero_grad() 50# out.backward(torch.randn(1, 10)) 51target = torch.randn(10) 52target = target.view(1, -1) 53criterion = nn.MSELoss() 54loss = criterion(output, target) 55print(loss) 56 57print(loss.grad_fn) # MSELoss 58print(loss.grad_fn.next_functions[0][0]) # Linear 59print(loss.grad_fn.next_functions[0][0].next_functions[0][0]) # ReLU

网络的反向传播,为了反向传播损失(error)所做的只需要调用loss.backward()函数,如果没有清除已有的梯度,反向传播会累积梯度

调用loss.backward()函数,看以下conv1的bias的梯度在调用前后的差别。

1net.zero_grad() # zeroes the gradient buffers of all parameters 2 3print('conv1.bias.grad before backward') 4print(net.conv1.bias.grad) 5 6loss.backward() 7 8print('conv1.bias.grad after backward') 9print(net.conv1.bias.grad)

 使用SGD更新权重

公式:weight = weight - learning_rate * gradient

可以用下面的torch代码实现

1learning_rate = 0.01 2for f in net.parameters(): 3 f.data.sub_(f.grad.data * learning_rate)

 但是torch已经实现了各种权重更新方式,比如SGD, Nesterov-SGD, Adam, RMSProp等,可以直接调用

1import torch.optim as optim 2 3# create your optimizer 4optimizer = optim.SGD(net.parameters(), lr=0.01) 5 6# in your training loop: 7optimizer.zero_grad() # zero the gradient buffers 8output = net(input) 9loss = criterion(output, target) 10loss.backward() 11optimizer.step() # Does the update
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

swap空间的增减方法

(1)增大swap空间去激活swap交换区:swapoff v /dev/vg00/lvswap扩展交换lv:lvextend L 10G /dev/vg00/lvswap重新生成swap交换区:mkswap /dev/vg00/lvswap激活新生成的交换区:swapon v /dev/vg00/lvswap

PyTorch入门笔记一 - HelloWorld