1.导入pytorch包
import torch
验证PyTorch是否安装成功
x = torch.rand(5,3)
x
tensor([[0.6694, 0.1483, 0.4672],
[0.9607, 0.4880, 0.3327],
[0.6390, 0.4924, 0.3028],
[0.8347, 0.4373, 0.5038],
[0.4654, 0.1590, 0.2173]])
检测GPU及CUDA是否可用
torch.cuda.is_available()
True
2.Tensor张量
2.1构建未初始化张量
x = torch.empty(5, 3)
x
tensor([[9.8266e-39, 4.2246e-39, 1.0286e-38],
[1.0653e-38, 1.0194e-38, 8.4490e-39],
[1.0469e-38, 9.3674e-39, 9.9184e-39],
[8.7245e-39, 9.2755e-39, 8.9082e-39],
[9.9184e-39, 8.4490e-39, 9.6429e-39]])
2.2构造一个全为0,数据类型为long的张量
x = torch.zeros(5, 3, dtype=torch.long)
x
tensor([[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]])
2.3根据已有数据构造张量
x = torch.tensor([[4, 3], [1, 2]])
x
tensor([[4, 3],
[1, 2]])
2.4初始化两个张量
x = torch.randint(1, 10, (3, 5))
y = torch.randint(1, 10, (3, 5))
x
tensor([[2, 7, 8, 3, 8],
[5, 1, 7, 4, 4],
[7, 8, 9, 9, 8]])
y
tensor([[5, 6, 2, 7, 9],
[5, 3, 5, 1, 5],
[7, 8, 3, 9, 5]])
2.5.Tensors支持的四种加法运算
第一种加法运算
x + y
tensor([[ 7, 13, 10, 10, 17],
[10, 4, 12, 5, 9],
[14, 16, 12, 18, 13]])
第二种加法运算
torch.add(x, y)
tensor([[ 7, 13, 10, 10, 17],
[10, 4, 12, 5, 9],
[14, 16, 12, 18, 13]])
第三种加法运算
result = torch.Tensor(3,5)
torch.add(x, y, out=result)
tensor([[ 7., 13., 10., 10., 17.],
[10., 4., 12., 5., 9.],
[14., 16., 12., 18., 13.]])
第四种加法运算
y.add(x)
tensor([[ 7, 13, 10, 10, 17],
[10, 4, 12, 5, 9],
[14, 16, 12, 18, 13]])
3.autograd自动求导
#创建张量x,并设置requires_grad=True用来追踪计算历史
x = torch.ones(2, 2, requires_grad=True)
x
tensor([[1., 1.],
[1., 1.]], requires_grad=True)
#对张量做一次运算
y = x + 3
y
tensor([[4., 4.],
[4., 4.]], grad_fn=<AddBackward0>)
#y结果有grad_fn属性
y.grad_fn
<AddBackward0 at 0x24d2e69c5e0>
#对y进行更多操作
z = y * y * 5
out = z.mean()
print(z, out)
tensor([[80., 80.],
[80., 80.]], grad_fn=<MulBackward0>) tensor(80., grad_fn=<MeanBackward0>)
a = torch.randn(2,2)
b = ((a*5)/(a-1))
b.requires_grad #requires_grad没有指定,默认值为False
False
b.requires_grad_(True) #b.requires_grad_()改变了现有张量的b.requires_grad标志
tensor([[-0.0968, 18.3622],
[ 0.2433, 1.6085]], requires_grad=True)
c = (b * b).sum()
c.grad_fn
<SumBackward0 at 0x24d2ec393a0>
4.神经网络
4.1定义神经网络
import torch
import torch.nn as nn
import torch.nn.functional as F
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.conv1 = nn.Conv2d(1, 6, 5)
self.conv2 = nn.Conv2d(6, 16, 5)
self.fc1 = nn.Linear(16 * 5 * 5, 120)
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, 10)
def forward(self, x):
x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))
x = F.max_pool2d(F.relu(self.conv2(x)), 2)
x = torch.flatten(x, 1)
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = self.fc3(x)
return x
net = Net()
print(net)
Net(
(conv1): Conv2d(1, 6, kernel_size=(5, 5), stride=(1, 1))
(conv2): Conv2d(6, 16, kernel_size=(5, 5), stride=(1, 1))
(fc1): Linear(in_features=400, out_features=120, bias=True)
(fc2): Linear(in_features=120, out_features=84, bias=True)
(fc3): Linear(in_features=84, out_features=10, bias=True)
)
torch.nn.Conv2d语法格式如下:
torch.nn.Conv2d(in_channles, out_nels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True)
torch.nn.Linear语法格式如下:
yorch.nn.Linear(in_fetures, out_features, bias=True)
torch.nn.functional.max_pool2d语法格式如下:
torch.nn.functional.max_pool2d(input, kernel_size, stride=None, padding=0, dilation=1, ceil_mode=False, return_indices=False)
4.2net.parameters()可以返回一个模型的学习参数
params = list(net.parameters())
print(len(params))
10
params[0].size()
torch.Size([6, 1, 5, 5])
4.3输入随机的32×32的张量
input = torch.randn(1, 1, 32, 32)
out = net(input)
out
tensor([[-0.0905, 0.0649, -0.0700, -0.0624, -0.0603, -0.1023, -0.0306, 0.1210,
0.0160, -0.0459]], grad_fn=<AddmmBackward>)
4.5清零所有参数的梯度缓存,之后进行随机梯度的反向传播
net.zero_grad()
out.backward(torch.randn(1, 10))
5.损失函数
nn.MSELoss损失函数
该损失函数计算输出和目标的均方误差
损失函数接受(output, target)作为输入,通过计算一个值来估计网络的输出和目标值相差多少
output = net(input)
target = torch.randn(10) #使用模拟数据
target = target.view(1, -1) #使目标值与数据值尺寸一致
criterion = nn.MSELoss()
loss = criterion(output, target)
loss
tensor(0.9413, grad_fn=<MseLossBackward>)
#向后跟踪
print(loss.grad_fn)
print(loss.grad_fn.next_functions[0][0])
print(loss.grad_fn.next_functions[0][0].next_functions[0][0])
<MseLossBackward object at 0x00000250521EFAF0>
<AddmmBackward object at 0x000002504CC6F100>
<AccumulateGrad object at 0x0000025052209A30>
反向传播
net.zero_grad() #清零所有参数
print("反向传播前conv1.bias.grad:{}".format(net.conv1.bias.grad))
loss.backward()
print("反向传播后conv1.bias.grad:{}".format(net.conv1.bias.grad))
反向传播前conv1.bias.grad:tensor([0., 0., 0., 0., 0., 0.])
反向传播后conv1.bias.grad:tensor([ 0.0122, -0.0041, -0.0036, -0.0057, -0.0269, -0.0030])
更新权重
weight = weight - learning_rate * gradient
import torch.optim as optim
#创建优化路
optimizer = optim.SGD(net.parameters(), lr=0.01)
#在训练的迭代中
optimizer.zero_grad() #清零梯度缓存
output = net(input)
loss = criterion(output, target)
loss.backward()
optimizer.step() #更新参数
6.数据并行处理
device = torch.device(“cuda:0”)
model.to(device)
mytensor = my_tensor.to(device)
modek = nn.DataParallel(model)
model = nn.DataParallel(model)