学习PyTorch 的张量(Tensor)

发布于
# 机器学习 # PyTorch

PyTorch 是一个强大的深度学习框架,张量(Tensor)是其核心数据结构。学习 PyTorch 中的张量运算是掌握深度学习的基础。

1. **张量的创建**

张量是 PyTorch 中的多维数组,类似于 NumPy 的 `ndarray`,但支持 GPU 加速。

import torch

# 创建未初始化的张量
x = torch.empty(2, 3)  # 2行3列的空张量

# 创建随机初始化的张量
x = torch.rand(2, 3)  # 2行3列的随机张量(值在0到1之间)

# 创建全零张量
x = torch.zeros(2, 3)  # 2行3列的全零张量

# 创建全一张量
x = torch.ones(2, 3)  # 2行3列的全一张量

# 从 Python 列表创建张量
x = torch.tensor([1.0, 2.0, 3.0])  # 1维张量

# 创建指定范围的张量
x = torch.arange(0, 10, 2)  # 0到10,步长为2


2. **张量的基本属性**

张量有一些重要的属性,如形状、数据类型和设备(CPU 或 GPU)。

x = torch.rand(2, 3)

# 查看张量的形状
print(x.shape)  # 或 x.size()

# 查看张量的数据类型
print(x.dtype)  # 默认是 torch.float32

# 查看张量的设备
print(x.device)  # 默认是 CPU

# 将张量移动到 GPU(如果有 GPU)
if torch.cuda.is_available():
    x = x.to("cuda")


3. **张量的基本运算**

PyTorch 支持多种张量运算,包括逐元素运算、矩阵运算等。


逐元素运算

x = torch.tensor([1.0, 2.0, 3.0])
y = torch.tensor([4.0, 5.0, 6.0])

# 加法
z = x + y  # 或 torch.add(x, y)

# 减法
z = x - y

# 乘法(逐元素)
z = x * y

# 除法(逐元素)
z = x / y

# 指数运算
z = torch.exp(x)  # e^x

矩阵运算

x = torch.tensor([[1.0, 2.0], [3.0, 4.0]])
y = torch.tensor([[5.0, 6.0], [7.0, 8.0]])

# 矩阵乘法
z = torch.matmul(x, y)  # 或 x @ y

# 转置
z = x.T

广播机制

PyTorch 支持广播机制,允许不同形状的张量进行运算。

x = torch.tensor([[1.0, 2.0], [3.0, 4.0]])
y = torch.tensor([1.0, 2.0])

# 广播加法
z = x + y  # y 会被广播为 [[1.0, 2.0], [1.0, 2.0]]

4. **张量的索引和切片**

张量的索引和切片与 NumPy 类似。

x = torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])

# 获取第一行
print(x[0])  # tensor([1.0, 2.0, 3.0])

# 获取第二列
print(x[:, 1])  # tensor([2.0, 5.0])

# 修改某个元素
x[0, 1] = 10.0

5. **张量的形状操作**

PyTorch 提供了多种方法来改变张量的形状。

x = torch.arange(6)  # tensor([0, 1, 2, 3, 4, 5])

# 改变形状
y = x.view(2, 3)  # 2行3列的张量

# 展平张量
z = y.flatten()  # 回到1维张量

# 增加维度
y = x.unsqueeze(0)  # 在第0维增加一个维度

# 减少维度
z = y.squeeze(0)  # 去掉第0维

6. **张量的梯度计算**

PyTorch 支持自动微分,可以通过 `requires_grad=True` 启用梯度计算。

x = torch.tensor([1.0, 2.0, 3.0], requires_grad=True)
y = x * 2  # y = [2.0, 4.0, 6.0]
z = y.sum()  # z = 12.0

# 计算梯度
z.backward()

# 查看 x 的梯度
print(x.grad)  # tensor([2.0, 2.0, 2.0])

7. **常用函数**

以下是一些常用的张量操作函数:

- **求和**:`torch.sum(x)`

- **均值**:`torch.mean(x)`

- **最大值**:`torch.max(x)`

- **最小值**:`torch.min(x)`

- **连接张量**:`torch.cat([x, y], dim=0)`

- **堆叠张量**:`torch.stack([x, y], dim=0)`

8. **GPU 加速**

PyTorch 支持将张量移动到 GPU 上进行加速。

