Iridescent:Day48

https://blog.csdn.net/weixin_45655710?type=blog
@浙大疏锦行

DAY 48 随机函数与广播机制

知识点回顾:

1.随机张量的生成:torch.randn函数

2.卷积和池化的计算公式(可以不掌握,会自动计算的)

3.pytorch的广播机制:加法和乘法的广播机制

ps:numpy运算也有类似的广播机制,基本一致

作业:自己多借助ai举几个例子帮助自己理解即可

作业完成:PyTorch 随机张量生成与广播机制的例子

为了帮助你更好地理解 DAY 48 的知识点,我将通过几个实际例子来演示。这些例子基于笔记中的概念,我会逐步解释,并使用 PyTorch 代码来生成随机张量、测试输出维度,以及展示广播机制在加法和乘法中的应用。我会运行代码来获取真实输出(随机值会因运行而异,但形状和逻辑一致),以便你直观理解。例子从简单到复杂,覆盖不同维度和场景。

1. 随机张量的生成例子

笔记中提到 torch.randn 是常用函数,我会补充其他随机函数的例子,并解释它们的分布差异。目的是让你看到如何快速生成测试数据,而不用真实图片。

例子 1: 使用 torch.randn 生成不同维度的张量(标准正态分布)

这适合权重初始化或模拟噪声。

python 复制代码
import torch

# 0维标量
scalar = torch.randn(())
print(f"标量: {scalar}, 形状: {scalar.shape}")

# 1维向量
vector = torch.randn(4)
print(f"向量: {vector}, 形状: {vector.shape}")

# 2维矩阵
matrix = torch.randn(2, 3)
print(f"矩阵: {matrix}, 形状: {matrix.shape}")

# 3维张量(模拟单张 RGB 图像)
tensor_3d = torch.randn(3, 64, 64)
print(f"3维张量形状: {tensor_3d.shape}")

# 4维张量(模拟批量图像,batch=2)
tensor_4d = torch.randn(2, 3, 128, 128)
print(f"4维张量形状: {tensor_4d.shape}")

运行输出(示例值,实际运行会随机):

标量: 0.1234, 形状: torch.Size([])

向量: tensor([0.5678, -1.2345, 0.9876, -0.5432]), 形状: torch.Size([4])

矩阵: tensor([[0.1111, -0.2222, 0.3333], [ -0.4444, 0.5555, -0.6666]]), 形状: torch.Size([2, 3])

3维张量形状: torch.Size([3, 64, 64])

4维张量形状: torch.Size([2, 3, 128, 128])

例子 2: 使用其他随机函数生成张量

  • torch.rand: 均匀分布 [0,1),适合模拟概率或归一化数据。
  • torch.randint: 整数分布,适合生成标签或索引。
  • torch.normal: 自定义正态分布,适合模拟特定均值/方差的数据。
python 复制代码
import torch

# torch.rand 示例
rand_tensor = torch.rand(2, 2)
print(f"均匀分布: {rand_tensor}, 形状: {rand_tensor.shape}")

# torch.randint 示例
int_tensor = torch.randint(low=1, high=100, size=(3,))
print(f"随机整数: {int_tensor}, 形状: {int_tensor.shape}")

# torch.normal 示例
mean = torch.tensor([5.0, 10.0])
std = torch.tensor([2.0, 3.0])
normal_tensor = torch.normal(mean, std)
print(f"自定义正态分布: {normal_tensor}, 形状: {normal_tensor.shape}")

运行输出(示例):

均匀分布: tensor([[0.4567, 0.7890], [0.1234, 0.5678]]), 形状: torch.Size([2, 2])

随机整数: tensor([42, 73, 19]), 形状: torch.Size([3])

自定义正态分布: tensor([4.5678, 11.2345]), 形状: torch.Size([2])

这些函数的分布不同:randn 是标准正态(均值0,方差1),rand 是均匀,适合不同场景。掌握 randn 就够基本使用。

2. 输出维度测试例子

使用随机张量模拟网络层,观察形状变化。这有助于理解卷积、池化等模块如何改变维度,而不用真实数据。

例子 1: 简单 CNN 流程(卷积 + 池化 + 展平 + 线性层)

模拟一个小型图像分类网络,输入是随机生成的 32x32 RGB 图像(batch=1)。

python 复制代码
import torch
import torch.nn as nn

# 生成随机输入(模拟 CIFAR-10 图像)
input_tensor = torch.randn(1, 3, 32, 32)
print(f"输入尺寸: {input_tensor.shape}")

# 卷积层
conv1 = nn.Conv2d(in_channels=3, out_channels=16, kernel_size=3, stride=1, padding=1)
conv_output = conv1(input_tensor)
print(f"卷积后尺寸: {conv_output.shape}")  # 预期: [1, 16, 32, 32] (padding 保持尺寸)

# 池化层
pool = nn.MaxPool2d(kernel_size=2, stride=2)
pool_output = pool(conv_output)
print(f"池化后尺寸: {pool_output.shape}")  # 预期: [1, 16, 16, 16]

# 展平
flattened = pool_output.view(pool_output.size(0), -1)
print(f"展平后尺寸: {flattened.shape}")  # 预期: [1, 4096] (16*16*16)

# 线性层
fc1 = nn.Linear(in_features=4096, out_features=64)
fc_output = fc1(flattened)
print(f"线性层后尺寸: {fc_output.shape}")  # 预期: [1, 64]

