首页 > 其他分享 >利用Theano理解深度学习——Multilayer Perceptron

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

时间:2023-06-14 21:04:04浏览次数:48  
标签:函数 Multilayer self MLP Theano validation Perceptron 模型 out


一、多层感知机MLP

1、MLP概述

对于含有单个隐含层的多层感知机(single-hidden-layer Multi-Layer Perceptron, MLP),可以将其看成是一个特殊的Logistic回归分类器,这个特殊的Logistic回归分类器首先通过一个非线性变换利用Theano理解深度学习——Multilayer Perceptron_权重(non-linear transformation)对样本的输入进行非线性变换,然后将变换后的值作为Logistic回归的输入。非线性变换的目的是将输入的样本映射到一个空间,在该空间中,这些样本是线性可分的。这个中间层我们称之为隐含层(a hidden layer)。

A single hidden layer is sufficient to make MLPs a universal approximator.

2、MLP模型

对于含有单隐层的MLP模型(也可以称为人工神经网络,ANN)可以由下图表示:

利用Theano理解深度学习——Multilayer Perceptron_线性变换_02

在上图中,对于含有一个隐含层的MLP可以表示为:

利用Theano理解深度学习——Multilayer Perceptron_线性变换_03

其中,利用Theano理解深度学习——Multilayer Perceptron_权重_04指的是输入向量利用Theano理解深度学习——Multilayer Perceptron_Theano_05的大小,利用Theano理解深度学习——Multilayer Perceptron_深度学习_06表示的是输出向量利用Theano理解深度学习——Multilayer Perceptron_Theano_07的大小,输出向量利用Theano理解深度学习——Multilayer Perceptron_Theano_07可以表示为:

利用Theano理解深度学习——Multilayer Perceptron_Theano_09

其中,利用Theano理解深度学习——Multilayer Perceptron_线性变换_10利用Theano理解深度学习——Multilayer Perceptron_权重_11是偏置,利用Theano理解深度学习——Multilayer Perceptron_深度学习_12利用Theano理解深度学习——Multilayer Perceptron_激活函数_13是权重矩阵,利用Theano理解深度学习——Multilayer Perceptron_深度学习_14利用Theano理解深度学习——Multilayer Perceptron_Theano_15是激活函数。

隐含层的输出为利用Theano理解深度学习——Multilayer Perceptron_深度学习_16利用Theano理解深度学习——Multilayer Perceptron_Theano_17是输入层到隐含层的权重向量,利用Theano理解深度学习——Multilayer Perceptron_深度学习_12中的每一列代表从输入单元到第利用Theano理解深度学习——Multilayer Perceptron_深度学习_19个隐含单元的权重。对于激活函数利用Theano理解深度学习——Multilayer Perceptron_深度学习_14,可以使用tanh或者sigmoid函数,其中,tanh函数为:

利用Theano理解深度学习——Multilayer Perceptron_深度学习_21

sigmoid函数为:

利用Theano理解深度学习——Multilayer Perceptron_深度学习_22

选择激活函数tanh有时具有更快的训练速度和训练精度

输出向量为利用Theano理解深度学习——Multilayer Perceptron_Theano_23。(在下面的程序中利用Theano理解深度学习——Multilayer Perceptron_Theano_15选择的是sigmoid函数,类似于Logistic Regression的多类别分类)。

3、MLP模型的训练

为了训练处MLP模型中的所有参数,可以使用带mini-batch的随机梯度下降法。需要学习的参数为:

利用Theano理解深度学习——Multilayer Perceptron_权重_25

在这里,要获得梯度利用Theano理解深度学习——Multilayer Perceptron_线性变换_26可以使用backpropagation algorithm,这是一个链式求导的法则。

二、Tips和Tricks

在代码中存在着很多的超参数,有些参数的选择是不能通过梯度下降法得到的。严格来讲,这些超参数的最优解是不可解的。首先,我们不能单独的优化每一个超参数。其次,我们不能直接使用梯度下降法,因为有些超参数是离散的,有些超参数是连续的。最后,这是非凸优化问题,找到一个局部最优解需要花费很大的功夫。

在过去的25年中,研究者们已经设计出大量的经验法则用于在一个神经网络中选择超参数。

1、非线性变换

两个最常见的非线性函数是sigmoid函数和tanh函数。其中,tanh函数的形式为:

利用Theano理解深度学习——Multilayer Perceptron_深度学习_21

sigmoid函数的形式为:

利用Theano理解深度学习——Multilayer Perceptron_深度学习_22

