PyTorch:nn模型层container

本文详细介绍了PyTorch中的容器类,包括nn.Module、nn.ModuleList、nn.Sequential及nn.ModuleDict的使用方法与区别。通过示例展示了如何构建复杂的神经网络结构。
部署运行你感兴趣的模型镜像

-柚子皮-

概述

模型层的命名方式

命名方式 {自动识别名称如bn_layers}.0.weight

if self.use_bn:
    self.bn_layers = nn.ModuleList(
        [nn.BatchNorm1d(hidden_units[i + 1]) for i in range(len(hidden_units) - 1)])

查看模型每层输出详情

Keras有一个简洁的API来查看模型的每一层输出尺寸,这在调试网络时非常有用。

在PyTorch中也可以实现这个功能。
使用很简单,如下用法:
from torchsummary import summary
summary(your_model, input_size=(channels, H, W))
input_size 是根据你自己的网络模型的输入尺寸进行设置。

容器类及其区别

nn.Module, nn.ModuleList, nn.Sequential,这些类我们称之为容器 (containers),因为我们可以添加模块 (module) 到它们之中。

如果你确定 nn.Sequential 里面的顺序是你想要的,而且不需要再添加一些其他处理的函数 (比如 nn.functional 里面的函数),那么完全可以直接用 nn.Sequential。这么做的代价就是失去了部分灵活性,毕竟不能自己去定制 forward 函数里面的内容了。

使用Module:当您有由多个小块组成的大块时
使用Sequential:想要从层创建小块时使用
使用ModuleList:当您需要遍历某些层或构建块并执行某些操作时
使用ModuleDict:当您需要参数化机器学习模型的某些块时使用,例如激活函数

[PyTorch 中的 ModuleList 和 Sequential: 区别和使用场景]

Module:主要构建块

Module是主要构建块,它定义了所有神经网络的基类。

CLASStorch.nn.Module(*args, **kwargs)

方法

apply(fn)

Applies fn recursively to every submodule (as returned by .children()) as well as self. Typical use includes initializing the parameters of a model (see also torch.nn.init).

>>> @torch.no_grad()
>>> def init_weights(m):
>>>     if type(m) == nn.Linear:
>>>         m.weight.fill_(1.0)
>>> net = nn.Sequential(nn.Linear(2, 2), nn.Linear(2, 2))
>>> net.apply(init_weights)

示例

import torch.nn as nn
import torch.nn.functional as F

