pytorch学习笔记案例一

本文为🔗小白入门Pytorch内部限免文章
参考本文所写记录性文章,请在文章开头注明以下内容,复制粘贴即可

PyTorch是一个开源的深度学习框架。它的自动求导功能也使得实现反向传播算法变得简单,是训练深度学习模型的关键组件,本节主要分为如下两个主要内容:

  • 创建张量:学会如何创建空张量、随机张量、全零张量以及使用已有数据创建张量。
  • 张量的操作:学会如何对张量进行操作,包括张量的加减乘除运算、shape变换、转置、索引与切片以及数组、列表与张量之间的互转。
  • 自动求导原理与实现:自动求导是一个关键的功能,它允许我们自动计算梯度,从而进行反向传播和优化。
  • 反向传播:反向传播是深度学习中的关键概念之一,它是训练神经网络模型的基础。

笔记和想法

重点内容

本周教程分为两个部分来进行讲解:

  • 第一部分为张量的创建以及运算操作
  • 第二部分设计自动求导以及反向传播的原理

第一部分

  • 张量的创立:torch.tensor( ) ,使用torch.tensor函数从Python列表或NumPy数组创建张量,也可以使用其他创建函数,torch.zerostorch.onestorch.rand分别创建全0,全1,随机张量。其中()内传入张量的形状。
  • 张量操作:可以对张量执行各种数学运算和操作,如加法、减法、乘法、除法、矩阵乘法等。例如 tensor1+tensor2,tensor1-tensor2,tensor1*tensor2
  • 张量索引和切片:可以使用索引和切片操作来访问张量中的特定元素或子张量。同numpy中切片,[:],前面是行号后面是列号。
  • 张量的GPU加速 在PyTorch中,可以将张量存储在CPU或GPU上。cpu转到GPU torch.to(“cuda“)。
  • 张量转化为numpy和list列表:分别用 array = tensor.numpy(),list=tensor.tolist()来完成。

第二部分

  • 梯度计算:每个张量都有一个属性requires_grad,默认为False。如果我们希望计算某个张量的梯度,需要将requires_grad设置为True,那么就会开始追踪在该变量上的所有操作,而完成计算后,可以调用 .backward() 并自动计算所有的梯度,得到的梯度都保存在属性 .grad 中。
  • 反向传播:使用梯度下降法来最小化损失函数。首先对输入样本进行前向传播计算出预测结果,将预测值与真实值比较,得到损失函数,利用求梯度对损失函数进行优化,时损失函数最小,在此过程中更新各参数的值。

疑难重点

求梯度时,先执行y.sum()再求导的目的是为了计算一个标量值(scalar)的梯度。PyTorch的自动微分机制是基于标量值的,因此我们需要确保我们要计算的梯度是一个标量。具体解释如下:

y是一个张量,它可能包含多个元素,例如[y1, y2, …],每个元素都与x相关。如果我们直接调用y.backward(),PyTorch会尝试计算y中每个元素对应的梯度,这将得到一个与x具有相同形状的梯度张量。这在某些情况下可能是有用的,但通常我们更关心的是一个标量目标函数的梯度。
通过执行y.sum(),我们将y中的所有元素相加,得到一个标量值(单个数字)。然后,我们对这个标量值执行反向传播,计算相对于x的梯度。这确保了我们计算的是整个目标函数相对于x的梯度,而不是每个元素的梯度。

重点代码复现

创建张量

# 导入PyTorch库
import torch 

#创建0维
tensor = torch.tensor(5)
print(tensor.shape)
torch.Size([])
#创建1维
tensor = torch.tensor([1, 2, 3, 4, 5])
print(tensor.shape)
torch.Size([5])

利用zeros和ones和rand

# 创建一个形状为(2, 3)的零张量
zeros_tensor = torch.zeros((2, 3))

print(zeros_tensor)
tensor([[0., 0., 0.],
        [0., 0., 0.]])
# 创建一个形状为(2, 4)的一张量
one_tensor=torch.ones((2,4))
print(one_tensor)
tensor([[1., 1., 1., 1.],
        [1., 1., 1., 1.]])
# 创建一个形状为(3, 3)的随机张量
rand_tensor = torch.rand((3, 3))

print(rand_tensor)
tensor([[0.5825, 0.4410, 0.6772],
        [0.5829, 0.1274, 0.7013],
        [0.8257, 0.9574, 0.7388]])

加减乘除

import torch

tensor1 = torch.tensor([1, 2, 3])
tensor2 = torch.tensor([4, 5, 6])
result = tensor1 + tensor2
print(result) 
result = tensor1 * tensor2
print(result)  
result = tensor2 - tensor1
print(result)
result = tensor2 / tensor1
print(result)
tensor([5, 7, 9])
tensor([ 4, 10, 18])
tensor([3, 3, 3])
tensor([4, 2, 2])

张量索引和切片

import torch

# 创建一个形状为(3, 3)的张量
tensor = torch.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

# 访问第一个元素
print(tensor[0, 0])  # 输出: tensor(1)

