使用PyTorch构建的“感知器”网络

点击关注我哦

一篇文章带你使用PyTorch构建“感知器”网络

PyTorch是一个很棒的深度学习框架,简单易学。本篇文章将带领大家从头开始构建一个“原始”的神经网络。

从某个角度来说,深度学习其实很“烂”,基本上是使用一种随机搜索的方法来找到一种最优解,从而实现某种功能;从另一个角度上来说,深度学习很“棒”,可以做一些令人难以置信的事情。

尽管大家可能已经可以构建一套完整的Imagenet分类器,但是在本篇文章中,我们还是从基础知识讲起。大家最开始学习神经网络的时候,肯定接触过一个概念——感知器。

感知器

从生物学的角度上讲,神经元是大脑的组成部分;但是从神经网络角度上讲:神经元是将加权输入求和并求和以产生一些输出的单位;更有用的是在产生输出之前将非线性函数应用于求和。

首先,我们先import一些常用库函数:

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

然后,我们定义一个只有一个线性神经元的网络:

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.fc1 = nn.Linear(1, 1)


    def forward(self, x):
        x = self.fc1(x)
        return x

该网络包含一个全连接层,具有一个输入和一个输出。现在,该层(从技术上讲是神经元/权重组合)针对输入,将输出Ax + b([权重 * 输入] +偏差),此时它完全是线性的,并没有激活功能。

在网络定义时,我们只需要定义对输入变量的处理方式,而不必担心反向传播过程。毕竟autograd库可以帮助我们完成对variable梯度的跟踪。下列是网络内部的示例:

net = Net()
print(net)
Net (
  (fc1): Linear (1 -> 1)
)

然后可以查看网络的参数,参数由网络自动优化。但是例如学习率之类的超参数需要我们手动进行设置。

print(list(net.parameters()))
[Parameter containing:
1.00000e-02 *
 -6.6961
[torch.FloatTensor of size 1x1]
, Parameter containing:
-0.4478
[torch.FloatTensor of size 1]
]

因此我们的网络初始化时的随机权重为-6.6961e-02,偏差为-0.4478,现在我们对网络进行输入:

input = Variable(torch.randn(1,1,1), requires_grad=True)
print(input)
Variable containing:
(0 ,.,.) = 
 -0.5085
[torch.FloatTensor of size 1x1x1]

上述代码中,我们使用PyTorch创建了一个随机数-0.5085作为网络的输入值,设置require_grad为True,从而表示它是可优化的变量。然后我们可以通过网络学习来计算其来计算其结果:

out = net(input)
print(out)
Variable containing:
(0 ,.,.) = 
 -0.4138
[torch.FloatTensor of size 1x1x1]

手动计算同样可得:(-6.6961e-02 * -0.5085) + -0.4478 = -0.4138。接下来使用随机梯度下降定义损失函数和优化器:

import torch.optim as optim
def criterion(out, label):
    return (label - out)**2
optimizer = optim.SGD(net.parameters(), lr=0.01, momentum=0.5)

在这种情况下,我们定义了自己的损失函数:最小二乘法,其通过最小化误差的平方和确定梯度是向上还是向下进行移动。并设置随机梯度下降的超参数:lr和momentum,便于网络反向传播进行梯度计算和更新。

然后,我们开始定义一个数据集。对于本文,我们只需要教会网络如果将数字增大三倍:我们对于Ax + b的单个感知器的目标是A = 3和b = 0。一个简单的训练数据集如下所示:

data = [(1,3), (2,6), (3,9), (4,12), (5,15), (6,18)]

然后,训练过程如下所示:

for epoch in range(100):
    for i, data2 in enumerate(data):
        X, Y = iter(data2)
        X, Y = Variable(torch.FloatTensor([X]), requires_grad=True), Variable(torch.FloatTensor([Y]), requires_grad=False)
        optimizer.zero_grad()
        outputs = net(X)
        loss = criterion(outputs, Y)
        loss.backward()
        optimizer.step()
        if (i % 10 == 0):
            print("Epoch {} - loss: {}".format(epoch, loss.data[0]))

