【Keras入门日志(2】 Keras里的模块介绍

时间:2024-03-29 07:14:42

【时间】2018.10.30

【Keras入门日志(2】 Keras里的模块介绍

目录

概述

一、Keras中的模块

 keras模块思维导图

1.1 Optimizers

1.2 Objectives

1.3 Activations

1.4 Initializations

1.5. layers

1.6 Embedding层

1.7  Preprocessing

1.8 utils

1.9 Models

二、一个实例:用CNN分类Mnist

2.1. 数据下载

2.2 读取图片数据

2.3.构建CNN,训练

2.4.代码使用与结果


概述

本文内容主要来自文章 https://blog.csdn.net/u012162613/article/details/45397033,在文章基础上进行补充说明,主要介绍了Keras中的模块,以对Keras有一个整体的认识。并在后面给出了一个使用Keras的具体代码例子,以加深对各个模块的理解。

一、Keras中的模块

 keras模块思维导图

【Keras入门日志(2】 Keras里的模块介绍

1.1 Optimizers

顾名思义,Optimizers包含了一些优化的方法,比如最基本的随机梯度下降SGD,另外还有Adagrad、Adadelta、RMSprop、Adam,一些新的方法以后也会被不断添加进来。

keras.optimizers.SGD(lr=0.01, momentum=0.9, decay=0.9, nesterov=False)

上面的代码是SGD的使用方法,lr表示学习速率,momentum表示动量项,decay是学习速率的衰减系数(每个epoch衰减一次),Nesterov的值是False或者True,表示使不使用Nesterov momentum。其他的请参考文档。

1.2 Objectives

这是目标函数模块,keras提供了mean_squared_error,mean_absolute_error,squared_hinge,hinge,binary_crossentropy,categorical_crossentropy这几种目标函数。这里binary_crossentropy 和 categorical_crossentropy也就是常说的logloss.

1.3 Activations

这是**函数模块,keras提供了linear、sigmoid、hard_sigmoid、tanh、softplus、relu、softplus,另外softmax也放在Activations模块里(我觉得放在layers模块里更合理些)。此外,像LeakyReLU和PReLU这种比较新的**函数,keras在keras.layers.advanced_activations模块里提供。

1.4 Initializations

这是参数初始化模块,在添加layer的时候调用init进行初始化。keras提供了uniform、lecun_uniform、normal、orthogonal、zero、glorot_normal、he_normal这几种。

这个模块有两种初始化方法

1.4.1 通过制定初始化方法的名称:

示例代码:

model.add(Dense(64, init='uniform'))

可以选择的初始化方法有:

uniform、lecun_uniform、normal、orthogonal、zero、glorot_normal、he_normal等

1.4.2 通过调用对象:

该对象必须包含两个参数:shape(待初始化的变量的shape)和name(该变量的名字),该可调用对象必须返回一个(Keras)变量,例如K.variable()返回的就是这种变量,示例代码:

from keras import backend as K

import numpy as np

def my_init(shape, name=None):

    value = np.random.random(shape)

    return K.variable(value, name=name)

model.add(Dense(64, init=my_init))

或者

from keras import initializations

def my_init(shape, name=None):

    return initializations.normal(shape, scale=0.01, name=name)

model.add(Dense(64, init=my_init))

所以说可以通过库中的方法设定每一层的初始化权重,

也可以自己初始化权重,自己设定的话可以精确到每个节点的权重,

1.5. layers

layers模块包含了core(常用层)、convolutional、recurrent(递归层)、advanced_activations(高级**层)、normalization(规范层)、embeddings(嵌入层)这几种layer,当然也可以编写自己的层。

其中core里面包含了flatten(CNN的全连接层之前需要把二维特征图flatten成为一维的)、reshape(CNN输入时将一维的向量弄成二维的)、dense(就是隐藏层,dense是稠密的意思),还有其他的就不介绍了。convolutional层基本就是Theano的Convolution2D的封装。还包括Dropout、Activation等。

1.5.1对于层的操作

layer.get_weights() #返回该层的权重

layer.set_weights(weights)#将权重加载到该层

config = layer.get_config()#保存该层的配置

layer = layer_from_config(config)#加载一个配置到该层

#该层有一个节点时,获得输入张量、输出张量、及各自的形状:

layer.input

layer.output

layer.input_shape

layer.output_shape

#该层有多个节点时(node_index为节点序号):

layer.get_input_at(node_index)

layer.get_output_at(node_index)

layer.get_input_shape_at(node_index)

layer.get_output_shape_at(node_index)

1.5.2 Dense层(全连接层)

keras.layers.core.Dense(output_dim, init='glorot_uniform', activation='linear', weights=None, W_regularizer=None, b_regularizer=None, activity_regularizer=None, W_constraint=None, b_constraint=None, bias=True, input_dim=None)

output_dim:输出数据的维度

init:初始化该层权重的方法

activation:该层的**函数

weights:numpy array的list。该list应含有一个形如(input_dim,output_dim)的权重矩阵和一个形如(output_dim,)的偏置向量

regularizer:正则项,w为权重的、b为偏执的,activity为输出的

constraints:约束项

bias:是否包含偏执向量,是布尔值

input_dim:输入数据的维度

1.5.3 dropout层

keras.layers.core.Dropout(p)

为输入数据施加Dropout。Dropout将在训练过程中每次更新参数时随机断开一定百分比(p)的输入神经元连接,Dropout层用于防止过拟合。

1.5.4 递归层(Recurrent)

递归层包含三种模型:LSTM、GRU和SimpleRNN

1)抽象层,不能直接使用

keras.layers.recurrent.Recurrent(weights=None, return_sequences=False, go_backwards=False, stateful=False, unroll=False, consume_less='cpu', input_dim=None, input_length=None)

return_sequences:True返回整个序列,false返回输出序列的最后一个输出

go_backwards:True,逆向处理输入序列,默认为False

stateful:布尔值,默认为False,若为True,则一个batch中下标为i的样本的最终状态将会用作下一个batch同样下标的样本的初始状态

2) 全连接RNN网络--SimpleRNN

keras.layers.recurrent.SimpleRNN(output_dim, init='glorot_uniform', inner_init='orthogonal', activation='tanh', W_regularizer=None, U_regularizer=None, b_regularizer=None, dropout_W=0.0, dropout_U=0.0)

inner_init:内部单元的初始化方法

dropout_W:0~1之间的浮点数,控制输入单元到输入门的连接断开比例

dropout_U:0~1之间的浮点数,控制输入单元到递归连接的断开比例

3) LSTM层

