教你用Pytorch搭建第一个神经网络

1.使用nn.Sequential定义神经网络

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

net = nn.Sequential(nn.Linear(20,256),nn.ReLU(),nn.Linear(256,10))
x = torch.rand(2,20)
net(x)

上述代码示例中,首先构建了一个简单的神经网络net,然后生成了一个随机的输入张量x,最后通过net(x)将x作为输入数据通过神经网络。具体实现的步骤和过程如下:

1.1构建神经网络:

神经网络 net 使用 nn.Sequential 构建,它按顺序包含了以下层:

① nn.Linear(20,256):第一个线性层(全连接层),接收20维的输入向量,输出 256 维的向量。

② nn.ReLU(): 一个ReLU 激活函数,对第一个线性层的输出应用非线性激活,增加模型的非线性能力,使得网络可以学习更复杂的函数映射。

③ nn.Linear(256,10): 第二个线性层,将ReLU激活函数的256维输出转换成10维的输出向量。这10维的输出通常用于分类任务,每一维代表一个类别的分类。

1.2 生成输入向量:

通过torch.rand(2, 20)创建了一个形状为(2, 20)的张量x,这意味着有两个20维的向量,每个元素都是从[0, 1)区间内均匀分布生成的随机数。这个张量可以被视作包含两个样本的批次,每个样本是一个20维的输入向量。

1.3. 通过网络传递数据:

当执行net(x)时,输入的张量x按照net定义的层序列通过神经网络:

  • 首先,x通过第一个线性层,得到一个形状为(2, 256)的张量,即两个256维的向量。
  • 然后,这个(2, 256)的张量通过ReLU激活函数,仍然保持(2, 256)的形状,但所有负值都被设置为0。
  • 最后,经过ReLU激活的张量通过第二个线性层,转换成一个形状为(2, 10)的张量,这表示两个样本的输出,每个样本对应10个类别的分数。
    在这里插入图片描述

2. 自定义神经网络

nn.squential 定义了一种特殊的 Module ,我们自定义一个MLP实现nn.squential 一样的操作。

class MLP(nn.Module):
    def __init__ (self):
        super().__init__()
        self.hidden = nn.Linear(20,256)
        self.out = nn.Linear(256,10)
        
    def forward(self, x):
        return self.out(F.relu(self.hidden(x)))

net = MLP()
net(x)

还有一种写法:

class MySequential(nn.Module):
    def __init__(self, *args):
        super(MySequential, self).__init__()
        # 为每个模块命名并添加到当前模块中
        for idx, module in enumerate(args):
            # 这里使用add_module方法添加模块,确保模块被正确注册
            self.add_module(str(idx), module)
    
    def forward(self, x):
        # 依次通过所有模块
        for module in self._modules.values():
            x = module(x)
        return x

# 测试自定义的MySequential
net = MySequential(nn.Linear(20, 256), nn.ReLU(), nn.Linear(256, 10))
x = torch.rand(2, 20)  # 创建输入张量

output = net(x)  # 前向传播
print(output.shape)  # 输出结果的形状应该是[2, 10]
print(output)

3. 参数管理

假设我们用nn.sequential() 定义了net,我想取出net[2]的参数,怎么取呢?

net = nn.Sequential(nn.Linear(20,256),nn.ReLU(),nn.Linear(256,10))
x = torch.rand(2,20)
net(x)
print(net[2].state_dict())

得到的结果是:

OrderedDict([(‘weight’, tensor([[-0.0282, -0.0167, -0.0511, …, 0.0577, -0.0041, -0.0491],
[-0.0166, -0.0429, 0.0390, …, 0.0090, 0.0607, -0.0525],
[-0.0106, 0.0355, 0.0616, …, 0.0281, 0.0251, 0.0412],
…,
[ 0.0369, 0.0303, 0.0138, …, -0.0400, 0.0557, -0.0274],
[ 0.0587, 0.0082, -0.0232, …, -0.0490, -0.0268, -0.0015],
[-0.0077, -0.0336, 0.0506, …, 0.0259, -0.0537, -0.0339]])), (‘bias’, tensor([-0.0415, -0.0138, -0.0404, -0.0211, -0.0504, 0.0538, -0.0407, -0.0125,
0.0438, 0.0278]))])

它有 weight 和 bias 两个参数。

我们也可以直接访问每一层的参数。

print(type(net[2].bias))#打印它的类型
print(net[2].bias)
print(net[2].bias.data)

打印结果是:

<class ‘torch.nn.parameter.Parameter’>
Parameter containing:
tensor([-0.0415, -0.0138, -0.0404, -0.0211, -0.0504, 0.0538, -0.0407, -0.0125,
0.0438, 0.0278], requires_grad=True)
tensor([-0.0415, -0.0138, -0.0404, -0.0211, -0.0504, 0.0538, -0.0407, -0.0125,
0.0438, 0.0278])

因为我们还没有进行反向计算,所以grad=None

net[2].weight.grad == None

结果是:True

如果把整个网络的参数拿出来,可以这么做

print(*[(name, param.shape) for name, param in net[0].named_parameters()])
print(*[(name, param.shape) for name, param in net.named_parameters()])

因为有两个全连接层,第一层是0,第二个是ReLU没有参数的,拿不出来的,第三个是2。
(‘weight’, torch.Size([256, 20])) (‘bias’, torch.Size([256]))
(‘0.weight’, torch.Size([256, 20])) (‘0.bias’, torch.Size([256])) (‘2.weight’, torch.Size([10, 256])) (‘2.bias’, torch.Size([10]))

4. 内置初始化

如果是全连接层的话,我们就对它的 weight 做均值为0,方差为 0.01的正态分布操作。

def init_normal(m):
    if type(m) == nn.Linear:
        nn.init.normal_(m.weight,mean=0,std=0.01)
        nn.init.zeros_(m.bias)

net.apply(init_normal)
net[0].weight.data[0], net[0].bias.data[0]
  • 12
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
你可以使用PyTorch搭建神经网络。首先,你需要导入相关的库: ```python import torch import torch.nn as nn import torch.optim as optim ``` 然后,你可以定义一个继承自`nn.Module`的类来构建你的神经网络模型。在这个类中,你需要定义网络的结构和前向传播过程。以下是一个简单的例子: ```python class YourModel(nn.Module): def __init__(self): super(YourModel, self).__init__() self.fc1 = nn.Linear(input_size, hidden_size) self.fc2 = nn.Linear(hidden_size, output_size) def forward(self, x): x = torch.relu(self.fc1(x)) x = self.fc2(x) return x ``` 在上面的例子中,`YourModel`类有两个全连接层(`nn.Linear`),分别是`fc1`和`fc2`。在`forward`方法中,输入`x`通过第一个全连接层后使用ReLU激活函数,并经过第二个全连接层输出。 接下来,你可以实例化你的模型,并定义损失函数和优化器: ```python model = YourModel() loss_fn = nn.CrossEntropyLoss() optimizer = optim.SGD(model.parameters(), lr=learning_rate) ``` 在训练过程中,你可以通过向前传播计算输出值,然后计算损失,并通过反向传播更新参数: ```python 假设有输入数据x和标签y output = model(x) loss = loss_fn(output, y) optimizer.zero_grad() loss.backward() optimizer.step() ``` 以上是一个简单PyTorch神经网络搭建的例子,你可以根据自己的需求进行修改和扩展。希望对你有所帮助!如果还有其他问题,请继续提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值