一段时间后,loss开始收敛至零:

Epoch 0 - loss: 1.0141230821609497 
Epoch 10 - loss: 0.022670941427350044 
Epoch 20 - loss: 0.007926558144390583
...

此时我们的Ax + b已经逼近3x + 0:

print(list(net.parameters()))
[Parameter containing:
 2.9985
[torch.FloatTensor of size 1x1]
, Parameter containing:
1.00000e-03 *
  8.3186
[torch.FloatTensor of size 1]
]

如何做出预测?

print(net(Variable(torch.Tensor([[[1]]]))))
Variable containing:
(0 ,.,.) = 
  3.0068
[torch.FloatTensor of size 1x1x1]

由此可见,网络预测出的结果已经足够接近期望值。

扩展:多层感知器

上述代码仍适用于两层(或更多)网络,我们只需要更改网络的构建方式即可:(注:各层需要在一层输出和下一层输入的数量上匹配)

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.fc1 = nn.Linear(1, 10)
        self.fc2 = nn.Linear(10, 1)
    def forward(self, x):
        x = self.fc2(self.fc1(x))
        return x

使用GPU加速

PyTorch支持轻松地将计算过程转移至GPU,只需使用cuda()将网络和变量转移至GPU即可:

net = Net()
net.cuda()

在训练循环中:

X, Y = Variable(torch.FloatTensor([X]), requires_grad=True).cuda(), Variable(torch.FloatTensor([Y])).cuda()

添加一些非线性元素:

神经网络能起作用,因为每个神经元都有一些非线性。我们可以在构建网络时,添加目前被认为比较好的非线性函数ReLU,以下是代码的相关更改:

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.fc1 = nn.Linear(1,1)
        self.fc2 = nn.Linear(1,1)
    def forward(self, x):
        x = F.relu(self.fc2(F.relu(self.fc1(x))))
        return xcriterion = nn.MSELoss()

·  END  ·

HAPPY LIFE

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PyTorch是一个流行的深度学习框架,可以用于构建多层感知器(MLP)模型。MLP是一种前馈神经网络,由多个全连接层组成。每个层都由一组神经元(或称为节点)组成,其中每个节点都与上一层的所有节点相连。 在PyTorch构建一个MLP模型通常涉及以下步骤: 1. 导入必要的库:导入PyTorch和其他需要的库。 2. 定义模型:使用PyTorch的`nn.Module`类定义一个继承自该类的模型类。在模型类中,你可以定义模型的结构,包括各个层的数量、每个层的大小等。 3. 初始化模型:在模型类的构造函数中,初始化每个层的参数。 4. 前向传播:定义一个`forward`方法,该方法描述了数据从输入到输出的传播过程。在这个方法中,你可以定义每个层的激活函数、连接方式等。 5. 训练模型:使用定义好的模型对数据进行训练。这包括定义损失函数、选择优化器以及执行前向传播和反向传播的步骤。 下面是一个简单的PyTorch多层感知器的示例代码: ```python import torch import torch.nn as nn # 定义模型类 class MLP(nn.Module): def __init__(self, input_size, hidden_size, output_size): super(MLP, self).__init__() self.fc1 = nn.Linear(input_size, hidden_size) # 第一个全连接层 self.relu = nn.ReLU() # 激活函数 self.fc2 = nn.Linear(hidden_size, output_size) # 第二个全连接层 def forward(self, x): x = self.fc1(x) x = self.relu(x) x = self.fc2(x) return x # 初始化模型 input_size = 10 hidden_size = 20 output_size = 2 model = MLP(input_size, hidden_size, output_size) # 使用模型进行训练 # ... ``` 这只是一个简单的示例,你可以根据自己的需求和数据来定义更复杂的MLP模型。希望对你有所帮助!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值