diff --git a/Class/ClassTest/.idea/ClassTest.iml b/Class/ClassTest/.idea/ClassTest.iml index d8b3f6c..b910500 100644 --- a/Class/ClassTest/.idea/ClassTest.iml +++ b/Class/ClassTest/.idea/ClassTest.iml @@ -2,7 +2,7 @@ - + \ No newline at end of file diff --git a/Class/ClassTest/.idea/misc.xml b/Class/ClassTest/.idea/misc.xml index 1d3ce46..5c8f845 100644 --- a/Class/ClassTest/.idea/misc.xml +++ b/Class/ClassTest/.idea/misc.xml @@ -3,5 +3,5 @@ - + \ No newline at end of file diff --git a/Class/ClassTest/main.py b/Class/ClassTest/class.py similarity index 100% rename from Class/ClassTest/main.py rename to Class/ClassTest/class.py diff --git a/Class/ClassTest/mytorch.py b/Class/ClassTest/mytorch.py new file mode 100644 index 0000000..5ce2086 --- /dev/null +++ b/Class/ClassTest/mytorch.py @@ -0,0 +1,61 @@ +import torch +import torch.nn as nn +import matplotlib.pyplot as plt + +# 定义输入层大小、隐藏层大小、输出层大小和批量大小 +n_in, n_h, n_out, batch_size = 10, 5, 1, 10 + +# 创建虚拟输入数据和目标数据 +x = torch.randn(batch_size, n_in) # 随机生成输入数据 +y = torch.tensor([[1.0], [0.0], [0.0], + [1.0], [1.0], [1.0], [0.0], [0.0], [1.0], [1.0]]) # 目标输出数据 + +# 创建顺序模型,包含线性层、ReLU激活函数和Sigmoid激活函数 +model = nn.Sequential( + nn.Linear(n_in, n_h), # 输入层到隐藏层的线性变换 + nn.ReLU(), # 隐藏层的ReLU激活函数 + nn.Linear(n_h, n_out), # 隐藏层到输出层的线性变换 + nn.Sigmoid() # 输出层的Sigmoid激活函数 +) + +# 定义均方误差损失函数和随机梯度下降优化器 +criterion = torch.nn.MSELoss() +optimizer = torch.optim.SGD(model.parameters(), lr=0.01) # 学习率为0.01 + +# 用于存储每轮的损失值 +losses = [] + +# 执行梯度下降算法进行模型训练 +for epoch in range(50): # 迭代50次 + y_pred = model(x) # 前向传播,计算预测值 + loss = criterion(y_pred, y) # 计算损失 + losses.append(loss.item()) # 记录损失值 + print(f'Epoch [{epoch+1}/50], Loss: {loss.item():.4f}') # 打印损失值 + + optimizer.zero_grad() # 清零梯度 + loss.backward() # 反向传播,计算梯度 + optimizer.step() # 更新模型参数 + +# 可视化损失变化曲线 +plt.figure(figsize=(8, 5)) +plt.plot(range(1, 51), losses, label='Loss') +plt.xlabel('Epoch') +plt.ylabel('Loss') +plt.title('Training Loss Over Epochs') +plt.legend() +plt.grid() +plt.show() + +# 可视化预测结果与实际目标值对比 +y_pred_final = model(x).detach().numpy() # 最终预测值 +y_actual = y.numpy() # 实际值 + +plt.figure(figsize=(8, 5)) +plt.plot(range(1, batch_size + 1), y_actual, 'o-', label='Actual', color='blue') +plt.plot(range(1, batch_size + 1), y_pred_final, 'x--', label='Predicted', color='red') +plt.xlabel('Sample Index') +plt.ylabel('Value') +plt.title('Actual vs Predicted Values') +plt.legend() +plt.grid() +plt.show() \ No newline at end of file diff --git a/Pytorch/autograd/readme.md b/Pytorch/autograd/readme.md new file mode 100644 index 0000000..e69de29 diff --git a/Pytorch/nn/nn.Module.md b/Pytorch/nn/nn.Module.md new file mode 100644 index 0000000..20736f5 --- /dev/null +++ b/Pytorch/nn/nn.Module.md @@ -0,0 +1,464 @@ +`torch.nn.Module` 是 PyTorch 中构建神经网络的核心基类,所有的神经网络模型都继承自它。它提供了许多方法来管理模块、参数、子模块和前向传播等功能。以下基于 PyTorch 官方文档(https://pytorch.org/docs/stable/generated/torch.nn.Module.html)对 `torch.nn.Module` 的所有方法进行详细讲解,力求清晰、简洁且实用。 + +--- + +### 1. `__init__` 方法 +- **描述**: 初始化方法,用于定义模块的结构(如层、子模块等)。 +- **用法**: 在自定义模块时,重写 `__init__` 来定义子模块或参数。 +- **示例**: + ```python + import torch.nn as nn + class MyModel(nn.Module): + def __init__(self): + super(MyModel, self).__init__() + self.fc1 = nn.Linear(10, 5) + ``` +- **说明**: 调用 `super().__init__()` 确保基类的初始化,子模块需注册到模块中(通过赋值给 `self`)。 + +--- + +### 2. `forward(*args, **kwargs)` +- **描述**: 定义模块的前向传播逻辑,子类必须实现此方法。 +- **用法**: 输入数据通过此方法计算输出。 +- **示例**: + ```python + def forward(self, x): + x = self.fc1(x) + return x + ``` +- **说明**: 这是核心方法,所有输入数据的计算流程在此定义。调用模型实例(如 `model(x)`)时会自动调用 `forward`。 + +--- + +### 3. `__call__` 方法 +- **描述**: 使模块实例可调用,内部调用 `forward` 方法并添加钩子(hook)功能。 +- **用法**: 不需要显式重写,用户通过 `model(input)` 间接调用。 +- **说明**: 通常不需要直接操作,但了解它是 `model(input)` 的实现基础。 + +--- + +### 4. `add_module(name: str, module: Module) -> None` +- **描述**: 向模块添加一个子模块,并以指定名称注册。 +- **用法**: 动态添加子模块。 +- **示例**: + ```python + model = nn.Module() + model.add_module("fc1", nn.Linear(10, 5)) + ``` +- **说明**: 等价于 `self.name = module`,但更灵活,适合动态构建模型。 + +--- + +### 5. `apply(fn: Callable[['Module'], None]) -> T` +- **描述**: 递归地将函数 `fn` 应用到模块及其所有子模块。 +- **用法**: 用于初始化参数或修改模块属性。 +- **示例**: + ```python + def init_weights(m): + if isinstance(m, nn.Linear): + nn.init.xavier_uniform_(m.weight) + model.apply(init_weights) + ``` +- **说明**: 常用于自定义权重初始化。 + +--- + +### 6. `buffers(recurse: bool = True) -> Iterator[Tensor]` +- **描述**: 返回模块中所有缓冲区(如 `running_mean` 或 `running_var`)的迭代器。 +- **用法**: 获取模块的非可训练参数(如 BatchNorm 的统计数据)。 +- **示例**: + ```python + for buf in model.buffers(): + print(buf) + ``` +- **说明**: 如果 `recurse=True`,包括子模块的缓冲区。 + +--- + +### 7. `children() -> Iterator[Module]` +- **描述**: 返回直接子模块的迭代器。 +- **用法**: 遍历模型的直接子模块。 +- **示例**: + ```python + for child in model.children(): + print(child) + ``` +- **说明**: 仅返回直接子模块,不递归到更深层。 + +--- + +### 8. `cpu() -> T` +- **描述**: 将模块的所有参数和缓冲区移动到 CPU。 +- **用法**: 用于设备切换。 +- **示例**: + ```python + model.cpu() + ``` +- **说明**: 确保模型和数据在同一设备上运行。 + +--- + +### 9. `cuda(device: Optional[Union[int, torch.device]] = None) -> T` +- **描述**: 将模块的所有参数和缓冲区移动到指定的 GPU 设备。 +- **用法**: 指定 GPU 设备(如 `cuda:0`)。 +- **示例**: + ```python + model.cuda(0) # 移动到 GPU 0 + ``` +- **说明**: 如果不指定 `device`,使用当前默认 GPU。 + +--- + +### 10. `double() -> T` +- **描述**: 将模块的参数和缓冲区转换为 `torch.float64`(双精度浮点)。 +- **用法**: 提高数值精度。 +- **示例**: + ```python + model.double() + ``` +- **说明**: 通常在需要高精度计算时使用,但会增加内存占用。 + +--- + +### 11. `eval() -> T` +- **描述**: 将模块设置为评估模式。 +- **用法**: 关闭训练特有的行为(如 Dropout 和 BatchNorm 的更新)。 +- **示例**: + ```python + model.eval() + ``` +- **说明**: 与 `train(False)` 等效,用于推理阶段。 + +--- + +### 12. `float() -> T` +- **描述**: 将模块的参数和缓冲区转换为 `torch.float32`(单精度浮点)。 +- **用法**: 默认浮点类型,适合大多数深度学习任务。 +- **示例**: + ```python + model.float() + ``` +- **说明**: 比 `double()` 更节省内存。 + +--- + +### 13. `get_buffer(target: str) -> Tensor` +- **描述**: 返回指定名称的缓冲区。 +- **用法**: 访问特定缓冲区(如 BatchNorm 的 `running_mean`)。 +- **示例**: + ```python + running_mean = model.get_buffer("bn.running_mean") + ``` +- **说明**: 如果缓冲区不存在,会抛出 `KeyError`。 + +--- + +### 14. `get_parameter(target: str) -> Parameter` +- **描述**: 返回指定名称的参数。 +- **用法**: 访问特定参数(如 `weight` 或 `bias`)。 +- **示例**: + ```python + weight = model.get_parameter("fc1.weight") + ``` +- **说明**: 参数必须是注册的参数,否则抛出 `KeyError`。 + +--- + +### 15. `get_submodule(target: str) -> Module` +- **描述**: 返回指定路径的子模块。 +- **用法**: 访问嵌套子模块。 +- **示例**: + ```python + submodule = model.get_submodule("block1.conv1") + ``` +- **说明**: 使用点号(如 `block1.conv1`)访问嵌套结构。 + +--- + +### 16. `half() -> T` +- **描述**: 将模块的参数和缓冲区转换为 `torch.float16`(半精度浮点)。 +- **用法**: 用于加速计算和节省 GPU 内存。 +- **示例**: + ```python + model.half() + ``` +- **说明**: 需确保硬件支持半精度运算。 + +--- + +### 17. `load_state_dict(state_dict: Mapping[str, Any], strict: bool = True, assign: bool = False) -> _IncompatibleKeys` +- **描述**: 从 `state_dict` 加载参数和缓冲区。 +- **用法**: 用于加载预训练模型或检查点。 +- **示例**: + ```python + model.load_state_dict(torch.load("model.pth")) + ``` +- **说明**: + - `strict=True`:要求 `state_dict` 的键完全匹配。 + - `assign=True`:直接赋值而非复制(实验性功能)。 + - 返回 `_IncompatibleKeys`,指示缺失或多余的键。 + +--- + +### 18. `modules() -> Iterator[Module]` +- **描述**: 返回模块及其所有子模块(递归)的迭代器。 +- **用法**: 遍历整个模块树。 +- **示例**: + ```python + for module in model.modules(): + print(module) + ``` +- **说明**: 比 `children()` 更深入,包含所有层级子模块。 + +--- + +### 19. `named_buffers(recurse: bool = True, prefix: str = '', remove_duplicate: bool = True) -> Iterator[Tuple[str, Tensor]]` +- **描述**: 返回模块中所有缓冲区的名称和值的迭代器。 +- **用法**: 获取缓冲区的名称和值。 +- **示例**: + ```python + for name, buf in model.named_buffers(): + print(name, buf) + ``` +- **说明**: 如果 `recurse=True`,包括子模块的缓冲区。 + +--- + +### 20. `named_children() -> Iterator[Tuple[str, Module]]` +- **描述**: 返回直接子模块的名称和模块的迭代器。 +- **用法**: 遍历直接子模块及其名称。 +- **示例**: + ```python + for name, child in model.named_children(): + print(name, child) + ``` +- **说明**: 仅返回直接子模块,不递归。 + +--- + +### 21. `named_modules(memo: Optional[Set[Module]] = None, prefix: str = '', remove_duplicate: bool = True) -> Iterator[Tuple[str, Module]]` +- **描述**: 返回模块及其所有子模块(递归)的名称和模块的迭代器。 +- **用法**: 遍历整个模块树及其名称。 +- **示例**: + ```python + for name, module in model.named_modules(): + print(name, module) + ``` +- **说明**: 比 `named_children()` 更深入,包含所有层级。 + +--- + +### 22. `named_parameters(recurse: bool = True, prefix: str = '', remove_duplicate: bool = True) -> Iterator[Tuple[str, Parameter]]` +- **描述**: 返回模块中所有参数的名称和值的迭代器。 +- **用法**: 访问模型的参数(如权重和偏置)。 +- **示例**: + ```python + for name, param in model.named_parameters(): + print(name, param.shape) + ``` +- **说明**: 如果 `recurse=True`,包括子模块的参数。 + +--- + +### 23. `parameters(recurse: bool = True) -> Iterator[Parameter]` +- **描述**: 返回模块中所有参数的迭代器。 +- **用法**: 用于优化器配置。 +- **示例**: + ```python + optimizer = torch.optim.SGD(model.parameters(), lr=0.01) + ``` +- **说明**: 如果 `recurse=True`,包括子模块的参数。 + +--- + +### 24. `register_buffer(name: str, tensor: Optional[Tensor], persistent: bool = True) -> None` +- **描述**: 注册一个缓冲区(如非可训练的张量)。 +- **用法**: 用于存储不需要梯度的张量(如 BatchNorm 的 `running_mean`)。 +- **示例**: + ```python + self.register_buffer("running_mean", torch.zeros(10)) + ``` +- **说明**: `persistent=True` 表示缓冲区会保存到 `state_dict`。 + +--- + +### 25. `register_forward_hook(hook: Callable[..., None], *, prepend: bool = False, with_kwargs: bool = False) -> RemovableHandle` +- **描述**: 注册一个前向传播钩子函数,在模块前向传播时调用。 +- **用法**: 用于监控或修改前向传播的输入/输出。 +- **示例**: + ```python + def hook(module, input, output): + print(output) + handle = model.register_forward_hook(hook) + ``` +- **说明**: 返回 `RemovableHandle`,可通过 `handle.remove()` 移除钩子。 + +--- + +### 26. `register_forward_pre_hook(hook: Callable[..., None], *, prepend: bool = False, with_kwargs: bool = False) -> RemovableHandle` +- **描述**: 注册一个前向传播前的钩子函数,在 `forward` 调用前触发。 +- **用法**: 用于修改输入或调试。 +- **示例**: + ```python + def pre_hook(module, input): + print(input) + handle = model.register_forward_pre_hook(pre_hook) + ``` +- **说明**: 类似 `register_forward_hook`,但在 `forward` 之前运行。 + +--- + +### 27. `register_full_backward_hook(hook: Callable[..., None], prepend: bool = False) -> RemovableHandle` +- **描述**: 注册一个反向传播钩子函数,在梯度计算时调用。 +- **用法**: 用于监控或修改梯度。 +- **示例**: + ```python + def backward_hook(module, grad_input, grad_output): + print(grad_output) + handle = model.register_full_backward_hook(backward_hook) + ``` +- **说明**: 在 PyTorch 2.0+ 中推荐使用,替代旧的 `register_backward_hook`。 + +--- + +### 28. `register_parameter(name: str, param: Optional[Parameter]) -> None` +- **描述**: 注册一个参数到模块。 +- **用法**: 动态添加可训练参数。 +- **示例**: + ```python + self.register_parameter("weight", nn.Parameter(torch.randn(10, 5))) + ``` +- **说明**: 参数会自动加入 `parameters()` 和 `state_dict`。 + +--- + +### 29. `requires_grad_(requires_grad: bool = True) -> T` +- **描述**: 设置模块所有参数的 `requires_grad` 属性。 +- **用法**: 冻结或解冻参数。 +- **示例**: + ```python + model.requires_grad_(False) # 冻结参数 + ``` +- **说明**: 常用于冻结预训练模型的部分层。 + +--- + +### 30. `share_memory() -> T` +- **描述**: 将模块的参数和缓冲区移动到共享内存。 +- **用法**: 用于多进程数据共享。 +- **示例**: + ```python + model.share_memory() + ``` +- **说明**: 主要用于 `torch.multiprocessing` 场景。 + +--- + +### 31. `state_dict(*args, destination: Optional[Dict[str, Tensor]] = None, prefix: str = '', keep_vars: bool = False) -> Dict[str, Tensor]` +- **描述**: 返回模块的参数和缓冲区的状态字典。 +- **用法**: 保存模型状态。 +- **示例**: + ```python + torch.save(model.state_dict(), "model.pth") + ``` +- **说明**: `keep_vars=True` 时保留 `Tensor` 的 `Variable` 特性(较少使用)。 + +--- + +### 32. `to(*args, **kwargs) -> T` +- **描述**: 将模块的参数和缓冲区移动到指定设备或数据类型。 +- **用法**: 灵活的设备/类型转换。 +- **示例**: + ```python + model.to(device="cuda", dtype=torch.float16) + ``` +- **说明**: 支持多种参数形式(如 `to(device)`, `to(dtype)`)。 + +--- + +### 33. `to_empty(*, device: Union[str, torch.device], recurse: bool = True) -> T` +- **描述**: 将模块的参数和缓冲区移动到指定设备,但不初始化内容。 +- **用法**: 用于初始化空模型。 +- **示例**: + ```python + model.to_empty(device="cuda") + ``` +- **说明**: 较少使用,适合特殊场景。 + +--- + +### 34. `train(mode: bool = True) -> T` +- **描述**: 设置模块的训练模式。 +- **用法**: 启用/禁用训练特有的行为(如 Dropout、BatchNorm)。 +- **示例**: + ```python + model.train() # 训练模式 + model.train(False) # 等同于 eval() + ``` +- **说明**: 与 `eval()` 相对,用于切换训练/评估模式。 + +--- + +### 35. `type(dst_type: Union[str, torch.dtype]) -> T` +- **描述**: 将模块的参数和缓冲区转换为指定数据类型。 +- **用法**: 类似 `float()`, `double()` 等,但更通用。 +- **示例**: + ```python + model.type(torch.float16) + ``` +- **说明**: 支持字符串(如 `"torch.float32"`)或 `torch.dtype`。 + +--- + +### 36. `xpu(device: Optional[Union[int, torch.device]] = None) -> T` +- **描述**: 将模块移动到 XPU 设备(Intel GPU)。 +- **用法**: 用于支持 XPU 的设备。 +- **示例**: + ```python + model.xpu(0) + ``` +- **说明**: 仅在支持 XPU 的环境中有效。 + +--- + +### 37. `zero_grad(set_to_none: bool = False) -> None` +- **描述**: 将模块所有参数的梯度清零。 +- **用法**: 在优化步骤前调用。 +- **示例**: + ```python + model.zero_grad() + ``` +- **说明**: 如果 `set_to_none=True`,梯度设为 `None` 而非 0(更节省内存)。 + +--- + +### 注意事项 +- **模块管理**: 使用 `children()`, `modules()`, `named_parameters()` 等方法可以方便地管理复杂模型的结构和参数。 +- **设备与类型**: 确保模型和输入数据在同一设备和数据类型(`to()`, `cuda()`, `float()` 等)。 +- **钩子函数**: 钩子(如 `register_forward_hook`)是调试和动态修改模型的强大工具。 +- **状态保存**: `state_dict()` 和 `load_state_dict()` 是保存和加载模型的关键方法。 + +### 实践建议 +你可以尝试以下代码来探索 `torch.nn.Module` 的功能: +```python +import torch +import torch.nn as nn + +class MyModel(nn.Module): + def __init__(self): + super().__init__() + self.fc1 = nn.Linear(10, 5) + self.register_buffer("running_mean", torch.zeros(5)) + + def forward(self, x): + return self.fc1(x) + +model = MyModel() +print(list(model.named_parameters())) # 查看参数 +print(list(model.named_buffers())) # 查看缓冲区 +model.to("cuda") # 移动到 GPU +model.eval() # 设置评估模式 +torch.save(model.state_dict(), "model.pth") # 保存模型 +``` + +如果你想深入某个方法(如钩子函数或 `state_dict`)或需要具体代码示例,请告诉我,我可以进一步展开! \ No newline at end of file diff --git a/Pytorch/nn/nn.Sequential.md b/Pytorch/nn/nn.Sequential.md new file mode 100644 index 0000000..5bca582 --- /dev/null +++ b/Pytorch/nn/nn.Sequential.md @@ -0,0 +1,140 @@ +### torch.nn.Sequential 类的概述 + +根据 PyTorch 官网(https://pytorch.org/docs/stable/generated/torch.nn.Sequential.html)的最新文档,`torch.nn.Sequential` 是一个顺序容器(Sequential container),它允许你将多个神经网络模块(`nn.Module`)按顺序堆叠起来,形成一个简单的前向传播链。模块会按照构造函数中传入的顺序依次执行前向传播:输入数据传递给第一个模块,其输出作为下一个模块的输入,以此类推,最后返回最后一个模块的输出。 + +这个类继承自 `nn.Module`,因此它继承了 `nn.Module` 的所有通用方法和属性(如 `forward()`、`parameters()`、`train()` 等)。但官网针对 `Sequential` 特有的方法和属性进行了详细描述。下面我将逐一讲解所有特有的方法和属性,包括名称、描述、参数、返回值以及示例(基于官网内容)。注意,`Sequential` 的核心是其 `_modules` 属性(一个有序字典,用于存储子模块),其他方法大多围绕它展开。 + +#### 1. 构造函数 `__init__` +- **描述**:初始化 `Sequential` 容器。你可以直接传入多个 `nn.Module` 对象,或者传入一个 `OrderedDict`(键为字符串,值为模块)。这定义了模块的执行顺序。 +- **参数**: + - `*args`:可变数量的 `nn.Module` 对象(例如,`nn.Linear(10, 20), nn.ReLU()`)。 + - `arg`(可选):一个 `collections.OrderedDict`,其中键是模块的名称(字符串),值是 `nn.Module` 对象。 +- **返回值**:无(返回 `Sequential` 实例本身)。 +- **注意**: + - 与 `nn.ModuleList` 的区别:`ModuleList` 只是一个模块列表,不自动连接层;`Sequential` 会自动将输出连接到下一个输入,形成级联。 + - 支持动态添加模块,但初始化时定义的顺序固定。 +- **示例**: + ```python + import torch.nn as nn + from collections import OrderedDict + + # 直接传入模块 + model = nn.Sequential( + nn.Conv2d(1, 20, 5), + nn.ReLU(), + nn.Conv2d(20, 64, 5), + nn.ReLU() + ) + + # 使用 OrderedDict(便于命名模块) + model = nn.Sequential( + OrderedDict([ + ("conv1", nn.Conv2d(1, 20, 5)), + ("relu1", nn.ReLU()), + ("conv2", nn.Conv2d(20, 64, 5)), + ("relu2", nn.ReLU()), + ]) + ) + ``` + 当你打印 `model` 时,它会显示所有子模块的结构。 + +#### 2. 属性:`_modules` +- **描述**:这是一个私有属性(但在文档中被提及),是一个 `collections.OrderedDict`,存储所有子模块。键是模块的名称(字符串或整数索引),值是 `nn.Module` 对象。这是 `Sequential` 内部维护模块顺序的核心数据结构。 +- **参数**:无(它是只读的,但可以通过方法如 `append` 等间接修改)。 +- **返回值**:`OrderedDict` 对象。 +- **注意**: + - 你不应该直接修改它(例如,不要用 `model._modules['new'] = some_module`),而应使用提供的公共方法(如 `append`、`insert`)来添加或修改模块,以确保正确性。 + - 在前向传播中,`_forward_impl` 方法会遍历这个字典,按顺序调用每个模块的 `forward`。 +- **示例**: + ```python + model = nn.Sequential(nn.Linear(1, 2)) + print(model._modules) # 输出: OrderedDict([('0', Linear(...))]) + ``` + 这有助于调试,但实际使用中很少直接访问。 + +#### 3. 方法:`append(module)` +- **描述**:将一个给定的模块追加到 `Sequential` 容器的末尾。这会动态扩展模型,而无需重新初始化。 +- **参数**: + - `module`:要追加的 `nn.Module` 对象(必需)。 +- **返回值**:`Self`,即 `Sequential` 实例本身(支持链式调用)。 +- **注意**: + - 追加后,模块会自动获得一个新的索引名称(如从 '0' 开始递增)。 + - 这是一个便捷方法,适合在训练过程中动态添加层。 + - 源代码位置:`torch/nn/modules/container.py` 中的 Sequential 类。 +- **示例**: + ```python + import torch.nn as nn + + n = nn.Sequential(nn.Linear(1, 2), nn.Linear(2, 3)) + n.append(nn.Linear(3, 4)) + print(n) + # 输出: + # Sequential( + # (0): Linear(in_features=1, out_features=2, bias=True) + # (1): Linear(in_features=2, out_features=3, bias=True) + # (2): Linear(in_features=3, out_features=4, bias=True) + # ) + ``` + +#### 4. 方法:`extend(sequential)` +- **描述**:将另一个 `Sequential` 容器中的所有层扩展(追加)到当前容器的末尾。这相当于合并两个顺序模型。 +- **参数**: + - `sequential`:另一个 `Sequential` 实例,其中的层将被追加(必需)。 +- **返回值**:`Self`,即 `Sequential` 实例本身。 +- **注意**: + - 也可以使用 `+` 操作符实现类似效果,例如 `n + other`,它会返回一个新的 `Sequential` 而非修改原对象。 + - 如果 `other` 不是 `Sequential`,可能会引发错误;确保类型匹配。 + - 源代码位置:同上。 +- **示例**: + ```python + import torch.nn as nn + + n = nn.Sequential(nn.Linear(1, 2), nn.Linear(2, 3)) + other = nn.Sequential(nn.Linear(3, 4), nn.Linear(4, 5)) + n.extend(other) # 或者 n = n + other + print(n) + # 输出: + # Sequential( + # (0): Linear(in_features=1, out_features=2, bias=True) + # (1): Linear(in_features=2, out_features=3, bias=True) + # (2): Linear(in_features=3, out_features=4, bias=True) + # (3): Linear(in_features=4, out_features=5, bias=True) + # ) + ``` + +#### 5. 方法:`insert(index, module)` +- **描述**:在指定的索引位置插入一个模块到 `Sequential` 容器中。现有模块会根据插入位置向后移位。 +- **参数**: + - `index`:整数,指定插入位置(从 0 开始;如果超出范围,会追加到末尾)。 + - `module`:要插入的 `nn.Module` 对象(必需)。 +- **返回值**:`Self`,即 `Sequential` 实例本身。 +- **注意**: + - 如果 `index` 等于当前模块数量,它相当于 `append`。 + - 插入后,模块名称会自动调整(例如,插入到索引 1,会将原 1 变为 2)。 + - 源代码位置:同上。 +- **示例**: + ```python + import torch.nn as nn + + n = nn.Sequential(nn.Linear(1, 2), nn.Linear(2, 3)) + n.insert(1, nn.ReLU()) # 在索引 1 插入 ReLU + print(n) + # 输出: + # Sequential( + # (0): Linear(in_features=1, out_features=2, bias=True) + # (1): ReLU() + # (2): Linear(in_features=2, out_features=3, bias=True) + # ) + ``` + +### 附加说明 +- **继承的方法**:除了以上特有方法,`Sequential` 还继承了 `nn.Module` 的所有方法,例如: + - `forward(input)`:核心前向传播方法,自动遍历所有子模块。 + - `parameters()` / `named_parameters()`:获取模型参数。 + - `zero_grad()`、`step()`:用于优化器交互。 + - `to(device)`:移动到指定设备(如 GPU)。 + 这些在官网的 `nn.Module` 文档中详细描述,这里不赘述。 +- **使用建议**:`Sequential` 适合构建简单的线性网络(如 MLP 或 CNN 的基本堆叠)。对于复杂结构(如残差连接),推荐使用自定义 `nn.Module` 子类。 +- **版本信息**:以上基于 PyTorch 2.4+ 文档(官网持续更新,当前日期 2025-09-09 时为最新)。如果需要代码验证,建议在实际环境中测试。 + +如果您需要某个方法的更详细代码示例、数学推导或其他 PyTorch 相关问题,请随时补充! \ No newline at end of file diff --git a/Pytorch/nn/readme.md b/Pytorch/nn/readme.md new file mode 100644 index 0000000..07b480c --- /dev/null +++ b/Pytorch/nn/readme.md @@ -0,0 +1,216 @@ +好嘞 😃,那我给你系统、详细地讲一下 **`torch.nn`** ——它基本上是 PyTorch 搭建神经网络的核心模块。 + +--- + +# 🔹 1. `torch.nn` 是什么? + +* `torch.nn` = **neural network(神经网络)** 的缩写。 +* 作用:提供了构建神经网络的各种**模块**(layers)、**容器**、**损失函数**、**工具函数**。 +* 核心思想:把网络看成一组 **模块(Module)** 的组合,每个模块都可以包含参数(权重、偏置),也可以嵌套其他模块。 + +--- + +# 🔹 2. 核心类:`nn.Module` + +所有神经网络的基础类,几乎所有东西(层、模型、损失函数)都继承自它。 + +### 常见用法 + +```python +import torch +import torch.nn as nn + +class MyModel(nn.Module): + def __init__(self): + super().__init__() + self.fc1 = nn.Linear(10, 20) # 输入10维 -> 输出20维 + self.fc2 = nn.Linear(20, 1) # 输入20维 -> 输出1维 + + def forward(self, x): # 定义前向传播 + x = torch.relu(self.fc1(x)) + x = self.fc2(x) + return x + +model = MyModel() +``` + +👉 所有模型都需要定义 `__init__` 和 `forward` 方法。 + +--- + +# 🔹 3. 常用层(Layers) + +`torch.nn` 提供了很多常用的层,常见的分类: + +### (1)全连接层(Linear) + +```python +nn.Linear(in_features, out_features) +``` + +* 就是矩阵乘法 + bias +* 常用于 MLP + +--- + +### (2)卷积层(CNN) + +```python +nn.Conv1d, nn.Conv2d, nn.Conv3d +``` + +* 卷积神经网络的核心 +* 用于提取空间/时序特征 + +--- + +### (3)循环神经网络(RNN / LSTM / GRU) + +```python +nn.RNN, nn.LSTM, nn.GRU +``` + +* 用于处理序列数据(文本、时间序列) + +--- + +### (4)归一化层 + +```python +nn.BatchNorm1d, nn.BatchNorm2d, nn.LayerNorm +``` + +* 让训练更稳定,加速收敛 + +--- + +### (5)正则化层 + +```python +nn.Dropout(p=0.5) +``` + +* 随机“丢弃”神经元,防止过拟合 + +--- + +# 🔹 4. 常用容器(Containers) + +用于把多个层组合在一起。 + +### (1)Sequential + +```python +model = nn.Sequential( + nn.Linear(10, 20), + nn.ReLU(), + nn.Linear(20, 1) +) +``` + +* 顺序堆叠层,适合简单模型。 + +### (2)ModuleList / ModuleDict + +```python +self.layers = nn.ModuleList([nn.Linear(10, 20), nn.Linear(20, 30)]) +self.dict = nn.ModuleDict({ + "fc1": nn.Linear(10, 20), + "fc2": nn.Linear(20, 1) +}) +``` + +* 更灵活,可以动态组合模块。 + +--- + +# 🔹 5. 常用损失函数(Loss functions) + +`torch.nn` 提供了很多常用的 loss: + +* **回归** + + ```python + nn.MSELoss() # 均方误差 + nn.L1Loss() # 绝对值误差 + ``` + +* **分类** + + ```python + nn.CrossEntropyLoss() # 多分类交叉熵 + nn.BCELoss() # 二分类交叉熵 + nn.NLLLoss() # 负对数似然 + ``` + +* **其他** + + ```python + nn.SmoothL1Loss() # Huber loss + ``` + +--- + +# 🔹 6. 激活函数 + +激活函数也在 `torch.nn` 里,分为 **类** 和 **函数式** 两种: + +* 类形式(模块) + + ```python + nn.ReLU(), nn.Sigmoid(), nn.Tanh() + ``` +* 函数形式(函数接口) + + ```python + torch.relu(x), torch.sigmoid(x), torch.tanh(x) + ``` + +👉 一般在 `nn.Sequential` 里用类形式,在 `forward` 里用函数形式。 + +--- + +# 🔹 7. 使用流程(套路) + +一个典型训练流程: + +```python +import torch +import torch.nn as nn +import torch.optim as optim + +# 1. 定义模型 +model = nn.Sequential( + nn.Linear(10, 20), + nn.ReLU(), + nn.Linear(20, 1) +) + +# 2. 定义损失函数 +criterion = nn.MSELoss() + +# 3. 定义优化器 +optimizer = optim.SGD(model.parameters(), lr=0.01) + +# 4. 前向传播 + 反向传播 + 更新 +x = torch.randn(5, 10) # 输入 (batch=5, features=10) +y = torch.randn(5, 1) # 目标 + +output = model(x) # 前向 +loss = criterion(output, y) # 计算损失 +optimizer.zero_grad() # 梯度清零 +loss.backward() # 反向传播 +optimizer.step() # 参数更新 +``` + +--- + +# 🔹 8. 记忆小技巧 + +* **所有层、损失函数、网络结构都是 `nn.Module` 的子类** +* **训练流程三步走:forward → loss → backward** +* **组合模块时,先想清楚输入输出 shape** + +--- + +要不要我帮你整理一个 **torch.nn 思维导图(层 → 容器 → 损失函数 → 激活函数 → 用法套路)**,这样你一张图就能记住? diff --git a/Pytorch/readme.md b/Pytorch/readme.md new file mode 100644 index 0000000..eeecdef --- /dev/null +++ b/Pytorch/readme.md @@ -0,0 +1,124 @@ +好问题 👍!如果你想系统学习 **PyTorch**,可以按模块分层次来学。我给你整理一个「PyTorch 学习清单表」,从最核心到常用扩展,覆盖 80% 以上的开发需求。 + +--- + +# 📑 PyTorch 学习清单 + +| 模块 | 关键内容 | 说明 / 示例 | +| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- | +| **1. 基础(torch.Tensor)** | - 创建 Tensor(`torch.tensor`, `torch.randn`, `torch.zeros`)
- Tensor 属性(`shape`, `dtype`, `device`)
- 基本运算(加减乘除、索引切片、矩阵运算 `mm/matmul`)
- 广播机制 | PyTorch 的核心数据结构,几乎所有操作都基于它 | +| **2. 自动求导(torch.autograd)** | - `requires_grad=True`
- `backward()` 自动求梯度
- `grad` 属性
- `with torch.no_grad()` | 深度学习训练依赖的自动微分机制 | +| **3. 神经网络模块(torch.nn)** | - `nn.Module` 基类
- 常用层:`nn.Linear`, `nn.Conv2d`, `nn.Dropout`, `nn.BatchNorm`
- 激活函数:`ReLU`, `Sigmoid`, `Tanh`
- 容器:`nn.Sequential`, `nn.ModuleList`
- 常用损失函数:`MSELoss`, `CrossEntropyLoss` | 用来快速构建神经网络 | +| **4. 优化器(torch.optim)** | - `SGD`, `Adam`, `RMSprop`
- 常见用法:`zero_grad()`, `step()`
- 学习率调整:`optim.lr_scheduler` | 负责更新模型参数 | +| **5. 数据加载(torch.utils.data)** | - `Dataset` 自定义数据集
- `DataLoader` 批处理 & shuffle & 多线程
- 内置数据集(MNIST 等,来自 `torchvision`) | 解决大规模数据训练的问题 | +| **6. GPU 加速** | - `.to(device)` 或 `.cuda()`
- `torch.device("cuda" if torch.cuda.is_available() else "cpu")` | 利用显卡进行加速 | +| **7. 模型保存与加载** | - 保存参数:`torch.save(model.state_dict())`
- 加载参数:`model.load_state_dict(torch.load(...))` | 模型训练完要持久化保存 | +| **8. 高阶工具** | - `torch.nn.functional`(函数式 API,如 `F.relu`)
- `torch.distributed`(分布式训练)
- `torch.jit`(模型加速 & 部署)
- `torch.autocast`(混合精度训练) | 提升性能、扩展能力 | +| **9. 扩展库** | - `torchvision`(图像)
- `torchaudio`(语音)
- `torchtext`(NLP) | 方便调用现成模型和数据 | + +--- + +# 🔑 学习顺序推荐 + +1. **Tensor 基础**(先当作 NumPy 替代品来玩) +2. **autograd 自动求导**(理解梯度流) +3. **nn.Module + optim + loss**(最小训练循环) +4. **Dataset + DataLoader**(学会批处理) +5. **GPU 加速**(.cuda / .to) +6. **保存 / 加载模型** +7. **扩展功能**(半精度训练、分布式、多模态库) + +--- + +👉 总结一句话: + +> PyTorch 的主线是 **Tensor → autograd → nn → optim → data → GPU → save/load**。 + +--- + +要不要我帮你整理成一个「一周 PyTorch 学习计划」?每天学一点,1 周能把这张表过一遍,快速入门。 + +对!你抓住重点了 👍 + +在 **PyTorch 开发**里,常用的核心模块主要有这几个(按层次来看): + +--- + +## 🔹 1. **`torch` 基础** + +* `torch.Tensor` → 所有数据的核心类型 +* 常用操作:索引、切片、加减乘除、矩阵运算(`torch.mm`、`torch.matmul`) + +👉 可以把它理解成「比 NumPy 更强的张量库」。 + +--- + +## 🔹 2. **`torch.autograd`(自动求导)** + +* 这是 PyTorch 的「魔法」: + 只要 `requires_grad=True`,它就会自动构建计算图,帮你算梯度。 +* 常用的就是: + + ```python + x = torch.randn(3, 3, requires_grad=True) + y = x.sum() + y.backward() + print(x.grad) + ``` + +👉 用于 **反向传播**,深度学习训练的关键。 + +--- + +## 🔹 3. **`torch.nn`(神经网络模块)** + +* 提供 **层、损失函数、容器**,让你快速定义网络。 +* `nn.Module` → 所有网络的基类 +* `nn.Linear`、`nn.Conv2d`、`nn.ReLU`、`nn.CrossEntropyLoss` 等就是日常必备。 + +👉 可以理解为「把 `autograd` 封装起来,让写网络更方便」。 + +--- + +## 🔹 4. **`torch.optim`(优化器)** + +* 用于更新参数。 +* 常见优化器: + + * `optim.SGD` + * `optim.Adam` +* 使用套路: + + ```python + optimizer = optim.Adam(model.parameters(), lr=1e-3) + optimizer.zero_grad() + loss.backward() + optimizer.step() + ``` + +--- + +## 🔹 5. (扩展)常用工具 + +* **`torch.utils.data`** + + * `Dataset` / `DataLoader`:数据加载、批处理、多线程 +* **`torchvision` / `torchaudio` / `torchtext`** + + * 提供数据集 & 常用模型(ResNet, BERT 等) + +--- + +## ✅ 总结(开发最常用三件套) + +* **建模** → `torch.nn` +* **求梯度** → `torch.autograd` +* **更新参数** → `torch.optim` + +基本上你会发现: + +> 80% 的 PyTorch 代码就是在围绕 **Tensor → autograd → nn → optim → data** 这几个模块转。 + +--- + +要不要我帮你写一个「PyTorch 最小训练框架」,几乎涵盖 `autograd`、`nn`、`optim`、`data` 的核心套路?这样你看完能秒懂 PyTorch 主干逻辑。 diff --git a/Pytorch/tensor/.idea/.gitignore b/Pytorch/tensor/.idea/.gitignore new file mode 100644 index 0000000..359bb53 --- /dev/null +++ b/Pytorch/tensor/.idea/.gitignore @@ -0,0 +1,3 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml diff --git a/Pytorch/tensor/.idea/dictionaries/project.xml b/Pytorch/tensor/.idea/dictionaries/project.xml new file mode 100644 index 0000000..4787784 --- /dev/null +++ b/Pytorch/tensor/.idea/dictionaries/project.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/Pytorch/tensor/.idea/inspectionProfiles/profiles_settings.xml b/Pytorch/tensor/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..dd4c951 --- /dev/null +++ b/Pytorch/tensor/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/Pytorch/tensor/.idea/misc.xml b/Pytorch/tensor/.idea/misc.xml new file mode 100644 index 0000000..7fece0c --- /dev/null +++ b/Pytorch/tensor/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/Pytorch/tensor/.idea/modules.xml b/Pytorch/tensor/.idea/modules.xml new file mode 100644 index 0000000..79367b8 --- /dev/null +++ b/Pytorch/tensor/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/Pytorch/tensor/.idea/tensor.iml b/Pytorch/tensor/.idea/tensor.iml new file mode 100644 index 0000000..b910500 --- /dev/null +++ b/Pytorch/tensor/.idea/tensor.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/Pytorch/tensor/.idea/vcs.xml b/Pytorch/tensor/.idea/vcs.xml new file mode 100644 index 0000000..b2bdec2 --- /dev/null +++ b/Pytorch/tensor/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Pytorch/tensor/create_numpy.py b/Pytorch/tensor/create_numpy.py new file mode 100644 index 0000000..689273d --- /dev/null +++ b/Pytorch/tensor/create_numpy.py @@ -0,0 +1,24 @@ +import numpy as np +import torch + +a = np.array([1, 2, 3, 10, 9, 8, 7, 6, 5, 4]) +b = torch.from_numpy(a) +print(b) + +c = torch.arange(10) +print(c) +print(c.dtype, c.layout, c.device) + +d = int(c.matmul(b)) +#不写int是tensor(274) +e = c * b +print(d, e) + +#in-place与广播 +a1 = torch.tensor([1,1,3]) +a2 = torch.tensor([1])#右对齐 +a3 = torch.add(a1, a2) +print(a3, a3.layout) + +#比较 +print(torch.ge(a1, a2), torch.ne(a1, a2)) \ No newline at end of file diff --git a/Pytorch/tensor/create_tensor.py b/Pytorch/tensor/create_tensor.py new file mode 100644 index 0000000..bacb9da --- /dev/null +++ b/Pytorch/tensor/create_tensor.py @@ -0,0 +1,29 @@ +import torch + +a = torch.tensor(([[[[0., 0., 0.], + [0., 0., 0.]], + + [[0., 1., 0.], + [0., 0., 0.]]], + + + [[[0., 2., 0.], + [0., 0., 0.]], + + [[0., 3., 0.], + [0., 0., 0.]]]])) +print(a) + +b = torch.tensor([[3., 2., 1.], [1., 2., 3.]]) +c = torch.tensor([[1., 2., 3.], [4., 5., 6.]]) + +print(b) +times = b * c +print(times) +print(times.type()) + +c = torch.normal(mean=1.0, std=torch.rand(5, 5)) +print(c) + +d = torch.randperm(10) +print(d) \ No newline at end of file diff --git a/Pytorch/tensor/main.py b/Pytorch/tensor/main.py new file mode 100644 index 0000000..e69de29 diff --git a/Pytorch/tensor/readme.md b/Pytorch/tensor/readme.md new file mode 100644 index 0000000..bfcabc5 --- /dev/null +++ b/Pytorch/tensor/readme.md @@ -0,0 +1,205 @@ +好的 😄,我给你整理一个 **PyTorch `tensor` 使用大全**,覆盖创建、操作、转换、计算等常用方法。为了系统化,我会按类别来整理,并给简单示例。 + +--- + +# 🟢 1. 创建 Tensor + +```python +import torch + +# 直接从数据创建 +a = torch.tensor([1, 2, 3], dtype=torch.float32) + +# 全 0 / 全 1 / 全某数 +b = torch.zeros(3, 4) +c = torch.ones(2, 5) * 7 + +# 随机数 +d = torch.rand(3, 3) # 0~1 均匀分布 +e = torch.randn(3, 3) # 标准正态分布 + +# 类似 numpy 的 arange / linspace +f = torch.arange(0, 10, 2) # 0,2,4,6,8 +g = torch.linspace(0, 1, steps=5) # 0,0.25,0.5,0.75,1 + +# 空 tensor(占位) +h = torch.empty(2, 3) +``` + +--- + +# 🟢 2. Tensor 属性 + +```python +x = torch.randn(2, 3) + +x.shape # 返回 (2,3) +x.size() # 等同 shape +x.dtype # 数据类型,如 torch.float32 +x.device # 运行设备,如 cpu 或 cuda:0 +x.numel() # 元素总数 +x.requires_grad_(True) # 设置是否需要梯度 +``` + +--- + +# 🟢 3. Tensor 运算 + +### 3.1 基本算术 + +```python +a = torch.tensor([1,2,3]) +b = torch.tensor([4,5,6]) + +c = a + b +d = a - b +e = a * b +f = a / b +g = a ** 2 +``` + +### 3.2 矩阵运算 + +```python +A = torch.rand(2,3) +B = torch.rand(3,2) + +C = torch.matmul(A, B) # 矩阵乘法 +D = A @ B # 等价写法 +E = A.T # 转置 +``` + +### 3.3 统计函数 + +```python +x = torch.tensor([[1,2],[3,4]], dtype=torch.float32) + +x.sum() # 所有元素求和 +x.mean() # 平均值 +x.max() # 最大值 +x.min() # 最小值 +x.argmax() # 最大值索引 +x.argmin() # 最小值索引 +x.std() # 标准差 +x.var() # 方差 +``` + +--- + +# 🟢 4. Tensor 索引与切片 + +```python +x = torch.tensor([[1,2,3],[4,5,6]]) + +x[0] # 第一行 +x[:,1] # 第二列 +x[0,2] # 第一行第三列 +x[1,:2] # 第二行前两列 +x[-1,-1] # 最后一个元素 +``` + +--- + +# 🟢 5. Tensor 改变形状 + +```python +x = torch.arange(12) + +y = x.view(3,4) # 改变形状 (reshape) +z = x.reshape(3,4) # reshape 等同 view,但更安全 +w = x.unsqueeze(0) # 增加维度 +v = x.squeeze() # 删除维度为1的维 +t = x.transpose(0,0) # 交换维度 +``` + +--- + +# 🟢 6. Tensor 拼接与拆分 + +```python +a = torch.randn(2,3) +b = torch.randn(2,3) + +# 拼接 +c = torch.cat([a,b], dim=0) # 纵向拼接 +d = torch.cat([a,b], dim=1) # 横向拼接 + +# 堆叠(增加新维度) +e = torch.stack([a,b], dim=0) + +# 拆分 +f1, f2 = torch.chunk(c, 2, dim=0) # 按行拆成两块 +``` + +--- + +# 🟢 7. Tensor 类型转换 + +```python +x = torch.tensor([1,2,3], dtype=torch.int32) + +x.float() # 转 float +x.double() # 转 double +x.long() # 转 int64 +x.bool() # 转 bool +``` + +--- + +# 🟢 8. Tensor 与 NumPy 互转 + +```python +import numpy as np + +a = torch.tensor([1,2,3]) +b = a.numpy() # Tensor → numpy array + +c = np.array([4,5,6]) +d = torch.from_numpy(c) # numpy → Tensor +``` + +⚠️ 注意:共享内存,如果修改其中一个,另一个也会变。 + +--- + +# 🟢 9. GPU 操作 + +```python +x = torch.randn(2,3) + +device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") +x = x.to(device) + +y = torch.tensor([1,2,3], device=device) # 直接在 GPU 上创建 +``` + +--- + +# 🟢 10. 自动求导(梯度) + +```python +x = torch.tensor([2.0,3.0], requires_grad=True) +y = x ** 2 + 3*x +z = y.sum() +z.backward() # 自动求梯度 +print(x.grad) # dx +``` + +--- + +# 🟢 11. 常用函数速查 + +| 类别 | 常用函数 | +| ---- | --------------------------------------------- | +| 线性代数 | `matmul`, `mm`, `bmm`, `einsum` | +| 激活函数 | `relu`, `sigmoid`, `tanh`, `softmax` | +| 聚合函数 | `sum`, `mean`, `max`, `min`, `prod`, `cumsum` | +| 比较函数 | `eq`, `ne`, `gt`, `lt`, `ge`, `le` | +| 随机函数 | `rand`, `randn`, `randint`, `randperm` | +| 其他 | `clone`, `detach`, `item`, `expand`, `repeat` | + +--- + +如果你需要,我可以帮你整理一个 **可直接拷贝的 PyTorch Tensor 使用小抄(含示例和用法备注)**,适合放在屏幕边上快速查。 + +你希望我帮你整理吗?