赞
踩
之前我一直在使用Theano,前面五篇Deeplearning相关的文章也是学习Theano的一些笔记,当时已经觉得Theano用起来略显麻烦,有时想实现一个新的结构,就要花很多时间去编程,所以想过将代码模块化,方便重复使用,但因为实在太忙没有时间去做。最近发现了一个叫做Keras的框架,跟我的想法不谋而合,用起来特别简单,适合快速开发。(其实还有很多其他的深度学习框架都是比较容易用的。)
Keras是基于Theano的一个深度学习框架,它的设计参考了Torch,用Python语言编写,是一个高度模块化的神经网络库,支持GPU和CPU。使用文档在这:http://keras.io/,这个框架貌似是刚刚火起来的,使用上的问题可以到github提issue:https://github.com/fchollet/keras
下面简单介绍一下怎么使用Keras,以Mnist数据库为例,编写一个CNN网络结构,你将会发现特别简单。
keras.optimizers.SGD(lr=0.01, momentum=0.9, decay=0.9, nesterov=False)
上面的代码是SGD的使用方法,lr表示学习速率,momentum表示动量项,decay是学习速率的衰减系数(每个epoch衰减一次),Nesterov的值是False或者True,表示使不使用Nesterov momentum。其他的请参考文档。
这里binary_crossentropy 和 categorical_crossentropy也就是logloss
其中core里面包含了flatten(CNN的全连接层之前需要把二维特征图flatten成为一维的)、reshape(CNN输入时将一维的向量弄成二维的)、dense(就是隐藏层,dense是稠密的意思),还有其他的就不介绍了。convolutional层基本就是Theano的Convolution2D的封装。
- #coding:utf-8
- """
- Author:wepon
- Source:https://github.com/wepe
- file:data.py
- """
-
- import os
- from PIL import Image
- import numpy as np
-
- #读取文件夹mnist下的42000张图片,图片为灰度图,所以为1通道,
- #如果是将彩色图作为输入,则将1替换为3,图像大小28*28
- def load_data():
- data = np.empty((42000,1,28,28),dtype="float32")
- label = np.empty((42000,),dtype="uint8")
-
- imgs = os.listdir("./mnist")
- num = len(imgs)
- for i in range(num):
- img = Image.open("./mnist/"+imgs[i])
- arr = np.asarray(img,dtype="float32")
- data[i,:,:,:] = arr
- label[i] = int(imgs[i].split('.')[0])
- return data,label

- #导入各种用到的模块组件
- from __future__ import absolute_import
- from __future__ import print_function
- from keras.preprocessing.image import ImageDataGenerator
- from keras.models import Sequential
- from keras.layers.core import Dense, Dropout, Activation, Flatten
- from keras.layers.advanced_activations import PReLU
- from keras.layers.convolutional import Convolution2D, MaxPooling2D
- from keras.optimizers import SGD, Adadelta, Adagrad
- from keras.utils import np_utils, generic_utils
- from six.moves import range
- from data import load_data
-
- #加载数据
- data, label = load_data()
- print(data.shape[0], ' samples')
-
- #label为0~9共10个类别,keras要求格式为binary class matrices,转化一下,直接调用keras提供的这个函数
- label = np_utils.to_categorical(label, 10)
-
- ###############
- #开始建立CNN模型
- ###############
-
- #生成一个model
- model = Sequential()
-
- #第一个卷积层,4个卷积核,每个卷积核大小5*5。1表示输入的图片的通道,灰度图为1通道。
- #border_mode可以是valid或者full,具体看这里说明:http://deeplearning.net/software/theano/library/tensor/nnet/conv.html#theano.tensor.nnet.conv.conv2d
- #激活函数用tanh
- #你还可以在model.add(Activation('tanh'))后加上dropout的技巧: model.add(Dropout(0.5))
- model.add(Convolution2D(4, 1, 5, 5, border_mode='valid'))
- model.add(Activation('tanh'))
-
- #第二个卷积层,8个卷积核,每个卷积核大小3*3。4表示输入的特征图个数,等于上一层的卷积核个数
- #激活函数用tanh
- #采用maxpooling,poolsize为(2,2)
- model.add(Convolution2D(8,4, 3, 3, border_mode='valid'))
- model.add(Activation('tanh'))
- model.add(MaxPooling2D(poolsize=(2, 2)))
-
- #第三个卷积层,16个卷积核,每个卷积核大小3*3
- #激活函数用tanh
- #采用maxpooling,poolsize为(2,2)
- model.add(Convolution2D(16, 8, 3, 3, border_mode='valid'))
- model.add(Activation('tanh'))
- model.add(MaxPooling2D(poolsize=(2, 2)))
-
- #全连接层,先将前一层输出的二维特征图flatten为一维的。
- #Dense就是隐藏层。16就是上一层输出的特征图个数。4是根据每个卷积层计算出来的:(28-5+1)得到24,(24-3+1)/2得到11,(11-3+1)/2得到4
- #全连接有128个神经元节点,初始化方式为normal
- model.add(Flatten())
- model.add(Dense(16*4*4, 128, init='normal'))
- model.add(Activation('tanh'))
-
- #Softmax分类,输出是10类别
- model.add(Dense(128, 10, init='normal'))
- model.add(Activation('softmax'))
-
- #############
- #开始训练模型
- ##############
- #使用SGD + momentum
- #model.compile里的参数loss就是损失函数(目标函数)
- sgd = SGD(l2=0.0,lr=0.05, decay=1e-6, momentum=0.9, nesterov=True)
- model.compile(loss='categorical_crossentropy', optimizer=sgd,class_mode="categorical")
-
- #调用fit方法,就是一个训练过程. 训练的epoch数设为10,batch_size为100.
- #数据经过随机打乱shuffle=True。verbose=1,训练过程中输出的信息,0、1、2三种方式都可以,无关紧要。show_accuracy=True,训练时每一个epoch都输出accuracy。
- #validation_split=0.2,将20%的数据作为验证集。
- model.fit(data, label, batch_size=100,nb_epoch=10,shuffle=True,verbose=1,show_accuracy=True,validation_split=0.2)
-
- #fit方法在达到设定的nb_epoch时结束,并且自动地保存了效果最好的model,之后你可以调用model.evaluate()方法对测试数据进行测试,
- #还有model.predict_classes,model.predict_proba等方法,具体请看文档。