# 检查是否有 GPU
if torch.cuda.is_available():
    device = torch.device("cuda")
    x = torch.tensor([1.0, 2.0, 3.0]).to(device)
    y = torch.tensor([4.0, 5.0, 6.0]).to(device)
    z = x + y
    print(z)


- 参考 PyTorch 官方文档:PyTorch Documentation

https://pytorch.org/docs/stable/tensors.html


以下是一些 PyTorch 张量运算的课后小题目,帮助你巩固所学知识。每个题目都涵盖了不同的知识点,需动手编写代码并运行验证。


### **题目 1:张量创建与基本属性**

1. 创建一个形状为 `(3, 4)` 的随机张量,并打印它的形状、数据类型和设备。

2. 创建一个全零张量,形状为 `(2, 2)`,并将其数据类型设置为 `torch.float64`。

3. 从 Python 列表 `[1, 2, 3, 4, 5]` 创建一个张量,并将其移动到 GPU(如果有 GPU)。


### **题目 2:张量运算**

1. 创建两个形状为 `(2, 3)` 的随机张量 `x` 和 `y`,计算它们的逐元素加法、减法和乘法。

2. 创建一个形状为 `(3, 3)` 的随机张量 `x`,计算它的转置。

3. 创建两个形状为 `(2, 2)` 的随机张量 `x` 和 `y`,计算它们的矩阵乘法。


### **题目 3:广播机制**

1. 创建一个形状为 `(3, 1)` 的张量 `x` 和一个形状为 `(1, 3)` 的张量 `y`,计算它们的逐元素加法。

2. 创建一个形状为 `(2, 3)` 的张量 `x` 和一个标量 `2.0`,计算它们的逐元素乘法。


### **题目 4:索引与切片**

1. 创建一个形状为 `(4, 4)` 的随机张量 `x`,提取它的第 2 行和第 3 列。

2. 创建一个形状为 `(5, 5)` 的随机张量 `x`,将其第 2 到第 4 行的第 1 到第 3 列设置为 `1.0`。


### **题目 5:形状操作**

1. 创建一个形状为 `(6,)` 的张量 `x`,将其重塑为 `(2, 3)` 的形状。

2. 创建一个形状为 `(1, 3, 3)` 的张量 `x`,去掉其第 0 维。

3. 创建两个形状为 `(3,)` 的张量 `x` 和 `y`,将它们沿第 0 维连接。


### **题目 6:梯度计算**

1. 创建一个张量 `x = [2.0, 3.0, 4.0]`,并启用梯度计算。定义 `y = x^2 + 2x + 1`,计算 `y` 对 `x` 的梯度。

2. 创建一个形状为 `(2, 2)` 的随机张量 `x`,并启用梯度计算。定义 `y = sum(x^2)`,计算 `y` 对 `x` 的梯度。


### **题目 7:常用函数**

1. 创建一个形状为 `(3, 3)` 的随机张量 `x`,计算它的总和、均值和最大值。

2. 创建两个形状为 `(2, 2)` 的随机张量 `x` 和 `y`,将它们沿第 0 维堆叠。


### **题目 8:GPU 加速**

1. 检查是否有 GPU 可用,如果有,创建一个形状为 `(1000, 1000)` 的随机张量 `x`,并将其移动到 GPU 上,计算 `x + 1`。


### **题目 9:综合练习**

1. 创建一个形状为 `(5, 5)` 的随机张量 `x`,计算它的转置,并将结果与原始张量相加。

2. 创建一个形状为 `(10,)` 的张量 `x`,将其重塑为 `(2, 5)`,然后计算每列的和。

3. 创建一个形状为 `(3, 3)` 的随机张量 `x`,并启用梯度计算。定义 `y = sum(x * x.T)`,计算 `y` 对 `x` 的梯度。


### **题目 10:挑战题**

1. 实现一个简单的线性回归模型:

  - 创建输入数据 `x = [1.0, 2.0, 3.0, 4.0]` 和目标数据 `y = [2.0, 4.0, 6.0, 8.0]`。

  - 定义模型参数 `w` 和 `b`(初始化为随机值),并启用梯度计算。

  - 定义损失函数为均方误差(MSE),使用梯度下降法更新参数 `w` 和 `b`,训练 100 次并打印最终的 `w` 和 `b`。


### **提示**

- 使用 `torch.optim.SGD` 实现梯度下降。

- 使用 `torch.nn.functional.mse_loss` 计算均方误差。


找到 0 条评论