之前我1直在使用Theano,前面5篇Deeplearning相干的文章也是学习Theano的1些笔记,当时已觉得Theano用起来略显麻烦,有时想实现1个新的结构,就要花很多时间去编程,所以想过将代码模块化,方便重复使用,但由于实在太忙没有时间去做。最近发现了1个叫做Keras的框架,跟我的想法不谋而合,用起来特别简单,合适快速开发。(其实还有很多其他的深度学习框架都是比较容易用的。)
1. Keras简介
Keras是基于Theano的1个深度学习框架,它的设计参考了Torch,用Python语言编写,是1个高度模块化的神经网络库,支持GPU和cpu。使用文档在这:http://keras.io/,这个框架貌似是刚刚火起来的,使用上的问题可以到github提issue:https://github.com/fchollet/keras
下面简单介绍1下怎样使用Keras,以Mnist数据库为例,编写1个CNN网络结构,你将会发现特别简单。
2. Keras里的模块介绍
Optimizers
顾名思义,Optimizers包括了1些优化的方法,比如最基本的随机梯度降落SGD,另外还有Adagrad、Adadelta、RMSprop、Adam,1些新的方法以后也会被不断添加进来。
上面的代码是SGD的使用方法,lr表示学习速率,momentum表示动量项,decay是学习速率的衰减系数(每一个epoch衰减1次),Nesterov的值是False或True,表示使不使用Nesterov momentum。其他的请参考文档。
Objectives
这是目标函数模块,keras提供了mean_squared_error,mean_absolute_error ,squared_hinge,hinge,binary_crossentropy,categorical_crossentropy这几种目标函数。
这里binary_crossentropy 和 categorical_crossentropy也就是logloss
Activations
这是激活函数模块,keras提供了linear、sigmoid、hard_sigmoid、tanh、softplus、relu、softplus,另外softmax也放在Activations模块里(我觉得放在layers模块里更公道些)。另外,像LeakyReLU和PReLU这类比较新的激活函数,keras在keras.layers.advanced_activations模块里提供。
Initializations
这是参数初始化模块,在添加layer的时候调用init进行初始化。keras提供了uniform、lecun_uniform、normal、orthogonal、zero、glorot_normal、he_normal这几种。
layers
layers模块包括了core、convolutional、recurrent、advanced_activations、normalization、embeddings这几种layer。
其中core里面包括了flatten(CNN的全连接层之前需要把2维特点图flatten成为1维的)、reshape(CNN输入时将1维的向量弄成2维的)、dense(就是隐藏层,dense是稠密的意思),还有其他的就不介绍了。convolutional层基本就是Theano的Convolution2D的封装。
Preprocessing
这是预处理模块,包括序列数据的处理,文本数据的处理,图象数据的处理。重点看1下图象数据的处理,keras提供了ImageDataGenerator函数,实现data augmentation,数据集扩增,对图象做1些弹性变换,比如水平翻转,垂直翻转,旋转等。
Models
这是最主要的模块,模型。上面定义了各种基本组件,model是将它们组合起来,下面通过1个实例来讲明。
3.1个实例:用CNN分类Mnist
数据下载
Mnist数据在其官网上有提供,但是否是图象格式的,由于我们通常都是直接处理图象,为了以后程序能复用,我把它弄成图象格式的,这里可以下载:http://pan.baidu.com/s/1qCdS6,共有42000张图片。
读取图片数据
keras要求输入的数据格式是numpy.array类型(numpy是1个python的数值计算的库),所以需要写1个脚本来读入mnist图象,保存为1个4维的data,还有1个1维的label,代码:
#coding:utf⑻
"""
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
@H_502_21@#导入各种用到的模块组件
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
@H_502_21@#加载数据
data,label = load_data()
print(data.shape[0],' samples')
@H_502_21@#label为0~9共10个种别,keras要求格式为binary class matrices,转化1下,直接调用keras提供的这个函数
label = np_utils.to_categorical(label,10)
@H_502_21@###############
@H_502_21@#开始建立CNN模型
@H_502_21@###############
@H_502_21@#生成1个model
model = Sequential()
@H_502_21@#第1个卷积层,4个卷积核,每一个卷积核大小5*5。1表示输入的图片的通道,灰度图为1通道。
@H_502_21@#border_mode可以是valid或full,具体看这里说明:http://deeplearning.net/software/theano/library/tensor/nnet/conv.html#theano.tensor.nnet.conv.conv2d
@H_502_21@#激活函数用tanh
@H_502_21@#你还可以在model.add(Activation('tanh'))后加上dropout的技能: model.add(Dropout(0.5))
model.add(Convolution2D(4,5,border_mode='valid'))
model.add(Activation('tanh'))
@H_502_21@#第2个卷积层,8个卷积核,每一个卷积核大小3*3。4表示输入的特点图个数,等于上1层的卷积核个数
@H_502_21@#激活函数用tanh
@H_502_21@#采取maxpooling,poolsize为(2,2)
model.add(Convolution2D(8,4,3,border_mode='valid'))
model.add(Activation('tanh'))
model.add(MaxPooling2D(poolsize=(2,2)))
@H_502_21@#第3个卷积层,16个卷积核,每一个卷积核大小3*3
@H_502_21@#激活函数用tanh
@H_502_21@#采取maxpooling,poolsize为(2,2)
model.add(Convolution2D(16,8,border_mode='valid'))
model.add(Activation('tanh'))
model.add(MaxPooling2D(poolsize=(2,2)))
@H_502_21@#全连接层,先将前1层输出的2维特点图flatten为1维的。
@H_502_21@#Dense就是隐藏层。16就是上1层输出的特点图个数。4是根据每一个卷积层计算出来的:(28⑸+1)得到24,(24⑶+1)/2得到11,(11⑶+1)/2得到4
@H_502_21@#全连接有128个神经元节点,初始化方式为normal
model.add(Flatten())
model.add(Dense(16*4*4,128,init='normal'))
model.add(Activation('tanh'))
@H_502_21@#Softmax分类,输出是10种别
model.add(Dense(128,10,init='normal'))
model.add(Activation('softmax'))
@H_502_21@#############
@H_502_21@#开始训练模型
@H_502_21@##############
@H_502_21@#使用SGD + momentum
@H_502_21@#model.compile里的参数loss就是损失函数(目标函数)
sgd = SGD(l2=0.0,lr=0.05,decay=1e⑹,nesterov=True)
model.compile(loss='categorical_crossentropy',optimizer=sgd,class_mode="categorical")
@H_502_21@#调用fit方法,就是1个训练进程. 训练的epoch数设为10,batch_size为100.
@H_502_21@#数据经过随机打乱shuffle=True。verbose=1,训练进程中输出的信息,0、1、23种方式都可以,无关紧要。show_accuracy=True,训练时每个epoch都输出accuracy。
@H_502_21@#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)
@H_502_21@#fit方法在到达设定的nb_epoch时结束,并且自动地保存了效果最好的model,以后你可以调用model.evaluate()方法对测试数据进行测试,
@H_502_21@#还有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的验证集辨认率:
转载请注明出处:http://blog.csdn.net/u012162613/article/details/45397033