对于非线性变换的选择,通常是选择关于原点对称的非线性变换。这是因为具有这样特性的变换能够为下一层产生零均值的输入。[Nonlinearities that are symmetric around the origin are preferred because they tend to produce zero-mean inputs to the next layer (which is a desirable property)].

从经验上看,tanh函数具有更好的收敛性。

2、权重向量的初始化

在初始化阶段,我们希望权重在原点的周围,而且尽可能的小,这样,激活函数对其进行操作就像是线性函数,此处的梯度也是最大的。

At initialization we want the weights to be small enough around the origin so that the activation function operates in its linear regime, where gradients are the largest. Other desirable properties, especially for deep networks, are to conserve variance of the activation as well as variance of back-propagated gradients from layer to layer.

对于tanh激活函数,权重的激活方法为在区间:

利用Theano理解深度学习——Multilayer Perceptron_激活函数_29

上以均匀分布的方式产生随机数。而对于sigmoid激活函数,则是在区间:

利用Theano理解深度学习——Multilayer Perceptron_权重_30

上以均匀分布的方式产生随机数。其中,利用Theano理解深度学习——Multilayer Perceptron_激活函数_31利用Theano理解深度学习——Multilayer Perceptron_深度学习_32层节点的个数,而利用Theano理解深度学习——Multilayer Perceptron_激活函数_33利用Theano理解深度学习——Multilayer Perceptron_深度学习_19层节点的个数。

3、学习率

有很多文章在讲如何选择一个好的学习率。最简单的办法是选择一个固定的学习率,即常数。经验法则:尝试一些对数空间的数,如利用Theano理解深度学习——Multilayer Perceptron_Theano_35和通过网格搜索(grid search)不断缩小对数值以获得最小的验证误差。

随着代数不断减小学习率是一个很好的想法,一个简单的做法是:

利用Theano理解深度学习——Multilayer Perceptron_Theano_36

其中,利用Theano理解深度学习——Multilayer Perceptron_激活函数_37是初始的学习率(可以通过上述的网格搜索的办法取得),利用Theano理解深度学习——Multilayer Perceptron_Theano_38称为减少常数(decrease constant),控制着学习率的下降速度,通常是一个很小的正数,如利用Theano理解深度学习——Multilayer Perceptron_深度学习_39或者更小。利用Theano理解深度学习——Multilayer Perceptron_激活函数_40是epoch/stage。

4、隐含层节点的个数

这个超参数在很大程度上是取决于数据集的。笼统的说,对于越复杂的数据分布,神经网络需要越强的能力去对这批数据建模,因此,需要越多的隐含层节点个数。

除非我们使用一些正则化的策略,例如early stopping或者利用Theano理解深度学习——Multilayer Perceptron_线性变换_41惩罚,隐含层节点个数与泛化能力在图上表现为U字形的。

5、正则化参数

对于利用Theano理解深度学习——Multilayer Perceptron_激活函数_42或者利用Theano理解深度学习——Multilayer Perceptron_权重_43正则的参数$\lambda $有一些经验值,如利用Theano理解深度学习——Multilayer Perceptron_Theano_35

三、基于Theano的MLP实现解析

在利用Theano实现单隐层的MLP的过程中,主要分为如下几个步骤:

  1. 导入数据集
  2. 建立模型
  3. 训练模型
  4. 利用模型进行预测
    接下来,对每个部分的代码进行解析。

1、导入数据集

导入数据集的代码部分与利用Theano理解深度学习——Logistic Regression中一致,就不再细说。

2、建立模型

在实现的过程中,可以将单隐层的MLP想像成LR模型中增加了一个隐含层,故在实现的过程中使用到了LR中的LogisticRegression类。此外,还增加了一个MLP类和HiddenLayer类。其中,MLP类是整个MLP算法的模型,具体的代码如下:

class MLP(object):
	"""含单隐层的多层感知机类
	多层感知机是一个前馈人工神经网络模型,该模型有一个或者多个隐含层单元和非线性的激活函数。
	隐层层单元在“HiddenLayer”类中定义
	顶层是一个softmax层,在“LogisticRegression”类中定义
	"""
	def __init__(self, rng, input, n_in, n_hidden, n_out):
    	"""初始化参数
    	:type rng: numpy.random.RandomState
    	:param rng: 随机数生成器,用于随机生成权重

    	:type input: theano.tensor.TensorType
    	:param input: 符号,用于表示输入

    	:type n_in: int
    	:param n_in: 输入单元的个数

    	:type n_hidden: int
    	:param n_hidden: 隐含层单元的个数

    	:type n_out: int
    	:param n_out: 输出层单元的个数
    	"""

    	# 输入层到单个隐含层的初始化
    	self.hiddenLayer = HiddenLayer(
        	rng=rng,#随机数生成器
        	input=input,#输入
        	n_in=n_in,#输入层的节点个数
        	n_out=n_hidden,#输出层的节点个数
        	activation=T.tanh#激活函数
    	)

    	# 隐含层到输出层的初始化
    	self.logRegressionLayer = LogisticRegression(
        	input=self.hiddenLayer.output,
        	n_in=n_hidden,
        	n_out=n_out
    	)
    	# 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
    	)
    	# 用于计算validation和testing的错误率
    	self.errors = self.logRegressionLayer.errors
    	# 声明所有的参数
    	self.params = self.hiddenLayer.params + self.logRegressionLayer.params
    	#声明输入
    	self.input = input

MLP类中主要的部分包括声明输入层到隐含层以及隐含层到输出层的结构,正则化的方法以及损失函数的定义和模型中的主要参数。在MLP类中使用到了HiddenLayer类和LogisticRegression类。其中HiddenLayer类用于定义隐含层的结构以及基本操作,LogisticRegression类用于定义输出层的结构以及基本操作,LogisticRegression类在利用Theano理解深度学习——Logistic Regression已经解析过,下面是HiddenLayer类的代码:

class HiddenLayer(object):
	def __init__(self, rng, input, n_in, n_out, W=None, b=None, activation=T.tanh):
    	"""在MLP中,典型的隐含层中的节点是全连接的,使用的是sigmoid激活函数,权重矩阵W的大小为(n_in, n_out),
    	偏置向量b的大小为(n_out,)。在这里激活函数使用的是tanh
    	:type rng: numpy.random.RandomState
    	:param rng: 用于生成权重的随机数生成器

    	:type input: theano.tensor.dmatrix
    	:param input: 符号,输入

    	:type n_in: int
    	:param n_in: 输入层的节点个数

    	:type n_out: int
    	:param n_out: 输出层的节点个数

    	:type activation: theano.Op or function
    	:param activation: 激活函数的类型
    	"""
    	self.input = input
    
    	if W is None:
        	'''对于权重矩阵W中的元素的初始化,若使用的激活函数是tanh,则使用均匀分布在区间[sqrt(-6./(n_in+n_hidden)),sqrt(6./(n_in+n_hidden))]上生成。
        	权重矩阵的初始化与选择的激活函数是相关联的。若使用sigmoid激活函数,则生成的数是tanh激活函数的4倍。
        	'''
        	W_values = numpy.asarray(
            	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 = theano.shared(value=W_values, name='W', borrow=True)

    	if b is None:
        	'''对于偏置向量b的初始化,使用的是全部初始化为0
        	'''
        	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

    	lin_output = T.dot(input, self.W) + self.b#线性的输出
    	#判断是选择线性的激活函数还是非线性的激活函数
    	self.output = (
        	lin_output if activation is None
        	else activation(lin_output)
    	)
    	# 声明模型中的参数
    	self.params = [self.W, self.b]

在定义好上述的结构之后就可以建立模型,详细的代码如下:

#2、建立模型
print '... building the model'
# 分配全局的符号
index = T.lscalar()  # 用于指示batch
x = T.matrix('x')
y = T.ivector('y')

rng = numpy.random.RandomState(1234)#随机数生成器

# 构造函数
classifier = MLP(
    rng=rng,#随机数生成器
    input=x,#输入
    n_in=28 * 28,#输入的节点个数
    n_hidden=n_hidden,#隐含层节点个数
    n_out=10#输出的节点个数
)

# 在训练的时候,所有的损失是损失函数+L1正则+L2正则
cost = (
    classifier.negative_log_likelihood(y)
    	+ L1_reg * classifier.L1
    	+ L2_reg * classifier.L2_sqr
)

#构造验证模型的函数
validate_model = theano.function(
    inputs=[index],#输入为batch的索引
    outputs=classifier.errors(y),#输出为每个batch上的错误率
    givens={#x:样本,y:标签
        x: valid_set_x[index * batch_size:(index + 1) * batch_size],
        y: valid_set_y[index * batch_size:(index + 1) * batch_size]
    }
)

# 对每一个参数求偏导数
gparams = [T.grad(cost, param) for param in classifier.params]

# 更新规则
updates = [
    (param, param - learning_rate * gparam)
    for param, gparam in zip(classifier.params, gparams)
]

# 训练模型的函数
train_model = theano.function(
    inputs=[index],#输入为batch的索引
    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]
    }
)