# 切片操作
print(tensor[:, 1])  # 输出: tensor([2, 5, 8])
tensor(1)
tensor([2, 5, 8])

张量的GPU与CPU切换

import torch
tensor = torch.tensor([[1, 2], [3, 4]])
tensor = tensor.to('cuda')
tensor
tensor = tensor.to('cpu')
tensor
tensor([[1, 2],
        [3, 4]], device='cuda:0')

张量形状变换

import torch

# 改变张量的形状
a = torch.tensor([[1, 2, 3], [4, 5, 6]])
b = a.reshape(3, 2)  # 改变为3x2的张量

b
tensor([[1, 2],
        [3, 4],
        [5, 6]])
# 改变张量的形状(与reshape()功能相同)
a = torch.tensor([[1, 2, 3], [4, 5, 6]])
b = a.view(3, 2)  # 改变为3x2的张量

b
tensor([[1, 2],
        [3, 4],
        [5, 6]])
# 转置张量
a = torch.tensor([[1, 2, 3], [4, 5, 6]])
b = a.transpose(0, 1)  # 转置为3x2的张量

b
tensor([[1, 4],
        [2, 5],
        [3, 6]])

张量转化为数组

import torch
import numpy as np

# 创建一个PyTorch张量
tensor = torch.tensor([[1, 2, 3],
                       [4, 5, 6],
                       [7, 8, 9]])

# 将张量转换为NumPy数组
array = tensor.numpy()


# 现在,`array`就是一个NumPy数组,你可以使用NumPy的功能来操作它
print(array)
[[1 2 3]
 [4 5 6]
 [7 8 9]]

张量转化为列表

import torch

# 创建一个PyTorch张量
tensor = torch.tensor([[1, 2, 3], 
                       [4, 5, 6]])

# 将张量转换为Python列表
tensor_list = tensor.tolist()

print(tensor_list)
[[1, 2, 3], [4, 5, 6]]

请注意,.tolist()方法只能用于包含标量元素的张量,例如整数或浮点数。如果张量包含其他张量或复杂数据类型,则不能直接使用.tolist()。在这种情况下,你需要先将内部的张量或复杂数据类型转换为Python列表。

自动求导综合代码案例

🚩示例 1:线性回归

考虑一个简单的线性回归模型,我们的目标是找到一条直线,以最小化预测值与真实值之间的平方误差。我们可以使用梯度下降算法来更新直线的参数。

import torch

# 创建训练数据
x_train = torch.tensor([[1.0], [2.0], [3.0]])
y_train = torch.tensor([[2.0], [4.0], [6.0]])

# 定义模型参数
w = torch.tensor([[0.0]], requires_grad=True)
b = torch.tensor([[0.0]], requires_grad=True)

# 定义模型
def linear_regression(x):
    return torch.matmul(x, w) + b

# 定义损失函数
def loss_fn(y_pred, y):
    return torch.mean((y_pred - y)**2)

# 定义优化器
optimizer = torch.optim.SGD([w, b], lr=0.01)

# 训练模型
for epoch in range(100):
    # 前向传播
    y_pred = linear_regression(x_train)
    
    # 计算损失
    loss = loss_fn(y_pred, y_train)
    
    # 反向传播
    loss.backward()
    
    # 更新参数
    optimizer.step()
    
    # 清零梯度
    optimizer.zero_grad()

反向传播代码案例

import torch
import torch.nn as nn
import torch.optim as optim

class LinearRegression(nn.Module):
    def __init__(self):
        super(LinearRegression, self).__init__()
        self.linear = nn.Linear(1, 1)  # 输入维度为1,输出维度为1

    def forward(self, x):
        return self.linear(x)
model     = LinearRegression()
criterion = nn.MSELoss()  # 均方误差损失函数

# 随机梯度下降优化器
optimizer = optim.SGD(model.parameters(), lr=0.01) 
# 生成样本数据
x_train = torch.tensor([[1.0], [2.0], [3.0], [4.0]])
y_train = torch.tensor([[2.0], [4.0], [6.0], [8.0]])

# 训练模型
for epoch in range(100):
    optimizer.zero_grad()  # 梯度清零

    # 前向传播
    y_pred = model(x_train)

    # 计算损失
    loss = criterion(y_pred, y_train)

    # 反向传播
    loss.backward()

    # 参数更新
    optimizer.step()

闯关练习

👉练习1:请创建一个形状为 2x3 的全零张量,然后加上标量2,将结果赋予answer1

import torch
tensor = torch.zeros((2,3));
answer = tensor+2;
answer
tensor([[2., 2., 2.],
        [2., 2., 2.]])

👉练习2:请创建一个形状为 2x3 的全零张量a,一个形状为 2x3 的全1张量b,a与b相乘后,再乘以标量3,将结果赋予answer2


import torch
tensor1 = torch.zeros((2,3))
tensor2 = torch.ones((2,3))
tensor3 = tensor1 * tensor2
tensor3 = tensor3 *3
tensor3



tensor([[0., 0., 0.],
        [0., 0., 0.]])

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值