代码放在我github的机器学习仓库里:https://github.com/wepe/MachineLearning,非github用户直接点右下的DownloadZip。
在/DeepLearning Tutorials/keras_usage目录下包括data.py,cnn.py两份代码,下载Mnist数据后解压到该目录下,运行cnn.py这份文件即可。
结果如下所示,在Epoch 9达到了0.98的训练集识别率和0.97的验证集识别率:
以上总结了Keras的基本使用方法,相信用过的同学都会觉得不可思议,太简洁了。十多天前,我在github上发现这个框架的时候,关注Keras的人还比较少,这两天无论是github还是微薄,都看到越来越多的人关注和使用Keras。所以这篇文章就简单地再介绍一下Keras的使用,方便各位入门。
主要包括以下三个内容:
仍然以Mnist为例,代码中用的Mnist数据到这里下载
http://pan.baidu.com/s/1qCdS6,本文的代码在我的github上:dive_into _keras
数据是图片格式,利用pyhton的PIL模块读取,并转为numpy.array类型。这部分的代码在data.py里:
将上一步加载进来的数据分为训练数据(X_train,30000个样本)和验证数据(X_val,12000个样本),构建CNN模型并训练。训练过程中,每一个epoch得到的val-accuracy都不一样,我们保存达到最好的val-accuracy时的模型,利用Python的cPickle模块保持。(Keras的开发者最近在添加用hdf5保持模型的功能,我试了一下,没用成功,去github发了issue也没人回,估计还没完善,hdf5压缩率会更高,保存下来的文件会更小。)
这部分的代码在cnn.py里,运行:
python cnn.py
在第Epoch 4得到96.45%的validation accuracy,运行完后会得到model.pkl这份文件,保存的就是96.45%对应的模型:
上一步得到了一个val-accuracy为96.45%的CNN模型,在一些论文中经常会看到用CNN的全连接层的输出作为特征,然后去训练其他分类器。这里我也试了一下,用全连接层的输出作为样本的特征向量,训练SVM。SVM用的是scikit learn里的算法。
这部分代码在cnn-svm.py,运行:
python cnn-svm.py
得到下图的输出,可以看到,cnn-svm的准确率提高到97.89%:
将卷积层和全连接层后的特征图、特征向量以图片形式展示出来,用到matplotlib这个库。这部分代码在get_feature_map.py里。运行:
python get_feature_map.py
得到全连接层的输出,以及第一个卷积层输出的4个特征图:
作者:wphh
文章出处:http://blog.csdn.net/u012162613/article/details/45397033
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。