深度学习框架之一:Theano | Lasagne简单教程

参考Lasagne官网(http://lasagne.readthedocs.io/en/latest/)tutorial进行总结而来。

01

简介

Lasagne is a lightweight library to build and train neural networks in Theano.

Lasagen是一个基于Theano的轻量级的神经网络库。其实就是对Theano库的上层封装,使其用起来更简单,但是相应的灵活性下降。

Lasagne设计的六个原则是简洁、透明、模块化、实用、聚焦和专注。

官网地址:http://lasagne.readthedocs.io/en/latest/index.html GitHub: https://github.com/Lasagne/Lasagne

02

安装

本质上来说Lasagne还是个python库,所以它的安装还是很简单的,通过pip就可以安装了。整个安装就两步:安装依赖包和安装Lasagen.

官网有很详细的安装教程(http://lasagne.readthedocs.io/en/latest/user/installation.html)。

稳定版安装

执行下面两条命令即可:

pip install -r https://raw.githubusercontent.com/Lasagne/Lasagne/v0.1/requirements.txt pip install Lasagne==0.1

Bleeding-edge version

执行下面两条命令:

pip install --upgrade https://github.com/Theano/Theano/archive/master.zip pip install --upgrade https://github.com/Lasagne/Lasagne/archive/master.zip

开发版安装

执行下面命令

git clone https://github.com/Lasagne/Lasagne.git cd Lasagne pip install -r requirements.txt pip install --editable

这里建议安装Bleeding-edge version,功能相对比较新,而版本也相对稳定。

03

Tutorial

教程还是以经典的mnist数据集的字符识别为例。

整个过程分为以下几个部分:

  • Loading data/加载数据(http://lasagne.readthedocs.io/en/latest/user/tutorial.html#loading-data)
  • Building the model/建立模型(http://lasagne.readthedocs.io/en/latest/user/tutorial.html#building-the-model)
  • Training the model/训练模型(http://lasagne.readthedocs.io/en/latest/user/tutorial.html#training-the-model)

下面分别介绍这几个部分。

1、加载数据

这个和其它库的数据加载方法差不多,都是采用python语法处理数据,没有太多特殊之处,这里就不详细介绍了,具体的可以查阅源代码mnist.py(https://github.com/Lasagne/Lasagne/blob/master/examples/mnist.py)

2、建立模型

和所有的框架一样,非常重要的一个环节就是进行网络模型的定义。Lasagne的网络模型建立方法和torch比较相似,都是对各种常用网络层(layer)进行了封装,我们只需要调用相应的网络层函数并把它们搭接在一起就可以了,就像盖房子一样。

下面以建立多层感知机、卷积神经网络等模型为例进行介绍。

多层感知机

多层感知机(Multi-Layer Perceptron, MLP)(http://lasagne.readthedocs.io/en/latest/user/tutorial.html#multi-layer-perceptron-mlp)

这里以构建一个两个隐藏层的多层感知机为例,并对输入增加20%的dropout、隐藏层增加50%的dropout。

实际上,我们网络模型就由输入层+两个隐藏层+输出层组成,只需要对其分别进行定义即可。

** 输入层 **

输入层采用InputLayer进行定义,InputLayer只用于接收数据,不对数据做任何处理,类似于tensorfolw里的placeholder功能。定义方法如下:

l_in = lasagne.layers.InputLayer(shape=(None, 1, 28, 28), input_var=input_var)

shape里对应的四个参数分别表示:(batchsize, channels, rows, columns),input_var表示需要连接到网络输入层的theano变量,默认为none。

然后对输入数据加以20%的dropout,采用DropoutLayer进行定义:

l_in_drop = lasagne.layers.DropoutLayer(l_in, p=0.2)

p=0.2表示dropout的比例。DropoutLayer也属于layers里的一个组件,也可以简写为dropout。

** 隐藏层 ** 这里的隐藏层由全连接层、激活层、dropout层组成。Lasagne将全连接层和激活层封装到一个函数里了,即DenseLayer,定义如下:

l_hid1 = lasagne.layers.DenseLayer( l_in_drop, num_units=800, nonlinearity=lasagne.nonlinearities.rectify, W=lasagne.init.GlorotUniform

())

num_units表示全连接层的单元数目,nonlinearity用以定义激活层函数,激活层函数封装在lasagne.nonlinearities中,这里选择的是ReLU函数,而网络参数的初始化封装在lasagne.init里,只需要分别进行调用就可以了。

之后添加50%的dropou:

l_hid1_drop = lasagne.layers.DropoutLayer(l_hid1, p=0.5)

第二个隐藏层的定义与此类似,这里就不赘述了。

** 输出层 ** 输出层依然是一个全连接网络,只是不同的是这里是做分类任务,所以需要将非线性函数/激活函数修改为softmax,如下:

l_out = lasagne.layers.DenseLayer( l_hid2_drop, num_units=10, nonlinearity=lasagne.nonlinearities.softmax)

这样就得到了一个含两个隐藏层的多层感知机了。当然,我们也可以像官网一样将一些网络设置参数作为函数变量输入,创建可自定义的多层感知机。

卷积神经网络

这里以建立一个含两个卷积层的神经网络为例。网络模型的具体组成包括输入层、两个卷积层、全连接层、输出层。

** 输入层 ** 输入层的定义和前面一样,不再赘述。

** 卷积层 ** 卷积层采用Conv2DLayer进行定义,定义如下:

network = lasagne.layers.Conv2DLayer( network, num_filters=32, filter_size=(5, 5), nonlinearity=lasagne.nonlinearities.rectify, W=lasagne.init.GlorotUniform())

num_filters表示卷积核的数目,filter_size表示卷积核的大小,激活函数和参数初始化和DenseLayer类似。当然,我们还可以定义padding、stride等参数,具体方法可以查看Conv2DLayer的帮助。

值得注意的是lasagne默认采用的是theano的卷积实现方法,如果配置了gpu就会调用Nvidia提供的cuDNN实现。lasagne也提供了一些其它的实现方法:

lasagne.layers.dnn.Conv2DDNNLayer to enforce cuDNN, lasagne.layers.corrmm.Conv2DMMLayer to enforce the gemm-based one, lasagne.layers.cuda_convnet.Conv2DCCLayer for Krizhevsky’s cuda-convnet.

一般情况,我们会在卷积层后加上pooling层,其中maxpool采用函数MaxPool2DLayer进行定义:

network = lasagne.layers.MaxPool2DLayer(network, pool_size=(2, 2))

pool_size表示pooling的大小。当然我们也可以采用Pool2DLayer定义meanPool等。

之后的第二个卷积层、全连接层、输出层的定义与前面类似,此处不再赘述。

通过前面mlp和cnn的定义可以发现,在lasagne里定义网络,只需要在lasagne.layers里调用对应的网络层函数然后按照一定的结构组装起来即可。

关于lasagne.layers的详细使用可以查阅官方文档lasagne.layers(http://lasagne.readthedocs.io/en/latest/modules/layers.html)

3、训练模型

和一般的深度学习框架类似,我们还需要定义训练模型,包括:损失函数、更新/优化函数等。在Lasagne里,或者更准确的说是在Theano里,一般是将网络模型、训练模型整合在一块儿定义一个function,然后再将训练数据/测试数据作为函数的自变量输入到函数中,而输入数据通过tensor来进行定义,网络参数通过shared来更新并保存。tensorflow和这个其实是有点类似,tensorflow是将网络模型、训练模型等等整合成一个计算图,定义一个placeholder接收数据,而网络参数通过Variable来保持。

下面,通过代码来进行说明。

数据准备

通过Theano里的tensor进行定义:

# Prepare Theano variables for inputs and targets input_var = T.tensor4('inputs') target_var = T.ivector('targets')

这两个变量作为训练函数的自变量,在实际训练时只需要将真实的训练数据带入了函数中即可。

损失和更新函数定义

损失和更新函数定义(http://lasagne.readthedocs.io/en/latest/user/tutorial.html#loss-and-update-expressions)

通过调用lasagne.objectives里的损失函数来定义不同的损失函数:

prediction = lasagne.layers.get_output(network) loss = lasagne.objectives.categorical_crossentropy(prediction, target_var) loss = loss.mean()

这里的network是前面定义的网络模型,prediction表示网络模型的输出表达式。这里的的损失函数采用的是categorical_crossentropy。

验证集和测试集上的定义与此类似,只是我们需要更改deterministic为deterministic=True,这样会屏蔽掉所有的dropout层:

test_prediction = lasagne.layers.get_output(network, deterministic=True) test_loss = lasagne.objectives.categorical_crossentropy(test_prediction, target_var) test_loss = test_loss.mean()

有了网络模型和损失函数的定义后,还需要定义网络训练与参数更新方法的表达式,一般采用梯度下降方法。更新方法通过调用lasagne.updates里的更新函数来进行定义,这里采用的是Stochastic Gradient Descent (SGD) with Nesterov momentum,即nesterov_momentum:

params = lasagne.layers.get_all_params(network, trainable=True) updates = lasagne.updates.nesterov_momentum( loss, params, learning_rate=0.01, momentum=0.9

)

这里我们第一步需要先获取所有的网络参数,然后产生更新参数的更新表达式。

compliation

最后,就是基于前面的表达式定义一步训练函数:

train_fn = theano.function([input_var, target_var], loss, updates=updates)

这个函数是告诉Theano生成一个训练函数,接收两个输入input_var, target_var,然后计算trainning loss并返回,之后利用updates表达式更新参数。

如果是用于验证和测试,我们就不需要进行网络参数的更新,这时这样定义:

val_fn = theano.function([input_var, target_var], [test_loss, test_acc])

对于测试精度,采用下面定义:

test_acc = T.mean(T.eq(T.argmax(test_prediction, axis=1), target_var), dtype=theano.config.floatX

)

前面的这么多定义,其实并没有进行正式的计算,就像是tensorflow里的计算图定义。其实就像是我们在高中的时候解一道数学题,往往都是先把最终的符号表达式推导出来,最后再把输入x代入表达式计算结果y。

Theano的当初的诞生其实也是基于这个需求的,当时python的Numpy、Scipy等库主要用于数值计算,但是需要一种能够调用库就得到导数的符号表达式的库,所以就有了后来的Theano,所以本质上来说早期的Theano的定位是一个融合符号运算与数值计算的数学计算库。

循环训练

有了一步训练表达式后就可以将真实的数据输入到函数中进行循环训练了:

for epoch in range(num_epochs):
    # In each epoch, we do a full pass over the training data:
    train_err = 0
    train_batches = 0
    start_time = time.time()
    for batch in iterate_minibatches(X_train, y_train, 500, shuffle=True):
        inputs, targets = batch
        train_err += train_fn(inputs, targets)
        train_batches += 1

    # And a full pass over the validation data:
    val_err = 0
    val_acc = 0
    val_batches = 0
    for batch in iterate_minibatches(X_val, y_val, 500, shuffle=False):
        inputs, targets = batch
        err, acc = val_fn(inputs, targets)
        val_err += err
        val_acc += acc
        val_batches += 1

    # Then we print the results for this epoch:
    print("Epoch {} of {} took {:.3f}s".format(
        epoch + 1, num_epochs, time.time() - start_time))
    print("  training loss:\t\t{:.6f}".format(train_err / train_batches))
    print("  validation loss:\t\t{:.6f}".format(val_err / val_batches))
    print("  validation accuracy:\t\t{:.2f} %".format(
        val_acc / val_batches * 100))

以上就是Lasagne的简单使用方法的,还是挺简单的,跟着教程走,基本上一个小时就搞定了。如果要学习Theano库的其它一些用法以及各种函数的具体使用方法,建议查询官方文档里的API,主要包括:

  • all layers(lasagne.layers)
  • weight initializers (lasagne.init)
  • nonlinearities (lasagne.nonlinearities)
  • loss expressions (lasagne.objectives)
  • training methods (lasagne.updates)
  • regularizers (lasagne.regularization)
  • lasagne.random
  • lasagne.utils

原文发布于微信公众号 - 人工智能LeadAI(atleadai)

原文发表时间:2017-12-28

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏人工智能

深度学习框架之一:Theano

正文共7163个字,1张图,预计阅读时间18分钟。 参考Lasagne官网(http://lasagne.readthedocs.io/en/latest/)t...

1796
来自专栏大数据挖掘DT机器学习

机器学习算法-决策树C4.5练习

决策树是一个预测模型;他代表的是对象属性与对象值之间的一种映射关系。树中每个节点表示某个对象,而每个分叉路径则代表的某个可能的属性值,而每个叶结点则对应...

3366
来自专栏Android机动车

数据结构学习笔记——算法

算法是解决特定问题求解步骤的描述,在计算机中表现为指令的有限序列,并且每条指令表达一个或者多个步骤。

531
来自专栏机器学习之旅

基于Tensorflow实现多层感知机网络MLPs

之前在基于Tensorflow的神经网络解决用户流失概率问题写了一个MLPs的网络,很多人在问,其实这个网络看起来很清晰,但是却写的比较冗长,这边优化了一个版本...

502
来自专栏PPV课数据科学社区

【大数据问答】SPSS是如何做到发现数据质量问题,例如,如何发现缺失值?

SPSS是如何做到发现数据质量问题,例如,如何发现缺失值? (1)系统缺失值、空白值 每一个变量均有可能出现系统缺失或者空白,当数据量巨大时我们根本无法用眼睛...

3164
来自专栏Small Code

【TensorFlow】理解 Estimators 和 Datasets

Google 在 2017 年 9 月 12 号的博文 Introduction to TensorFlow Datasets and Estimators 中...

6678
来自专栏null的专栏

简单易学的机器学习算法——Label Propagation

一、社区划分的概述 对于社区,没有一个明确的定义,有很多对社区的定义,如社区是指在一个网络中,有一组节点,它们彼此都相似,而组内的节点与网络中的其他节点则不相似...

4418
来自专栏用户画像

Tensorflow生成了一些三维数据, 然后用一个平面拟合它

885
来自专栏程飞翔的专栏

XGBoost 源码阅读笔记 ( 1 ) :代码逻辑结构

XGBoost 是基于 GB 模型框架实现的一个高效,便捷,可扩展的一个机器学习库。本文主要记录了 XGBoost 源码中代码逻辑结构的阅读笔记。

2.1K1
来自专栏小鹏的专栏

01 TensorFlow入门(1)

tensorflow_cookbook--第1章 TensorFlow入门         Google的TensorFlow引擎具有独特的解决问题的方法。 ...

20810

扫描关注云+社区