Multilayer Perceptron

以下我们使用Theano来介绍一下单隐藏层的多层感知机(MLP)。MLP能够看成一个logistic回归分类器,它使用一个已经学习的非线性转换器处理输入。这个转换器把输入变成一个线性可分离的空间。中间层被看作是隐藏层

单个隐藏层足够让MLPs普遍逼近,可是我们会在后面看到使用多层隐藏层是非常有效的。

The Model

一个仅仅有单层隐藏层的MLP能够表示成一下形式:

通常地,一个单隐藏层的MLP是一个函数。当中D是输入x的大小,L是输出向量f(x)的大小,f(x)的矩阵表演示样例如以下:



当中偏置项b,权重项W和激活函数G和s。

向量组成了隐藏层。

是一个权值矩阵链接输入层和隐藏层。

每一列代表到第i个隐藏层每个输入的权值。s的传统选择包含tanh函数。。或者sigmoid函数,。本教程我们使用tanh函数由于它训练得更快(有时会达到一个更好的局部最小值).tanh和sigmoid函数都是标量到标量的函数可是它们能够使用元素依次运算自然地扩展到向量或张量。

输出向量是。读者需知道我们之前在前一课的形式。

曾经,类别的成员概率能够被softmax函数来表示。

要训练一个MLP,我们要学习全部的參数,这里我们使用小批量随机下降

要学习的參数集是。使用梯度能够进行后向传播算法

值得感谢的是,Theano会自己主动实现这个过程,这里就不详述。

Going from logistic regression to MLP

本教程会关注单隐藏层的MLP。我们实现一个类来表示一个隐藏层。

为了构造MLP我们将在后面在顶层使用logistic回归层。

class HiddenLayer(object):
def __init__(self, rng, input, n_in, n_out, W=None, b=None, activation=T.tanh):
'''
传统MLP的隐藏层:全链接而且使用sigmoid激活函数。权重矩阵大小为(n_in, n_out)
偏置项b是(n_out,) 提醒:非线性转换器使用tanh 隐藏层单元的激活函数: tanh(dot(input, W) + b) :rng 类型: numpy.random.RandomState
:rng 參数: 随机初始化权值 :input 类型: theano.tensor.dmatrix
:input 參数:符号张量,形状(n_examples, n_in) :n_in 类型: 整数
:n_in 參数: 输入的维数 :n_out 类型: 整数
:n_out 參数: 隐藏层的维数 :activation 类型: theano.Op
:actibation 參数: 应用在隐藏层的非线性
'''
self.input = input

隐藏层权值的初始化须要在相应激活函数的对称区间内抽样。

对于tanh函数。,当中(fan)in是第i-1层单元的数量,(fan)out是第i层单元的数量。对于sigmoid函数。这样初始化保证了在训练的时候,激活函数的神经运算信息能够更easy地前向或者后向传播。

    # 'W'被'W_values'初始化,区间为tanh的[sqrt(-6./(n_in+n_hidden))
# 到 sqrt(6./(n_in+n_hidden))]。
# 定义输出的dtype为theano.config.floatX有利于在GPU上运算。
# 提示:最佳的权值初始化取决于激活函数的使用。 # 比如:[Xavier10]的结果建议你。对照tanh使用4倍大的sigmoid的权重
# 可是我们没有其它函数的信息,所以我们使用和tanh同样的。
if W is None:
W_values = numpy.array(
rng.uniform(
low = -numpy.sqrt(6. / (n_in + n_out)),
high = numpy.sqrt(6. / (n_in + n_out)),
size = (n_in, n_out)
),
dtype = theano.config.floatX
)
if activation == theano.tensor.nnet.sigmoid:
W_values *= 4
W = thenao.shared(value=W_values, name='W', borrow=True)
if b is None:
b_values = numpy.zeros((n_out,), dtype=theano.config.floatX)
b = theano.shared(value=b_values, name='b', borrow=True)
self.W = W
self.b = b

我们使用一个给定的非线性函数当作隐藏层的激活函数。

默认使用tanh。可是有些情况我们会使用其它函数。

    lin_output = T.dot(input, self.W) + self.b
self.output = (
lin_output if activation is None
else activation(lin_output)
)

假设你看过类实现图的理论计算。假设给定这个图当作输入传给之前实现的LogisticRegression类。你会获得MLP的输出。

class MLP(object):
"""Muti-Layer Perceptron Class 一个多层感知机是一个前馈人工神经网络。它有一个或多个隐藏单元和非线性的激活器。
中间层有一个激活函数tanh或者sigmoid函数(HiddenLayer类),另外顶层是一个
softmax层(LogisticRegression)
""" def __init__(self, rng, input, n_in, n_hidden, n_out):
# 当我们处理一个隐藏层,它链接一个激活函数tanh和一个Logistic回归层。
# 激活函数能够被sigmoid函数或其它取代 self.hiddenLayer = HiddenLayer(
rng = rng,
input=input,
n_in=n_in,
n_out=n_hidden,
activation=T.tanh
) # Logistic回归成获得隐藏层的输入
self.logRegressionLayer = LogisticRegression(
input = self.hiddenLayer.output,
n_in = n_hidden,
n_out=n_out
)

