深度学习笔记012:AlexNet+.nn.Sequential构建神经网络使用实例+object to parameter ‘0’ (torch.nn.Parameter or None……

本文详细探讨了AlexNet神经网络模型中如何利用数据增强技术,如随机裁剪和色彩调整,以及如何通过torch.nn.Sequential构建和组织复杂的网络结构。作者还展示了如何在Sequential中嵌套自定义模块和处理可学习参数,以及潜在的错误处理和最佳实践。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

AlexNet

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
对 原 始 图 片 进 行 了 数 据 增 强 : 随 机 截 取 , 亮 度 与 色 温 的 改 变 对原始图片进行了数据增强:随机截取,亮度与色温的改变

在这里插入图片描述

torch.nn.Sequential源码链接

nn.Sequential
A sequential container. Modules will be added to it in the order they are passed in the constructor. Alternatively, an ordered dict of modules can also be passed in.

一个有序的容器,神经网络模块将按照在传入构造器的顺序依次被添加到计算图中执行,同时以神经网络模块为元素的有序字典也可以作为传入参数;代码链接。

import torch
from torch import nn

# Module 类是 nn 模块⾥提供的⼀个模型构造类,是所有神经⽹络模块的基类,继承它来定义我们想要的模型。需要重写Module 类的 __init__ 函数和 forward 函数。它们分别⽤于创建模型参数和定义前向计算。

class CenteredLayer(nn.Module):
    def __init__(self, **kwargs):
        super(CenteredLayer, self).__init__(**kwargs)

    def forward(self, x):

        return x - x.mean()

# 测试一下
layer = CenteredLayer()
layer(torch.tensor([1, 2, 3, 4, 5], dtype=torch.float))

# 放入到nn.Sequential中
net = nn.Sequential(nn.Linear(8, 128), CenteredLayer())
y = net(torch.rand(4, 8))
y.mean().item()
class FancyMLP(nn.Module):
    def __init__(self, **kwargs):
        super(FancyMLP, self).__init__(**kwargs)
    	self.rand_weight = torch.rand((20, 20),requires_grad=False)  # 不可训练参数(常数参数)
    	self.linear = nn.Linear(20, 20)

    def forward(self, x):
        x = self.linear(x)
        # 使⽤创建的常数参数,以及nn.functional中的relu函数和mm函数
    	x = nn.functional.relu(torch.mm(x, self.rand_weight.data) + 1)
    	# 复⽤全连接层。等价于两个全连接层共享参数
    	x = self.linear(x)
    	# 控制流,这⾥我们需要调⽤item函数来返回标量进⾏⽐较
    	while x.norm().item() > 1:
        	x /= 2
    	if x.norm().item() < 0.8:
        	x *= 10
    	return x.sum()
class NestMLP(nn.Module):
    def __init__(self, **kwargs):
        super(NestMLP, self).__init__(**kwargs)
        self.net = nn.Sequential(nn.Linear(40, 30), nn.ReLU())

    def forward(self, x):
        return self.net(x)


net = nn.Sequential(NestMLP(), nn.Linear(30, 20), FancyMLP())

更复杂一点的情况

如果模型中有需要学习的参数:

class MyDense(nn.Module):
    def __init__(self):
        # 在自己的模块中添加可学习的参数,供训练学习使用
        super(MyDense, self).__init__()
        self.params = nn.ParameterList([nn.Parameter(torch.randn(4,4)) for i in range(3)])
        # nn.Parameter(torch.randn(4,4)): Parameter 类其实是 Tensor 的⼦类,如果⼀个 Tensor 是 Parameter ,那么它会⾃动被添加到模型的参数列表⾥
        # ParameterList 接收⼀个 Parameter 实例的列表作为输⼊然后得到⼀个参数列表,使⽤的时候可以⽤索引来访问某个参数
        self.params.append(nn.Parameter(torch.randn(4, 1))) # 可以使⽤ append 和 extend 在列表后⾯新增参数
    def forward(self, x):
        for i in range(len(self.params)):
            x = torch.mm(x, self.params[i])
        return x

net = MyDense()
print(net)

模型参数访问

更多相关的编程细节

提示:
注:多个模型嵌套的情况下,函数中传播的部分写到了初始化中,可能正向传播没有问题,但是,无法获取参数列表进行反向传播。

TypeError: cannot assign ‘torch.FloatTensor’ object to parameter ‘0’ (torch.nn.Parameter or None required)

nn.Sequential(layers)中的用法及错误TypeError: list is not a Module subclass
ValueError:optimizer got an empty parameter list,参数空传

提示:
如果在forward 中传入或new数据,需要考虑和网络在同一个device。

其他实现方法

make layer是对每一层的层自定义创建:构造对象数组layers,然后调用nn.Sequential(*layers)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

<think>我们正在讨论的是`torch.nn.Sequential`的返回值。根据用户的问题,他想知道`torch.nn.Sequential`的返回值是什么。 首先,我们需要明确:`torch.nn.Sequential`是一个类,当我们调用它时,我们是在创建一个`Sequential`模型。因此,它的返回值是一个`Sequential`模型实例。 但是,用户可能更关心的是当我们使用这个模型进行前向传播时,它的输出(即返回值)是什么?或者,在构建模型时,`torch.nn.Sequential`返回的对象是什么? 根据引用[3]中的描述: > 一个序列容器,用于搭建神经网络的模块,被按照被传入构造器的顺序添加到nn.Sequential()容器中......模型前向传播时调用forward()方法,模型接受的输入首先被传入的nn.Sequential()包含的第一个网络模块中,然后第一个网络模块输出传入到第二个网络模块作为输入。按照顺序依次计算并传播,直到nn.Sequential()里的最后一个模块输出结果。 因此,我们可以总结: 1. **构造时的返回值**:当我们初始化一个`nn.Sequential`对象时,它返回一个包含所有传入模块的序列容器(一个模型)。这个容器本身是`torch.nn.Module`的子类,因此它具有模型的所有特性(例如可以调用`parameters()`方法,可以移动到GPU等)。 2. **前向传播的返回值**:当我们用一个输入张量调用这个`Sequential`模型时(即执行`model(input)`),它会将输入依次通过容器中的每一个模块(从第一个到最后一个),并将最后一个模块的输出作为整个模型的输出返回。 举个例子,引用[1]中: ```python input = torch.randn(2, 50) m = nn.Sequential( nn.Linear(50, 50), nn.Unflatten(1, (2, 5, 5)) ) output = m(input) print(output.size()) # 输出: torch.Size([2, 2, 5, 5]) ``` 这里,`m`就是`nn.Sequential`构造时返回的模型。当我们执行`m(input)`时,返回值`output`是经过`Linear`层和`Unflatten`层处理后的张量,其形状为`[2,2,5,5]`。 另外,引用[4]中展示了RNN使用,但`nn.Sequential`本身并不直接支持像RNN这样返回多个输出的模块(除非将多个输出打包成元组等)。所以,如果`Sequential`中的最后一个模块返回多个值,那么整个`Sequential`模型也会返回多个值。但通常情况下,模块都是返回一个张量。 因此,我们可以这样回答: - 在构建模型时,`torch.nn.Sequential`返回一个`Sequential`模型实例(`torch.nn.Module`对象)。 - 在模型进行前向传播时,该模型将输入数据依次通过各层,并返回最后一层的输出。输出类型取决于最后一层模块的返回值(通常是张量,也可能是元组等)。 注意:如果用户问的是函数调用的返回值,通常是指第一种情况(构造时返回的模型对象)。如果用户关心的是前向传播的输出,则需要明确上下文。 由于用户的问题没有明确是构造时还是前向传播,我们应涵盖两种情况。 另外,引用[5]中提到了`modules()`方法,但这不是直接关于返回值的问题,所以我们可以不涉及。 根据以上分析,我们给出回答。</think>### `torch.nn.Sequential` 返回值详解 #### 1. **构造时的返回值** 当调用`torch.nn.Sequential()`时,返回的是一个**顺序模型容器对象**(`torch.nn.Sequential`实例),该对象: - 继承自`torch.nn.Module`类[^5] - 包含所有传入的神经网络层模块 - 自动管理各层的参数和梯度计算 ```python model = nn.Sequential( nn.Linear(50, 50), nn.ReLU(), nn.Unflatten(1, (2, 5, 5)) # 引用[1]示例 ) print(type(model)) # 输出: <class 'torch.nn.modules.container.Sequential'> ``` #### 2. **前向传播时的返回值** 当对输入数据执行`model(input)`时,返回值由**最后一层的输出决定**: ```python output = model(input_tensor) # 引用[1]示例 ``` - **返回类型**:取决于序列中最后一个模块的输出类型 - **典型情况**: - 单张量输出(最常见):如全连接层、卷积层的输出 ```python # 输出torch.Size([2, 2, 5, 5])的张量 [^1] print(output.size()) ``` - 元组输出:如RNN层返回`(output, hidden_state)` [^4] - 自定义类型:若末层返回自定义对象则整体返回相同类型 #### 3. **返回值特性 | 特性 | 说明 | |------|------| | **自动链式计算** | 输入依次通过各层:$y = f_n(\cdots f_2(f_1(x)))$ [^3] | | **动态类型推断** | 返回类型由末层决定,无需显式声明 | | **梯度可追溯** | 返回的张量自动包含梯度计算图 | | **维度一致性** | 输出维度必须匹配下一层输入(若存在后续连接) | #### 4. **使用示例 ```python import torch import torch.nn as nn # 构造模型(返回Sequential实例) model = nn.Sequential( nn.Linear(100, 50), # 全连接层 nn.ReLU(), # 激活函数 nn.Linear(50, 10) # 输出层 ) input = torch.randn(32, 100) # 批量输入 output = model(input) # 前向传播 print(output.shape) # 输出: torch.Size([32, 10]) print(type(output)) # 输出: <class 'torch.Tensor'> ``` > ⚠️ **关键注意事项** > - 若序列中包含多个返回值的层(如RNN),整体返回值会变为元组[^4] > - 可通过索引直接访问中间层输出:`mid_output = model[:2](input)` > - 返回值始终包含`requires_grad=True`属性,支持自动微分
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值