keras.layers.recurrent.LSTM(output_dim, init='glorot_uniform', inner_init='orthogonal', forget_bias_init='one', activation='tanh', inner_activation='hard_sigmoid', W_regularizer=None, U_regularizer=None, b_regularizer=None, dropout_W=0.0, dropout_U=0.0)

 

forget_bias_init:遗忘门偏置的初始化函数,Jozefowicz et al.建议初始化为全1元素

inner_activation:内部单元**函数

1.6 Embedding层

keras.layers.embeddings.Embedding(input_dim, output_dim, init='uniform', input_length=None, W_regularizer=None, activity_regularizer=None, W_constraint=None, mask_zero=False, weights=None, dropout=0.0)

只能作为模型第一层

mask_zero:布尔值,确定是否将输入中的‘0’看作是应该被忽略的‘填充’(padding)值,该参数在使用递归层处理变长输入时有用。设置为True的话,模型中后续的层必须都支持masking,否则会抛出异常

1.7  Preprocessing

这是预处理模块,包括序列数据的处理,文本数据的处理,图像数据的处理。重点看一下图像数据的处理,keras提供了ImageDataGenerator函数,实现data augmentation,数据集扩增,对图像做一些弹性变换,比如水平翻转,垂直翻转,旋转等。

1.8 utils

此模块提供了一系列的功能集,比如:

提供了一个神经网络可视化的函数plot,并可以将可视化结果保存在本地。plot使用方法如下:

from keras.utils import plot_model

plot_model(model,to_file='model.png')

1.9 Models

这是最主要的模块,模型。上面定义了各种基本组件,model是将它们组合起来.

model的方法:

model.summary() : 打印出模型概况

model.get_config() :返回包含模型配置信息的Python字典

model.get_weights():返回模型权重张量的列表,类型为numpy array

model.set_weights():从numpy array里将权重载入给模型

model.to_json:返回代表模型的JSON字符串,仅包含网络结构,不包含权值。可以从JSON字符串中重构原模型

model_from_json:从代表模型的JSON字符串加载模型的网络结构:

from models import model_from_json

json_string = model.to_json()

model = model_from_json(json_string)