1、正则化方法

正则化方法是防止模型过拟合(overfitting)的重要的方法,模型过拟合是指训练出来的模型在训练集上表现的很好,但是在未知的数据集上表现较差。在前面的LR的模型训练中,我们没有考虑到正则项,只是使用到了early-stopping策略。在这里我们考虑L1和L2正则。

L1和L2正则是指在损失函数的基础上增加一个额外的正则项,这个正则项的目的是为了对模型中的参数进行惩罚。若损失函数如下所示:

利用Theano理解深度学习——Multilayer Perceptron_线性变换_45

则加入正则项的损失函数就变成:

利用Theano理解深度学习——Multilayer Perceptron_权重_46

其中,利用Theano理解深度学习——Multilayer Perceptron_线性变换_47

这里

利用Theano理解深度学习——Multilayer Perceptron_激活函数_48

2、权重 W W W的初始化

在权重的初始化过程中,我们希望权重的初始值在原点的附近。一些经验的做法是对于激活函数为tanh的情况下,权重的激活方法为在区间:

利用Theano理解深度学习——Multilayer Perceptron_激活函数_29

上以均匀分布的方式产生随机数。而对于sigmoid激活函数,则是在区间:

利用Theano理解深度学习——Multilayer Perceptron_权重_30

上以均匀分布的方式产生随机数。其中,利用Theano理解深度学习——Multilayer Perceptron_激活函数_31利用Theano理解深度学习——Multilayer Perceptron_深度学习_32层节点的个数,而利用Theano理解深度学习——Multilayer Perceptron_激活函数_33利用Theano理解深度学习——Multilayer Perceptron_深度学习_19层节点的个数。

3、激活函数的选择

在本程序中,主要牵涉到的激活函数有两个,一个是tanh函数,另一个是sigmoid函数。其中,tanh函数的形式为:

利用Theano理解深度学习——Multilayer Perceptron_深度学习_21

sigmoid函数的形式为:

利用Theano理解深度学习——Multilayer Perceptron_深度学习_22

3、训练模型

训练模型的具体代码如下:

#3、训练模型
print '... training'
# early-stopping参数
patience = 10000
patience_increase = 2
improvement_threshold = 0.995
validation_frequency = min(n_train_batches, patience / 2)

best_validation_loss = numpy.inf
best_iter = 0
start_time = timeit.default_timer()

epoch = 0
done_looping = False

while (epoch < n_epochs) and (not done_looping):
    epoch = epoch + 1
    for minibatch_index in xrange(n_train_batches):

        minibatch_avg_cost = train_model(minibatch_index)
        # iteration number
        iter = (epoch - 1) * n_train_batches + minibatch_index

        if (iter + 1) % validation_frequency == 0:
            # compute zero-one loss on validation set
            validation_losses = [validate_model(i) for i
                                 in xrange(n_valid_batches)]
            this_validation_loss = numpy.mean(validation_losses)

            print(
                'epoch %i, minibatch %i/%i, validation error %f %%' %
                (
                    epoch,
                    minibatch_index + 1,
                    n_train_batches,
                    this_validation_loss * 100.
                )
            )

            if this_validation_loss < best_validation_loss:
                if (
                    this_validation_loss < best_validation_loss *
                    improvement_threshold
                ):
                    patience = max(patience, iter * patience_increase)

                best_validation_loss = this_validation_loss
                best_iter = iter                    

        if patience <= iter:
            done_looping = True
            break


end_time = timeit.default_timer()
print(('Optimization complete. Best validation score of %f %% '
       'obtained at iteration %i') %
      (best_validation_loss * 100., best_iter + 1))
print >> sys.stderr, ('The code for file ' +
                      os.path.split(__file__)[1] +
                      ' ran for %.2fm' % ((end_time - start_time) / 60.))

4、利用模型进行预测

这部分的代码主要是将训练好的模型应用在新的测试数据集上,具体的代码如下:

'''增加了一段预测的代码
'''
# 4、利用模型进行预测
predict_model = theano.function(
    inputs=[classifier.input],
    outputs=classifier.logRegressionLayer.y_pred)

test_set_x = test_set_x.get_value()

predicted_values = predict_model(test_set_x[:10])#进行预测
print ("Predicted values for the first 10 examples in test set:")
print predicted_values

参考文献

Deep Learning Tutorialshttp://www.deeplearning.net/tutorial/