本教程我们会使用L1和L2正则

    # L1正则
self.L1 = (
abs(self.hiddenLayer.W).sum()
+ abs(self.logRegressionLayer.W).sum()
) # L2正则
self.L2_sqr = (
(self.hiddenLayer.W ** 2).sum()
+ (self.logRegressionLayer.W ** 2).sum()
) # 负对数似然
self.negative_log_likelihood = (
self.logRegressionLayer.negative_log_likelihood
) # 错误率
self.errors = self.logRegressionLayer.errors # 两层的參数
self.params = self.hiddenLayer.params + self.logRegressionLayer.parmas

在之前。我们用小批量随机下降法来训练模型。不同的是我们使用损失函数是带有L1和L2正则式的。L1_reg和L2_reg是控制权重的正则式。

    cost = (
classifier.negative_log_likelihood(y)
+ L1_reg * classifier.L1
+ L2_reg * classifier.L2_sqr
)

然后我们使用梯度来更新模型的參数。这段代码相似logsitic函数。

仅仅是參数数量不同而已。

为了做到这样(能够执行在不同数量參数的代码),我们会使用參数列表。在每一代计算梯度。

    # 对列表的參数一个个求导
gparams = [T.grad(cost, param) for param in classfier.params] # 约定如何更新权值,形式是(值, 更新表达式)对 # 给定两个同样长度的列表 A=[a1, a2, a3, a4]和
# B = [b1, b2, b3, b4],zip操作生成一个
# C = [(a1, b1), ..., (a4, b4)]
updates = [
(param, param - learning_rate * gparam)
for param, gparam in zip(classifier.params, gparams)
] # 编译一个Theano函数‘train_model’返回损失而且更新权值
train_model = theano.function(
inputs = [index],
outputs = cost,
updates = updates,
givens = {
x: train_set_x[index * batch_size : (index + 1) * batch_size]
y: train_set_y[index * batch_size : (index + 1) * batch_size]
}
)

Putting it All Together

Tips and Tricks for training MLPs

在上面的代码中有一些超參数,它不能用梯度下降来优化。严格来说,找到一个最佳的解集不是一个可行的问题。第一,我们不能独立地优化每个參数。第二,我们不能一下子应用前面说的梯度下降技术(一部分是由于一些參数是离散的。而还有一些是实数的)。第三,优化问题不是一个凸优化,找到一个(局部)最优解会涉及一堆不重要的工作。

在过去的25年里。好消息是研究者在神经网络设计了非常多选择超參数的规则。想了解很多其它能够看Yann LeCun,Leon Bottou,Genevieve Orr和Klaus-Robert的Efficient BackPro。在这里,我们总结一些方法,是一些我们应用在代码中的重点。

Nonlinearity

两个经常使用的方法是sigmoid和tanh。原因在Section 4.4中。非线性在刚開始对称由于它使输入变成平均值为0的输入到下一层。经验告诉我们。tanh有更好地收敛性质。

Weight initialization

在初始化我们想权值在刚開始时足够小,那样的话激活函数的运算就会在线性工作状态,这样导数最大。

另外合适的性质,特别在深度网络。是保存激活器的方差和层与层之间的反向传播梯度的方差。这同意信息在向上和向下都非常好地流动,降低层之间的差异。

在某些假设下,两个限制的妥协导致了以下的初始化方式:

tanh初始化权值

sigmoid初始化权值

数学推导请看Xavier10

Learning rate

在文献上有好的处理方法。

最简单的方法就是常数学习率。

经验法则是:尝试几个对数空间值(10的-1。 10的-2, …)和缩小(对数的)格子去搜索哪里获得最小检验错误。

多次降低学习率有时是一个非常好的方法。

一个简单的规则就是,当中u0是初始学习率,d是下降常数来控制下降速度(通常一个小的正数,10的-3或更小),t是epoch/stage。

Section 4.7參看很多其它信息。

Number of hidden units

超參数非常依赖于数据集。

含糊地说。输入的分布越复杂,网络要建模的能力越强。就须要越多的隐藏层。

除非我们使用正则化,典型数量的隐藏层 vs. 泛化表现就像一个U字。

Regularization parameter

经典的方法就是使用L1/L2正则參数,10的-2。10的-3, …,在以后的框架里,优化这个參数不会带来什么显著的变化。可是有时也值得尝试。

