Tensor基础
pytorch中的数据以tensor的形式存在,类似于numpy中的ndarrays。可以更好地利用GPU加速运算。
torch.empty():
torch.random()
torch.zeros(行数,列数,dtype=torch.long)
torch.tensor([1,2,3,4])
还可以从已有的张量(x)中定义一个新的张量,如果不进行指定会复用输入张量的属性(如dtype)
x = x.new_ones(5, 3, dtype=torch.double) # new_* methods take in sizes
print(x)
x = torch.randn_like(x, dtype=torch.float) # override dtype!
print(x) # result has the same size
x.size()
加法操作:
x+y 或 torch.add(x,y,output=...),指定output参数则将结果赋给该参数
y.add_(x)
x.copy_(y), x.t_()
可以像numpy一样对张量进行索引。
resize/reshape:
torch.view()
x = torch.randn(4, 4)
y = x.view(16)
z = x.view(-1, 8) #-1表示该维根据另一维计算得到。
.item()
张量各种操作参考:https://pytorch.org/docs/stable/torch.html
与numpy转换
.numpy()
torch.from_numpy()
并且如果是在CPU中,张量和numpy数组共享同一个内存,改变一个的值会影响另一个。
在CPU中除了CharTensor之外,所有Tensor都支持与NumPy的互相转换。
CUDA Tensor
if torch.cuda.is_available():
device = torch.device("cuda") # a CUDA device object
y = torch.ones_like(x, device=device) # directly create a tensor on GPU
x = (device) # or just use strings ``.to("cuda")``
z = x + y
print(z)
print(z.to("cpu", torch.double)) # ``.to`` can also change dtype together!
Autograd
官方文档:https://pytorch.org/docs/stable/autograd.html#function
Tensor类的属性 .requires_grad 如果被设置为 True (默认为 False ),所有对这个tensor的操作都会被记录下来。在调用 .backward() 函数时,梯度就会被自动计算。计算后的梯度会被累加到属性 .grad 中。如果需要清零梯度,可以使用 .zero_grad()
只有标量可以使用 .backward()求梯度,如果不是标量可以在该函数中传入一个矩阵进行点积得到标量。
所有非用户定义的(通过操作产生的)tensor都会有一个 grad_fn
如果某些操作不需要算入求梯度的步骤中,可以使用 with torch.no_grad(): 或是使用 .detach()
torch.nn
官方文档:https://pytorch.org/docs/stable/nn.html
自定义的神经网络需要继承nn.Module类, __init__ 函数中定义网络的结构, forward()
训练一个神经网络的步骤为:
- 定义包含可学习参数(或权重)的神经网络
- 在数据集或输入上进行迭代
- 通过网络处理输入
- 计算损失
- 将梯度传播回网络的参数
- 更新网络的权重,通常是使用
weight = weight - learning_rate * gradient
通过 .parameters()
nn package中自带了许多损失函数,可以直接进行调用,网络的输出结果和目标结果作为参数。
当对损失值(loss)调用 .backward() 网络中所有 requires_grad=True 的tensor都会关于loss计算梯度并累加到 grad 参数中。
反向传播时先清零梯度,调用loss的 .backward()
torch.optim 中预先定义了许多优化函数用于权重的更新,定义好优化函数后每次更新时调用 .step()
# create your optimizer
optimizer = optim.SGD(net.parameters(), lr=0.01)
# in your training loop:
optimizer.zero_grad() # zero the gradient buffers
output = net(input)
loss = criterion(output, target)
loss.backward()
optimizer.step() # Does the update
可以为不同层指定不同的学习参数
optim.SGD([
{'params': model.base.parameters()},
{'params': model.classifier.parameters(), 'lr': 1e-3}
], lr=1e-2, momentum=0.9)
数据读取
针对计算机视觉,pytorch还提供了 torchvision 包,其中 torchvision.datasets
数据集中的图片都是取值为$[0,1]$类型为PIL Image 的图片。
可以使用 torchvision.transforms 包含对数据的多种操作, .Compose()
读取数据集举例:
transform = transforms.Compose(
[transforms.ToTensor(),
transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])
#表示第一步将数据集中数据转为tensor,第二步进行规范化。第一个参数表示(R,G,B)的均值,第二个参数为方差
trainset = torchvision.datasets.CIFAR10(root='./data', train=True,
download=True, transform=transform)
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')
pytorch中有两种类型的数据集,map-style和Iterable-style。
Iterable-style的数据集可以调用 iter(dataset)
会返回一个读数据库的数据流。
Map-style的数据集可以使用torch.utils.data.Sampler 类指定数据读取时的下标序列。
collate_fn