model.to_yaml:与model.to_json类似,同样可以从产生的YAML字符串中重构模型:

from models import model_from_yaml

yaml_string = model.to_yaml()

model = model_from_yaml(yaml_string)

model.save_weights(filepath):将模型权重保存到指定路径,文件类型是HDF5(后缀是.h5)

model.load_weights(filepath, by_name=False):从HDF5文件中加载权重到当前模型中, 默认情况下模型的结构将保持不变。如果想将权重载入不同的模型(有些层相同)中,则设置by_name=True,只有名字匹配的层才会载入权重

keras有两种model,分别是Sequential序贯模型和函数式模型

1.9.1 Sequential模型

Sequential是多个网络层的线性堆叠

可以通过向Sequential模型传递一个layer的list来构造该模型:

from keras.models import Sequential

from keras.layers import Dense, Activation

model = Sequential([Dense(32,input_dim=784),Activation('relu'),Dense(10),Activation('softmax'),])

也可以通过.add()方法一个个的将layer加入模型中:

model = Sequential()

model.add(Dense(32, input_dim=784))

model.add(Activation('relu'))

还可以通过merge将两个Sequential模型通过某种方式合并

Sequential模型的方法:

compile(self, optimizer, loss, metrics=[], sample_weight_mode=None)

fit(self, x, y, batch_size=32, nb_epoch=10, verbose=1, callbacks=[], validation_split=0.0, validation_data=None, shuffle=True, class_weight=None, sample_weight=None)

evaluate(self, x, y, batch_size=32, verbose=1, sample_weight=None)

#按batch获得输入数据对应的输出,函数的返回值是预测值的numpy array

predict(self, x, batch_size=32, verbose=0)

#按batch产生输入数据的类别预测结果,函数的返回值是类别预测结果的numpy array或numpy

predict_classes(self, x, batch_size=32, verbose=1)

#本函数按batch产生输入数据属于各个类别的概率,函数的返回值是类别概率的numpy array

predict_proba(self, x, batch_size=32, verbose=1)

train_on_batch(self, x, y, class_weight=None, sample_weight=None)

test_on_batch(self, x, y, sample_weight=None)

predict_on_batch(self, x)

fit_generator(self, generator, samples_per_epoch, nb_epoch, verbose=1, callbacks=[], validation_data=None, nb_val_samples=None, class_weight=None, max_q_size=10)

evaluate_generator(self, generator, val_samples, max_q_size=10)

 

1.9.2 泛型模型

Keras泛型模型接口是:

用户定义多输出模型、非循环有向模型或具有共享层的模型等复杂模型的途径

适用于实现:全连接网络和多输入多输出模型

多输入多输出,官方例子给出:预测一条新闻的点赞转发数,主要输入是新闻本身,还可以加入额外输入,比如新闻发布日期,新闻作者等,具体的实现还是看官网文档吧:

http://keras-cn.readthedocs.io/en/latest/getting_started/functional_API/

泛型模型model的属性:

model.layers:组成模型图的各个层

model.inputs:模型的输入张量列表

model.outputs:模型的输出张量列表

方法:类似序列模型的方法

补充get_layer

get_layer(self, name=None, index=None)

本函数依据模型中层的下标或名字获得层对象,泛型模型中层的下标依据自底向上,水平遍历的顺序。

name:字符串,层的名字

index: 整数,层的下标

函数的返回值是层对象

 

二、一个实例:用CNN分类Mnist

2.1. 数据下载

Mnist数据在其官网上有提供,但是不是图像格式的,因为我们通常都是直接处理图像,为了以后程序能复用,我把它弄成图像格式的,这里可以下载:http://pan.baidu.com/s/1qCdS6,共有42000张图片。

2.2 读取图片数据

keras要求输入的数据格式是numpy.array类型(numpy是一个python的数值计算的库),所以需要写一个脚本来读入mnist图像,保存为一个四维的data,还有一个一维的label,代码:

#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,并且data[i,:,:,:] = arr改为data[i,:,:,:] = [arr[:,:,0],arr[:,:,1],arr[:,:,2]]

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

2.3.构建CNN,训练

短短二十多行代码,构建一个三个卷积层的CNN,直接读下面的代码吧,有注释,很容易读懂:

#导入各种用到的模块组件

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)

2.4.代码使用与结果

代码放在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入门日志(2】 Keras里的模块介绍

 

参考文章:https://blog.csdn.net/lk7688535/article/details/52862377