用PyTorch实现多层网络:从感知机到多层神经网络

神经网络中有许多的名词,比如MLP\ANN\CNN\RNN\DNN等,在文章开始之前先给出一个大致说明,免得像我一样为了区分多层感知机(MLP)与多层神经网络的概念搜索半天资料。

首先,深度前馈网络(deep feedforward network),也叫做前馈神经网络(feedforward neural network)或者多层感知机(Multilayer Perceptron,MLP),多层感知机(MLP)又叫人工神经网络(Artificial Neural Network,ANN),是典型的深度学习模型。其次,我觉得多层神经网络是一个很广泛的概念,所有那些具有较多隐藏层/中间层的神经网络都可以成为多层神经网络,还有一个深度神经网络(DNN)的概念,我觉得它就是多层神经网络。最后,卷积神经网络(CNN)和循环神经网络(RNN)是两种对简单全连接神经网络的传播过程进行设计的特殊/专业神经网络,这两种神经网络以后学习到时会介绍,这里就不具体说明了。
所以,感知机模型如果中间有很多隐藏层的话,也就属于多层神经网络。

对于神经网络的众多名称,‘花书’是这样说明的,“这个领域已经更换了很多名字,它反映了不同的研究人员和不同观点的影响。同时也因为它被赋予了许多不同的名称(其中大部分已经不在使用),最近才成为众所周知的深度学习”。

概念理解

感知机

感知机(perceptron)是二分类的线性分类模型,输入为实例的特征向量,输出为实例的类别(取+1和-1)。感知机对应于输入空间中将实例划分为两类的分离超平面。感知机旨在求出该超平面,为求得超平面导入了基于误分类的损失函数,利用梯度下降法 对损失函数进行最优化(最优化)。
从神经网络模型的角度看,感知机是最简单的分类模型。

多层感知机

多层感知器(Multilayer Perceptron,缩写MLP)是一种前向结构的人工神经网络,映射一组输入向量到一组输出向量。MLP可以被看作是一个有向图,由多个的节点层所组成,每一层都全连接到下一层。除了输入节点,每个节点都是一个带有非线性激活函数的神经元(或称处理单元)。一种被称为反向传播算法的监督学习方法(BP算法)常被用来训练MLP。
MLP是一种非线性分类器,传统的感知机模型是两层的NN,是线性的,而MLP是三层及以上的NN,就可以实现非线性任务,比如三层的MLP可以实现异或(XOR)问题。
多层感知机的层与层之间是全连接的,即每一层的任意一个神经元均与其前一层的所有神经元有连接,这种连接其实代表了一种权重加和。

上面这样对感知机与多层感知机的解释很简短明了,但是对很多初学者很不友好,所以我找到一篇文章从多层感知器到卷积网络(一)来一起食用。文章作者白话的非常清楚,从神经网络的原来讲起,介绍简单且广泛,另外神经网络中最基本的神经元与反向传播在文中配图介绍。

激活函数

从上面的介绍我们已经直到,神经元是神经网络的基本单元,除了输入节点,每个节点都是一个带有非线性激活函数的神经元。那么为什么需要激活函数,激活函数又是什么?以下进行简单说明。

不管是单层感知机还是多个感知器,只要不带激活函数,都只能解决线性可分的问题,解决不了线性不可分问题。激活函数是用来加入非线性因素的,提高神经网络对模型的表达能力,使得神经网络可以更好地解决较为复杂的问题。

激活函数(Activation Function),就是作用在人工神经网络的神经元上函数,负责将inputs加权求和后的输入映射到输出端。

常见的激活函数有:函数图形可见深度学习笔记六:常见激活函数总结
以下列出常见的四种。

  • Sigmoid(S型激活函数,将输入映射到一个0到1之间的值)
  • tanh(双曲正切函数,将输入映射到一个-1到1之间的值)
  • ReLU(近似生物神经激活函数)
f(x)=max(0,x)
  • Softmax(在多分类中常用的激活函数,是基于逻辑回归的。)

pytorch实现

import torch
from torch.autograd import Variable

# 一定要继承 nn.Module
class TwoLayerNet(nn.Module):
    def __init__(self, input_size, hidden_size, output_size):
        super(TwoLayerNet, self).__init__()
        self.twolayernet = nn.Sequential(
            nn.Linear(input_size, hidden_size),
            nn.ReLU(),
            nn.Linear(hidden_size, output_size),
        )

    def forward(self, x):
        y_pred = self.twolayernet(x)
        return y_pred

# M是样本数量,input_size是输入层大小, hidden_size是隐含层大小,output_size是输出层大小
M, input_size, hidden_size, output_size = 64, 1000, 100, 10

# 生成随机数当作样本
x = Variable(torch.randn(M, input_size))
y = Variable(torch.randn(M, output_size))

model = TwoLayerNet(input_size, hidden_size, output_size)

# 定义损失函数
loss_fn = nn.MSELoss(size_average=False)

learning_rate = 1e-4
EPOCH = 300

# 使用optim包来定义优化算法
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)

for t in range(EPOCH):    
    y_pred= model(x)
    loss = loss_fn(y_pred, y)
    if (t+1) % 50 == 0:
        print(loss.data[0])
    
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

参考:
“花书”《深度学习》
系统学习深度学习(九)–激活函数总结
神经网络激活函数的作用是什么?
深度学习:神经网络中的激活函数
https://github.com/LianHaiMiao/pytorch-lesson-zh/blob/master/basis/4、多层感知机.ipynb

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章