deeplearning.net 0.1 document - Multilayer Perceptron的更多相关文章

  1. Deep Learning Tutorial - Multilayer perceptron

    Multilayer perceptron:多层感知器 本节实现两层网络(一个隐层)作为分类器实现手写数字分类.引入的内容:激活函数(双曲正切.L1和L2正则化).Theano的共享变量.grad.f ...

  2. Spark Multilayer perceptron classifier (MLPC)多层感知器分类器

    多层感知器分类器(MLPC)是基于前馈人工神经网络(ANN)的分类器. MLPC由多个节点层组成. 每个层完全连接到网络中的下一层. 输入层中的节点表示输入数据. 所有其他节点,通过输入与节点的权重w ...

  3. 利用Theano理解深度学习——Multilayer Perceptron

    一.多层感知机MLP 1.MLP概述 对于含有单个隐含层的多层感知机(single-hidden-layer Multi-Layer Perceptron, MLP),可以将其看成是一个特殊的Logi ...

  4. MLPclassifier,MLP 多层感知器的的缩写(Multi-layer Perceptron)

    先看代码(sklearn的示例代码): from sklearn.neural_network import MLPClassifier X = [[0., 0.], [1., 1.]] y = [0 ...

  5. 将h5用HBuilderX打包成安卓app后,document.documentElement.scrollTop的值始终为0或者document.body.scrollTop始终为0

    let time = setInterval(() => { let scroll = document.documentElement.scrollTop || document.body.s ...

  6. 深度学习文档 DeepLearning 0.1 documentation

    Contents LICENSE Deep Learning Tutorials Getting Started Download Datasets Notation A Primer on Supe ...

  7. DeepLearning之路(三)MLP

    DeepLearning tutorial(3)MLP多层感知机原理简介+代码详解 @author:wepon @blog:http://blog.csdn.net/u012162613/articl ...

  8. DeepLearning tutorial(3)MLP多层感知机原理简介+代码详解

    本文介绍多层感知机算法,特别是详细解读其代码实现,基于python theano,代码来自:Multilayer Perceptron,如果你想详细了解多层感知机算法,可以参考:UFLDL教程,或者参 ...

  9. Apache Spark 2.2.0新特性介绍(转载)

    这个版本是 Structured Streaming 的一个重要里程碑,因为其终于可以正式在生产环境中使用,实验标签(experimental tag)已经被移除.在流系统中支持对任意状态进行操作:A ...

随机推荐

  1. this.$router.push() 在新窗口怎么打开

    参考:https://blog.csdn.net/qyl_0316/article/details/86550361

  2. BZOJ1709超级弹珠

    1709: [Usaco2007 Oct]Super Paintball超级弹珠 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 352  Solved:  ...

  3. 利用$.getJSON() 跨域请求操作

    原文发布时间为:2011-01-14 -- 来源于本人的百度文章 [由搬家工具导入] $.get 没有权限? $.post 没有权限? 因为他们都不能跨域,那就用 $.getJSON() 吧 利用$. ...

  4. 调试UPX压缩的notepad

    @date: 2016/11/29 @author: dlive 0x01 运行时压缩 对比upx压缩前后的notepad可以看到如下特点 PE头的大小一样 节区名称改变(.text -> .U ...

  5. [java]编程的智慧(转)

    编程是一种创造性的工作,是一门艺术.精通任何一门艺术,都需要很多的练习和领悟,所以这里提出的“智慧”,并不是号称一天瘦十斤的减肥药,它并不能代替你自己的勤奋.然而由于软件行业喜欢标新立异,把简单的事情 ...

  6. 如何得知 GIC 的所有中斷

    can get the supported GIC interrupts from the below adb command, adb root adb shell cat /proc/interr ...

  7. linux(debian)安装USB无线网卡(tp-link TL-WN725N rtl8188eu )

    1: 台式机家里面不想再走线了. 于是去某东买了个USB无线网卡.tp的WN725N  USB,非常小, 和罗技的优联接收器差不多大. 2:  驱动能自己识别是不指望了,既然是usb网卡,插入USB后 ...

  8. C#byte怎么转成图片

    这个其实很简单我给大家提供一个方法吧 /// <summary> /// 字节数组生成图片 /// </summary> /// <param name="By ...

  9. LeetCode OJ--Linked List Cycle **

    https://oj.leetcode.com/problems/linked-list-cycle/ 判断一个链表是否为循环链表(这个链表可能是 1 2 3 4 然后4指向2) 巧妙的方法:设置两个 ...

  10. 10.1综合强化刷题 Day3 morning

    竞赛时间:????年??月??日??:??-??:?? 题目名称 a b c 名称 a b c 输入 a.in b.in c.in 输出 a.out b.out c.out 每个测试点时限 1s 1s ...