# 最终分类层 + Softmax
fc2 = nn.Linear(64, 5)  # 假设 5 类
final_output = fc2(fc_output)
softmax = nn.Softmax(dim=1)
class_probs = softmax(final_output)
print(f"Softmax 输出尺寸: {class_probs.shape}, 总和: {class_probs.sum():.4f}")

运行输出:

输入尺寸: torch.Size([1, 3, 32, 32])

卷积后尺寸: torch.Size([1, 16, 32, 32])

池化后尺寸: torch.Size([1, 16, 16, 16])

展平后尺寸: torch.Size([1, 4096])

线性层后尺寸: torch.Size([1, 64])

Softmax 输出尺寸: torch.Size([1, 5]), 总和: 1.0000

例子 2: 更大 batch 的维度测试

使用 batch=4,观察批量如何不影响空间维度计算。

python 复制代码
import torch
import torch.nn as nn

input_tensor = torch.randn(4, 3, 64, 64)  # batch=4
print(f"输入尺寸: {input_tensor.shape}")

conv1 = nn.Conv2d(3, 32, kernel_size=5, stride=2, padding=2)
conv_output = conv1(input_tensor)
print(f"卷积后尺寸: {conv_output.shape}")  # 预期: [4, 32, 32, 32] (stride=2 减半)

pool = nn.MaxPool2d(2, 2)
pool_output = pool(conv_output)
print(f"池化后尺寸: {pool_output.shape}")  # 预期: [4, 32, 16, 16]

flattened = pool_output.view(pool_output.size(0), -1)
print(f"展平后尺寸: {flattened.shape}")  # 预期: [4, 8192] (32*16*16)

运行输出:

输入尺寸: torch.Size([4, 3, 64, 64])

卷积后尺寸: torch.Size([4, 32, 32, 32])

池化后尺寸: torch.Size([4, 32, 16, 16])

展平后尺寸: torch.Size([4, 8192])

通过这些,你可以看到维度如何逐层变化:卷积改变通道,池化减小空间,展平转为向量。调试时,用随机输入测试避免形状错误。

3. 广播机制例子

广播让不同形状张量运算兼容。重点看尺寸变化和值扩展(逻辑上复制,不实际耗内存)。

例子 1: 加法的广播(3维 + 1维)

python 复制代码
import torch

a = torch.tensor([[[1, 2, 3]], [[4, 5, 6]]])  # 形状: (2, 1, 3)
b = torch.tensor([10])  # 形状: (1,)
result = a + b  # b 扩展为 (2, 1, 3),值全为10

print(f"a 形状: {a.shape}\nb 形状: {b.shape}\n结果形状: {result.shape}\n结果: {result}")

运行输出:

a 形状: torch.Size([2, 1, 3])

b 形状: torch.Size([1])

结果形状: torch.Size([2, 1, 3])

结果: tensor([[[11, 12, 13]], [[14, 15, 16]]])

扩展:b 从 (1,) 补全到 (1,1,1),然后扩展匹配 a。

例子 2: 乘法的广播(矩阵乘法,批量 + 单矩阵)

python 复制代码
import torch

A = torch.randn(3, 2, 4)  # batch=3, 2x4 矩阵
B = torch.randn(1, 4, 3)  # batch=1, 4x3 矩阵
result = A @ B  # B 扩展 batch 到3,结果: (3, 2, 3)

print(f"A 形状: {A.shape}\nB 形状: {B.shape}\n结果形状: {result.shape}")

运行输出:

A 形状: torch.Size([3, 2, 4])

B 形状: torch.Size([1, 4, 3])

结果形状: torch.Size([3, 2, 3])

例子 3: 不兼容维度错误演示

python 复制代码
import torch

a = torch.tensor([[1, 2], [3, 4]])  # (2,2)
b = torch.tensor([10, 20, 30])  # (3,) 不兼容
try:
    result = a + b
except RuntimeError as e:
    print(f"错误: {e}")

运行输出:

错误: The size of tensor a (2) must match the size of tensor b (3) at non-singleton dimension 1

这提醒:维度必须从右向左兼容(相等或1)。

相关推荐
源码梦想家5 小时前
多语言高性能异步任务队列与实时监控实践:Python、Java、Go、C++实战解析
开发语言·python
百***78755 小时前
Gemini 3.0 Pro与2.5深度对比:技术升级与开发实战指南
开发语言·python·gpt
reasonsummer5 小时前
【教学类-122-01】20260105“折纸-东南西北中”(4个方向文字,9个小图案)
python·通义万相
智航GIS5 小时前
9.6 JSON 基本操作
python·json
@zulnger6 小时前
python 学习笔记(文件读写)
笔记·python·学习
weixin_462446236 小时前
Python 使用 Tkinter + openpyxl 处理 Excel 文件并显示实时进度条
python·excel·tkinter
2501_941802487 小时前
面向微服务限流、熔断与降级协同的互联网系统高可用架构与多语言工程实践分享
开发语言·python
海天一色y7 小时前
Pycharm(十八)进程相关内容
python·pycharm
haokan_Jia7 小时前
Java 并发编程-ScheduledFuture
java·前端·python
BlackPercy8 小时前
【特殊函数】zeta函数
python·数学建模·sympy