感知机+激活函数+多层感知机的实现

Posted 彭祥.

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了感知机+激活函数+多层感知机的实现相关的知识,希望对你有一定的参考价值。

单层感知机一般用于处理二分类问题

1.多层感知机

相较于softmax回归,其只是多加了一个隐藏层

可以通过在网络中加入一个或多个隐藏层来克服线性模型的限制, 使其能处理更普遍的函数关系类型。 要做到这一点,最简单的方法是将许多全连接层堆叠在一起。 每一层都输出到上面的层,直到生成最后的输出。 我们可以把前层看作表示,把最后一层看作线性预测器。 这种架构通常称为多层感知机(multilayer perceptron),通常缩写为MLP

多层感知机可以通过隐藏神经元,捕捉到输入之间复杂的相互作用, 这些神经元依赖于每个输入的值。 我们可以很容易地设计隐藏节点来执行任意计算。 例如,在一对输入上进行基本逻辑操作,多层感知机是通用近似器。 即使是网络只有一个隐藏层,给定足够的神经元和正确的权重, 我们可以对任意函数建模,尽管实际中学习该函数是很困难的。 你可能认为神经网络有点像C语言。 C语言和任何其他现代编程语言一样,能够表达任何可计算的程序。 但实际上,想出一个符合规范的程序才是最困难的部分。
而且,虽然一个单隐层网络能学习任何函数, 但并不意味着我们应该尝试使用单隐藏层网络来解决所有问题。 事实上,通过使用更深(而不是更广)的网络,我们可以更容易地逼近许多函数

2.激活函数

激活函数(activation function)通过计算加权和并加上偏置来确定神经元是否应该被激活, 它们将输入信号转换为输出的可微运算。 大多数激活函数都是非线性的

2.1ReLU函数

最受欢迎的激活函数是修正线性单元(Rectified linear unit,ReLU), 因为它实现简单,同时在各种预测任务中表现良好。 ReLU提供了一种非常简单的非线性变换。 给定元素x,ReLU函数被定义为该元素与0的最大值:

通俗地说,ReLU函数通过将相应的活性值设为0,仅保留正元素并丢弃所有负元素。 为了直观感受一下,我们可以画出函数的曲线图。 正如从图中所看到,激活函数是分段线性的。

2.2sigmoid函数

对于一个定义域在中的输入, sigmoid函数将输入变换为区间(0, 1)上的输出。 因此,sigmoid通常称为挤压函数(squashing function): 它将范围(-inf, inf)中的任意输入压缩到区间(0, 1)中的某个值:



sigmoid函数的导数图像如下所示。 注意,当输入为0时,sigmoid函数的导数达到最大值0.25; 而输入在任一方向上越远离0点时,导数越接近0。

2.3tanh函数

与sigmoid函数类似, tanh(双曲正切)函数也能将其输入压缩转换到区间(-1, 1)上。 tanh函数的公式如下:


tanh函数的导数图像如下所示。 当输入接近0时,tanh函数的导数接近最大值1。 与我们在sigmoid函数图像中看到的类似, 输入在任一方向上越远离0点,导数越接近0。


总结

多层感知机通过激活函数和隐藏层来得到非线性模型
常用的激活函数有sigmoid,Tanh,ReLU
使用SoftMax处理多类分类

3.多层感知机的实现

import torch
from torch import nn
from d2l import torch as d2l
#引入数据,我们仍使用Fashion-MNIST图像分类数据集
batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)
#初始化模型参数
num_inputs, num_outputs, num_hiddens = 784, 10, 256
W1 = nn.Parameter(torch.randn(
    num_inputs, num_hiddens, requires_grad=True) * 0.01)
b1 = nn.Parameter(torch.zeros(num_hiddens, requires_grad=True))
W2 = nn.Parameter(torch.randn(
    num_hiddens, num_outputs, requires_grad=True) * 0.01)
b2 = nn.Parameter(torch.zeros(num_outputs, requires_grad=True))
params = [W1, b1, W2, b2]
def relu(X):
    a = torch.zeros_like(X)
    return torch.max(X, a)
def net(X):
    X = X.reshape((-1, num_inputs))#这里-1代表我不知道行数,即按照原本的数据分成784列,能分多少行分多少行,这里X由于一次性读入256行,则有256行
    H = relu(X@W1 + b1)  # 这里“@”代表矩阵乘法
    return (H@W2 + b2)
#损失函数
loss = nn.CrossEntropyLoss(reduction='none')
#训练模型
from matplotlib import pyplot as pil
num_epochs, lr = 10, 0.1
updater = torch.optim.SGD(params, lr=lr)
pil.axes=d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, updater)
pil.show()
pil.axes=d2l.predict_ch3(net, test_iter)
pil.show()


4.多层感知机简洁实现

import torch
from torch import nn
from d2l import torch as d2l
net = nn.Sequential(nn.Flatten(),
                    nn.Linear(784, 256),
                    nn.ReLU(),
                    nn.Linear(256, 10))

def init_weights(m):
    if type(m) == nn.Linear:
        nn.init.normal_(m.weight, std=0.01)

net.apply(init_weights)
from matplotlib import pyplot as pil
batch_size, lr, num_epochs = 256, 0.1, 10
loss = nn.CrossEntropyLoss(reduction='none')
trainer = torch.optim.SGD(net.parameters(), lr=lr)

pil.axes=train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)
pil.show()
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, trainer)

以上是关于感知机+激活函数+多层感知机的实现的主要内容,如果未能解决你的问题,请参考以下文章

多层感知机的从零开始实现( 从D2L 包中抽取函数)

多层感知机的从零开始实现( 从D2L 包中抽取函数)

多层感知机

PyTorch如何实现多层全连接神经网络

感知机的梯度推导

神经网络多层感知机