[课堂笔记][pytorch学习][1]pytorch的tensor是什么?如何使用cuda?和简单的神经网络实现

 课程地址:https://www.bilibili.com/video/BV12741177Cu

第一节课课程笔记:

PyTorch与其他框架的对比

- PyTorch: 动态计算图 Dynamic Computation Graph 
- Tensorflow: 静态计算图 Static Computation Graph

什么是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

 

posted @ 2021-07-08 19:34  Nakkk  阅读(172)  评论(0编辑  收藏  举报