[课堂笔记][pytorch学习][1]pytorch的tensor是什么?如何使用cuda?和简单的神经网络实现
课程地址:https://www.bilibili.com/video/BV12741177Cu
第一节课课程笔记:
PyTorch与其他框架的对比
什么是PyTorch?
PyTorch是一个基于Python的科学计算库,它有以下特点:
- 类似于NumPy,但是它可以使用GPU
- 可以用它定义深度学习模型,可以灵活地进行深度学习模型的训练和使用
Tensors
Tensor类似与NumPy的ndarray,唯一的区别是Tensor可以在GPU上加速运算。
tensor举例:
1.in-place加法
y.add_(x)
输出:
tensor([[ 1.1866, 0.0035, -0.7225],
[ 0.8220, 0.9750, 0.8406],
[ 1.2857, 0.5896, 0.6168],
[ 0.8559, 0.7026, 2.2498],
[ 0.2741, -0.4248, 0.2826]])
#任何in-place的运算都会以``_``结尾。 举例来说:``x.copy_(y)``, ``x.t_()``, 会改变 ``x``。
2.如果你有一个只有一个元素的tensor,使用.item()
方法可以把里面的value变成Python数值。
x = torch.randn(1) 输出x: tensor([-1.1493]) x.item() 输出x: -1.1493233442306519
3.Torch Tensor和NumPy array会共享内存,所以改变其中一项也会改变另一项。
a = torch.ones(5) 输出a: tensor([1., 1., 1., 1., 1.]) b = a.numpy() 输出b: array([1., 1., 1., 1., 1.], dtype=float32) 改变numpy array里面的值。 b[1] = 2 输出a: tensor([1., 2., 1., 1., 1.])
#所有CPU上的Tensor都支持转成numpy或者从numpy转成Tensor。
#numpy不能在GPU上计算,但是tensor可以。
4.使用.to
方法,Tensor可以被移动到别的device上。例如:移到CUDA
#一般在代码中都会这样写 if torch.cuda.is_available(): device = torch.device("cuda")
Tensor和autograd
PyTorch的一个重要功能就是autograd,也就是说只要定义了forward pass(前向神经网络),计算了loss之后,PyTorch可以自动求导计算模型所有参数的梯度。
一个PyTorch的Tensor表示计算图中的一个节点。如果x
是一个Tensor并且x.requires_grad=True
那么x.grad
是另一个储存着x
当前梯度(相对于一个scalar,常常是loss)的向量。
使用PyTorch中nn这个库来构建一个简单的神经网络。 用PyTorch autograd来构建计算图和计算gradients, 然后PyTorch会帮我们自动计算gradient。
import torch.nn as nn N, D_in, H, D_out = 64, 1000, 100, 10 # 随机创建一些训练数据 x = torch.randn(N, D_in) y = torch.randn(N, D_out) model = torch.nn.Sequential( torch.nn.Linear(D_in, H, bias=False), # w_1 * x + b_1 torch.nn.ReLU(), torch.nn.Linear(H, D_out, bias=False), ) torch.nn.init.normal_(model[0].weight) torch.nn.init.normal_(model[2].weight) # model = model.cuda() loss_fn = nn.MSELoss(reduction='sum') learning_rate = 1e-6 for it in range(500): # Forward pass y_pred = model(x) # model.forward() # compute loss loss = loss_fn(y_pred, y) # computation graph print(it, loss.item()) # Backward pass loss.backward() # update weights of w1 and w2 with torch.no_grad(): for param in model.parameters(): # param (tensor, grad) param -= learning_rate * param.grad model.zero_grad()
optim
不手动更新模型的weights,而是使用optim这个包来帮助我们更新参数。 optim这个package提供了各种不同的模型优化方法,包括SGD+momentum, RMSProp, Adam等等。
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate) optimizer.zero_grad() # Backward pass loss.backward() # update model parameters optimizer.step()
自定义 nn Modules
我们可以定义一个模型,这个模型继承自nn.Module类。如果需要定义一个比Sequential模型更加复杂的模型,就需要定义nn.Module模型。
class TwoLayerNet(torch.nn.Module): def __init__(self, D_in, H, D_out): super(TwoLayerNet, self).__init__() # define the model architecture self.linear1 = torch.nn.Linear(D_in, H, bias=False) self.linear2 = torch.nn.Linear(H, D_out, bias=False) def forward(self, x): y_pred = self.linear2(self.linear1(x).clamp(min=0)) return y_pred