PyTorch学习之路

将PyTorch的学习过程记录下来。

什么是PyTorch

入门

张量与操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import torch
# 张量
# =============================================================================
x = torch.Tensor(5,3)
print(x)
#print(x.size(),type(x.size()))

# 操作
y = torch.rand(5,3)
# # =============================================================================
# 法1
print(x + y)
# 法2
print(torch.add(x,y))

# 定义一个输出张量
result = torch.Tensor(5,3)
torch.add(x,y, out = result)
print(result)
# in-place追加
y.add_(x)
print(y)
# # =============================================================================
print(y)
#x.copy_(y)
#print(x)
x.t_()
print(x)
print(x[:,1])
# =============================================================================

注意:torch包中带有下划线的op说明是就地进行的

Nmupy转换

将Torch张量转化为numpy数组

1
2
3
4
5
6
7
8
9
10
11
import torch
# =============================================================================
# Nmupy 转换
a = torch.ones(5)
print(a)
b = a.numpy()
print(b)
# 当给tensor a列表的每个值加一, numpys列表中的每个值加一
a.add_(1)
print(a)
print(b)

将numpy数组转化为Torch张量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import torch
# =============================================================================
# 将numpy数组转换成Torch张量
import numpy as np
a = np.ones(5)
b = torch.from_numpy(a)
np.add(a, 1, out=a)
print(a)
print(b)
a[0] = 333
print(a)
print(b)
## 结论和上面一样,无论是从tensor转换成numpy 还是反过来,都是一个内容修改,另一个也会变

# =============================================================================

CUDA传感器

cuda传感器是一个基于Python的科学计算包,主要分入如下2部分:

  • 使用GPU的功能代替numpy
  • 一个深刻的学习研究平台,提供最大的灵活性和速度
1
2
3
4
5
6
7
8
9
# CUDA传感器
import torch
x = torch.Tensor(5,3)
y = torch.rand(5,3)
if torch.cuda.is_available(): # 判断cuda是否可用
x = x.cuda()
print(x)
y = y.cuda()
x + y

Autograd:自动分化

autograd包是PyTorch所有神经网络的核心。

autograd包为Tensors上的所有操作提供了自动区分。它是一个逐个运行的框架,这意味着您的backprop由您的代码运行定义,每一次迭代都可以不同。

变量

autograd.Variable是包的中央类。它包含一个Tensor,并支持几乎所有定义的操作。完成计算后,可以调用.backward()并自动计算所有梯度。

变量与变量是有创造关系的,你可以对这些关系组成的函数求导。

创造一个变量:

1
2
3
4
import torch
from torch.autograd import Variable
x = Variable(torch.ones(2,2),requires_grad= True)
print(x)

输出

1
2
tensor([[1., 1.],
[1., 1.]], requires_grad=True)

做一个变量的操作:

1
2
y = x + 2
print(y)

输出

1
2
tensor([[3., 3.],
[3., 3.]], grad_fn=<AddBackward0>)

y 是由于操作造成的,所以它有一个创造者。

1
2
print(y.creator)  # 报错,已替换为grad_fn
print(y.grad_fn)

输出:

1
<AddBackward0 object at 0x00000226055E8940>

对y进行更多的操作

1
2
3
z = y * y * 3
out = z.mean()
print(z,out)

输出:

1
2
tensor([[27., 27.],
[27., 27.]], grad_fn=<MulBackward0>) tensor(27., grad_fn=<MeanBackward0>)

梯度

1
out.backward()

打印梯度 d(out)/dx

1
print(x.grad)

输出:

1
2
tensor([[4.5000, 4.5000],
[4.5000, 4.5000]])

自动求导可以做很多疯狂的事情

1
2
3
4
5
6
7
x = torch.rand(3)
x = Variable(x, requires_grad= True)
y = x * 2
while y.data.norm()< 1000:
y = y * 2

print(y)

解释:

y.data.norm()是用来求y的二范数

y的二范数小于1000的约束条件下,y的公式其实是 y = 1024*x

输出:

1
tensor([591.5636, 884.0807, 773.9807], grad_fn=<MulBackward0>)
1
2
3
gradients = torch.FloatTensor([0.1, 1.0, 0.0001])
y.backward(gradients)
print(x.grad)

输出:

1
tensor([1.0240e+02, 1.0240e+03, 1.0240e-01])

LeNet:

LeNet

显示CIFAR数据集图片

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import torchvision
import torchvision.transforms as transforms
import torch


transform = transforms.Compose([transforms.ToTensor(), # 转为tensor
transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)) # 归一化
])
trainset = torchvision.datasets.CIFAR10(root="./data", train=True, download=True, transform=transform)
print(len(trainset))
trainloader = torch.utils.data.DataLoader(trainset, batch_size=4,
shuffle=True, num_workers=2)

testset = torchvision.datasets.CIFAR10(root='./data', train=False, download=True, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=4,
shuffle=False, num_workers=2)
classes = ('plane', 'car', 'bird', 'cat',
'deer', 'dog', 'frog', 'horse', 'ship', 'truck')
# img, target = trainset[0]
# print(img)

import matplotlib.pyplot as plt
import numpy as np
def imshow(img):
img =img / 2 + 0.5 # unnormalize
npimg = img.numpy()
plt.imshow(np.transpose(npimg, (1,2,0)))
plt.show()

if __name__ == '__main__': # 开启多进程
dataiter = iter(trainloader)
images, labels = dataiter.next()
imshow(torchvision.utils.make_grid(images))
print(' '.join('%5s'%classes[labels[j]] for j in range(4)))

定义网络

等先把基础写完再继续补充😄

未完待续!!!


-------------The End-------------

本文标题:PyTorch学习之路

文章作者:Naqin

发布时间:2019年06月20日 - 21:06

最后更新:2019年11月05日 - 01:11

原始链接:https://chennq.top/Pytorch学习笔记/20190620-learning-PyTorch.html

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

Naqin wechat
欢迎看官加我微信!
坚持原创技术分享,您的支持将鼓励我继续创作!
0%