标签:函数,Multilayer,self,MLP,Theano,validation,Perceptron,模型,out
From: https://blog.51cto.com/u_16161414/6481060

相关文章

  • 利用Theano理解深度学习——Auto Encoder
    注:本系列是基于参考文献中的内容,并对其进行整理,注释形成的一系列关于深度学习的基本理论与实践的材料,基本内容与参考文献保持一致,并对这个专题起名为“利用Theano理解深度学习”系列,若文中有任何问题欢迎咨询。本文提供PDF版本,欢迎索取。“利用Theano理解深度学习”系列分为个部分,......
  • 感知机(Perceptrons)—人工神经元
    1957年科学家FrankRosenblatt开发了感知机这一人工神经元。感知机由两层神经元组成,输入层接收样本的特征,输出层产生样本的二进制类别。虽然现在大家主要是应用sigmoid神经元,仍然有必要对感知机的原理进行理解以明白sigmoid由来。工作原理假设我们有m个样本,每个样本有n个特征......
  • Theano 中文文档 0.9 - 2. 发行说明
    2.发行说明译者:Python文档协作翻译小组,原文:ReleaseNotes。本文以CCBY-NC-SA4.0协议发布,转载请保留作者署名和文章出处。Python文档协作翻译小组人手紧缺,有兴趣的朋友可以加入我们,完全公益性质。交流群:467338606。Theano0.8.2(2016年4月21日)这是一个小版本的发布,只支持cudnn......
  • Theano 中文文档 0.9 - 7.1.1 Python教程
    7.1.1Python教程译者:Python文档协作翻译小组,原文:Pythontutorial。本文以CCBY-NC-SA4.0协议发布,转载请保留作者署名和文章出处。Python文档协作翻译小组人手紧缺,有兴趣的朋友可以加入我们,完全公益性质。交流群:467338606。在本文档中,我们假设读者了解Python。如果你需要学习......
  • Theano 中文文档 0.9 - 7.2.2 更多示例
    7.2.2更多示例译者:Python文档协作翻译小组,原文:MoreExamples。本文以CCBY-NC-SA4.0协议发布,转载请保留作者署名和文章出处。Python文档协作翻译小组人手紧缺,有兴趣的朋友可以加入我们,完全公益性质。交流群:467338606。现在开始,通过浏览库的BasicTensorFunctionality这一部......
  • Theano 中文文档 0.9 - 7.1.2 NumPy新手
    7.1.2NumPy新手译者:Python文档协作翻译小组,原文:NumPyrefresher。本文以CCBY-NC-SA4.0协议发布,转载请保留作者署名和文章出处。Python文档协作翻译小组人手紧缺,有兴趣的朋友可以加入我们,完全公益性质。交流群:467338606。这里有一些NumPy的快速指南:Matlab用户快速指南Numpy用......
  • Theano 中文文档 0.9 - 5. 安装Theano
    5.安装Theano译者:Python文档协作翻译小组,原文:InstallingTheano。本文以CCBY-NC-SA4.0协议发布,转载请保留作者署名和文章出处。Python文档协作翻译小组人手紧缺,有兴趣的朋友可以加入我们,完全公益性质。交流群:467338606。支持平台:Ubuntu安装说明MacOS安装说明Windows安装说......
  • Theano 中文文档 0.9 - 3. Theano一览
    3.Theano一览译者:Python文档协作翻译小组,原文:TheanoataGlance。本文以CCBY-NC-SA4.0协议发布,转载请保留作者署名和文章出处。Python文档协作翻译小组人手紧缺,有兴趣的朋友可以加入我们,完全公益性质。交流群:467338606。Theano是一个Python库,它允许你定义、优化和求值数学......
  • Theano 中文文档 0.9 - 7.2.5 循环
    7.2.5循环译者:Python文档协作翻译小组,原文:Loop。本文以CCBY-NC-SA4.0协议发布,转载请保留作者署名和文章出处。Python文档协作翻译小组人手紧缺,有兴趣的朋友可以加入我们,完全公益性质。交流群:467338606。Scan重复的一般形式,可用于循环。Reduction和map(在前面的维度上循环)是sc......
  • Theano 中文文档 0.9 - 7.2.4 条件
    7.2.4条件译者:Python文档协作翻译小组,原文:Conditions。本文以CCBY-NC-SA4.0协议发布,转载请保留作者署名和文章出处。Python文档协作翻译小组人手紧缺,有兴趣的朋友可以加入我们,完全公益性质。交流群:467338606。IfElse和Switch这两个op在符号变量上构建一个条件。IfElse接收......