class Model(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1 = nn.Conv2d(1, 20, 5)
        self.conv2 = nn.Conv2d(20, 20, 5)

    def forward(self, x):
        x = F.relu(self.conv1(x))
        return F.relu(self.conv2(x))

nn.Sequential: stack和erge层

Sequential是一个模块的容器,可以stacked在一起并同时运行。

它实现了内部的 forward 函数,而且里面的模块必须是按照顺序进行排列的,所以我们必须确保前一个模块的输出大小和下一个模块的输入大小是一致的。

示例

class net5(nn.Module):
    def __init__(self):
        super(net5, self).__init__()
        self.block = nn.Sequential(nn.Conv2d(1,20,5),
                                    nn.ReLU(),
                                    nn.Conv2d(20,64,5),
                                    nn.ReLU())
    def forward(self, x):
        x = self.block(x)
        return x

net = net5()
print(net)

nn.ModuleList:我们需要迭代的时候

CLASStorch.nn.ModuleList(modules=None),代码实现上是class ModuleList(Module)继承了Module方法。

Holds submodules in a list. ModuleList can be indexed like a regular Python list, but modules it contains are properly registered, and will be visible by all Module methods.

ModuleList允许您存储Module为列表。当您需要遍历层并存储/使用某些信息(如U-net)时,它非常有用。和Sequential的主要区别在于ModuleList没有forward 方法,因此内部层没有连接。

      对于 nn.ModuleList 这个类,你可以把任意 nn.Module 的子类 (比如 nn.Conv2d, nn.Linear 之类的) 加到这个 list 里面,方法和 Python 自带的 list 一样,无非是 extend,append 等操作。但不同于一般的 list,加入到 nn.ModuleList 里面的 module 是会自动注册到整个网络上的,同时 module 的 parameters 也会自动添加到整个网络中(即net.parameters()这个是有相应值的)。但是nn.ModuleList 并没有定义一个网络,它只是将不同的模块储存在一起,这些模块之间并没有什么先后顺序可言,网络的执行顺序是根据 forward 函数来决定的。

示例1

class MyModule(nn.Module):
    def __init__(self):
        super().__init__()
        self.linears = nn.ModuleList([nn.Linear(10, 10) for i in range(10)])

    def forward(self, x):
        # ModuleList can act as an iterable, or be indexed using ints
        for i, l in enumerate(self.linears):
            x = self.linears[i // 2](x) + l(x)
        return x

示例2

def __init__(self, config):
    super().__init__(config)

    self.layers = torch.nn.ModuleList()
    for i in range(1, len(self.hidden_dimensions)):
        self.layers.append(
            torch.nn.Sequential(
                torch.nn.Linear(self.hidden_dimensions[i-1], self.hidden_dimensions[i]),
                torch.nn.ReLU(),
                torch.nn.BatchNorm1d(self.hidden_dimensions[i]),
                torch.nn.Dropout(p=0.5)
            ))

    self.layers.apply(self._init_weight)
    
def _init_weight(self, m):
    if isinstance(m, torch.nn.Linear):
        torch.nn.init.normal_(m.weight, std=0.1) 

示例3

import torch
from torch import nn
class MLP(nn.Module):
    def __init__(self, m, n, ln=2):
        super(MLP, self).__init__()
        self.linears = nn.ModuleList([nn.Linear(m, n) for _ in range(ln)])

    def forward(self, x):
        for module in self.linears:
            x = module(x)
        return x
x = torch.tensor([[1, 2], [3, 4], [5, 6]]).float()
mlp1 = MLP(2, 2)
y = mlp1(x)
print(y)

ModuleList和Sequential结合的示例

import torch
class Classifier(torch.nn.Module):
    def __init__(self):
        super().__init__()
        self.layers = torch.nn.ModuleList()
        for i in range(3):
            self.layers.append(
                torch.nn.Sequential(
                    torch.nn.Linear(1024, 128),
                    torch.nn.ReLU(),
                    torch.nn.BatchNorm1d(128),
                    torch.nn.Dropout(p=0.2)
                ))

    def forward(self, batch):
        for layer in self.layers:
            layer_activation = layer(batch)
        # ...

nn.ModuleDict:我们需要选择的时候

可以使用ModuleDict创建一个Module字典,并在需要时动态切换。

示例1

activations = nn.ModuleDict([
    ['relu', nn.ReLU()],
    ['hardtanh', nn.Hardtanh()],
    ['relu6', nn.ReLU6()],
    ['sigmoid', nn.Sigmoid()],
    ['tanh', nn.Tanh()],
    ['softmax', nn.Softmax()],
    ['softmax2d', nn.Softmax2d()],
    ['logsoftmax', nn.LogSoftmax()],
    ['elu', nn.ELU()],
    ['selu', nn.SELU()],
    ['celu', nn.CELU()],
    ['hardshrink', nn.Hardshrink()],
    ['leakyrelu', nn.LeakyReLU()],
    ['logsigmoid', nn.LogSigmoid()],
    ['softplus', nn.Softplus()],
    ['softshrink', nn.Softshrink()],
    ['prelu', nn.PReLU()],
    ['softsign', nn.Softsign()],
    ['softmin', nn.Softmin()],
    ['tanhshrink', nn.Tanhshrink()],
    ['rrelu', nn.RReLU()],
    ['glu', nn.GLU()],
])

activation1 = activations['relu']

示例2

    embedding_dict = nn.ModuleDict(
        {key: nn.Embedding(vocab_size, ope_config.embed_size if not linear else 1, sparse=sparse)
         for key, vocab_size, w2i, i2w in lang}
    )

示例3

loss = nn.ModuleDict([
    ['l1', nn.L1Loss()],
    ['nll', nn.NLLLoss()],
    ['kldiv', nn.KLDivLoss()],
    ['mse', nn.MSELoss()],
    ['bce', nn.BCELoss()],
    ['bce_with_logits', nn.BCEWithLogitsLoss()],
    ['cosine_embedding', nn.CosineEmbeddingLoss()],
    ['ctc', nn.CTCLoss()],
    ['hinge_embedding', nn.HingeEmbeddingLoss()],
    ['margin_ranking', nn.MarginRankingLoss()],
    ['multi_label_margin', nn.MultiLabelMarginLoss()],
    ['multi_label_soft_margin', nn.MultiLabelSoftMarginLoss()],
    ['multi_margin', nn.MultiMarginLoss()],
    ['smooth_l1', nn.SmoothL1Loss()],
    ['soft_margin', nn.SoftMarginLoss()],
    ['cross_entropy', nn.CrossEntropyLoss()],
    ['triplet_margin', nn.TripletMarginLoss()],
    ['poisson_nll', nn.PoissonNLLLoss()]
])

[matchzoo/utils/parse.py]

[du/layers/embedding_layer.py]

from: -柚子皮-

ref: 

您可能感兴趣的与本文相关的镜像

PyTorch 2.5

PyTorch 2.5

PyTorch
Cuda

PyTorch 是一个开源的 Python 机器学习库,基于 Torch 库,底层由 C++ 实现,应用于人工智能领域,如计算机视觉和自然语言处理

<think>我们刚刚完成了PyTorch 1.12.0+cu113和CUDA 11.3的安装,接下来需要做什么? 下一步操作通常包括: 1. 验证PyTorch和CUDA是否安装成功 2. 配置深度学习项目所需的其他组件(如数据集、模型代码等) 3. 运行一个简单的测试程序确认GPU可用性 下面提供详细步骤: </think>在成功安装PyTorch 1.12.0+cu113和CUDA 11.3后,下一步操作应包含以下关键步骤: ### 1. 环境验证(确保GPU可用性) ```python import torch # 验证PyTorch版本和CUDA状态 print(f"PyTorch版本: {torch.__version__}") # 应为1.12.0+cu113 print(f"CUDA可用: {torch.cuda.is_available()}") # 应为True # 检查GPU详细信息 if torch.cuda.is_available(): print(f"GPU设备数: {torch.cuda.device_count()}") print(f"当前设备: {torch.cuda.current_device()}") print(f"设备名称: {torch.cuda.get_device_name(0)}") print(f"CUDA版本: {torch.version.cuda}") # 应为11.3 else: print("警告:CUDA不可用,请检查安装!") ``` ### 2. 基础功能测试(张量操作) ```python # 创建GPU张量 device = torch.device("cuda" if torch.cuda.is_available() else "cpu") x = torch.tensor([1.0, 2.0], device=device) y = torch.tensor([3.0, 4.0], device=device) # 执行GPU计算 z = x + y print(f"计算结果: {z}") # 应为tensor([4., 6.], device='cuda:0') # 验证反向传播 w = torch.tensor([1.0], requires_grad=True, device=device) loss = (w * x).sum() loss.backward() print(f"梯度值: {w.grad}") # 应为tensor([3.], device='cuda:0') ``` ### 3. 模型训练测试(简易神经网络) ```python import torch.nn as nn import torch.optim as optim # 定义简易模型 class TestNet(nn.Module): def __init__(self): super().__init__() self.fc = nn.Linear(2, 1) def forward(self, x): return self.fc(x) # 配置训练环境 model = TestNet().to(device) optimizer = optim.SGD(model.parameters(), lr=0.01) criterion = nn.MSELoss() # 训练循环 inputs = torch.tensor([[1.0, 2.0], [3.0, 4.0]], device=device) targets = torch.tensor([[3.0], [7.0]], device=device) for epoch in range(100): optimizer.zero_grad() outputs = model(inputs) loss = criterion(outputs, targets) loss.backward() optimizer.step() print(f"最终损失: {loss.item():.4f}") # 应接近0 print(f"预测结果: {model(inputs).detach()}") # 应接近[[3.0], [7.0]] ``` ### 4. 性能基准测试(可选) ```python # 测试矩阵乘法性能 size = 4096 a = torch.randn(size, size, device=device) b = torch.randn(size, size, device=device) torch.cuda.synchronize() # 同步GPU操作 start = torch.cuda.Event(enable_timing=True) end = torch.cuda.Event(enable_timing=True) start.record() c = torch.matmul(a, b) end.record() torch.cuda.synchronize() print(f"4096x4096矩阵乘法耗时: {start.elapsed_time(end):.2f} ms") ``` ### 5. 项目初始化建议 1. **框架选择**: - 计算机视觉项目:安装`torchvision==0.13.0` $$ \text{pip install torchvision==0.13.0+cu113} $$ - NLP项目:安装`transformers`库 2. **环境配置**: ```bash # 创建项目专属环境 conda create -n my_project python=3.8 conda activate my_project pip install numpy pandas matplotlib ``` 3. **版本控制**: ```bash # 生成requirements.txt pip freeze > requirements.txt ``` ### 6. 常见问题排查 | 问题现象 | 解决方案 | |---------|---------| | `CUDA unavailable` | 执行`nvidia-smi`确认驱动状态 | | 版本不匹配 | 检查`torch.version.cuda == 11.3` | | 内存不足 | 使用`torch.cuda.empty_cache()`释放显存 | | 算子不支持 | 升级PyTorch到1.12.1补丁版本 | > 完成验证后即可开始构建深度学习项目。建议从官方示例开始:[PyTorch Examples](https://github.com/pytorch/examples)[^1]
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值