Keras框架使用

框架介绍

相当于封装后的神经网络框架,底层基于TensorFlow等其他神经网络框架运行(因此需要先安装对应的底层框架),使用该框架能够很简易的实现神经网络对应的代码、但相对的运行速度也会慢一些

安装

pip install keras(需要先安装别的底层框架,如:pip install tensorflow

官方中文文档地址

https://keras.io/zh/

使用介绍

使用步骤

1.导入相关模块

from keras.models import Sequential
# 导入最简单的顺序模型(即按顺序一层一层的添加层的那种)
from keras.layers import Dense
# 导入全连接层

2.创建训练数据x_trainy_train以及测试数据x_testy_test
3.构建模型:model = Sequential()
4.添加层:model.add(Dense(units=输出维度, input_dim=输入维度))
5.编译模型:model.compile(optimizer=优化器, loss=损失函数)
6.训练模型:model.fit(x_train, y_train, batch_size=批次大小, epochs=迭代次数)/model.train_on_batch(x_train, y_train)
7.评估模型:loss, accuracy = model.evaluate(x_test, y_test)
8.测试模型:y = model.predit(x_test)

简单示例
# 导入相关模块
import numpy as np
import matplotlib.pyplot as plt
from keras.models import Sequential
from keras.layers import Dense
from keras.optimizers import SGD
# 导入sgd优化器

# 创建测试数据
x_train = np.linspace(-0.5, 0.5, 200)[:, np.newaxis]
# 生成-0.5到0.5的200个等差数列,并转成二维数据,即从1行200列转成200行1列
noise = np.random.normal(0, 0.02, x_train.shape)
# 生成和x_train格式相同的噪音数据
y_train = np.square(x_train) + noise
# 期望值为x_train的平方加上噪音
x_test = x_train

model = Sequential()
# 创建模型
model.add(Dense(units=10, input_dim=1, activation='tanh'))
# 添加一个全连接层,1个输入,10个输出,激活函数为tanh
model.add(Dense(units=1, activation='tanh'))
# 同上
sgd = SGD(lr=0.3)
# 定义sgd优化器,学习率为0.3
model.compile(optimizer=sgd, loss='mse')
# 编译模型,优化器为sgd(可以使用字符串的'sgd',即默认的sgd,但是学习率为0.01),损失函数为mse
plt.scatter(x_train, y_train)
# 绘画训练数据散点图
for i in range(2000):
    loss = model.train_on_batch(x_train, y_train)
    # 训练模型
    if i % 500 == 0:
        print(loss)
# 上面的训练等效于:
# model.fit(x_train, y_train, epochs=2000)
y_test = model.predict(x_test)
# 预测测试数据结果
plt.plot(x_test, y_test, 'r')
# 绘画预测曲线
plt.show()

基本使用

模块内容

在keras的不同包里存放着各种对应封装好的api,部分如下:

keras.models       各种模型以及模型操作,如:Sequential、save_model、load_model
keras.layers       各种神经网络层,如:Dense、Activation、Dropout
keras.optimizers   各种优化器,如:SGD、Adam
keras.datasets     各种数据集,如:mnist
keras.regularizers 各种正则化方法,如:l1、l2、l1_l2
keras.preprocessing.image  各种图像操作,如:ImageDataGenerator、load_img、img_to_array
kears.utils        各种工具方法,如:to_categorical(one-hot编码)
keras.callbacks    各种训练过程中的回调方法,如:EarlyStopping、ModelCheckpoint
导入数据集

例如使用mnist数据集:

from keras.datasets import mnist
# 导入数据集
from keras.utils import np_utils
# 导入numpy工具包
(x_train, y_train), (x_test, y_test) = mnist.load_data()
# 载入数据
print(x_train.data.shape, y_train.data.shape)
# 输出数据形状
print(x_test.data.shape, y_test.data.shape)
构建模型

keras.models当中导入对应的模型,然后初始化即可,举例:

model = Sequential()
添加层

有两种方式:

1.使用model.add()

由于model可迭代,因此如果要再添加层数,可以再通过mode.add(...)添加,由于前一层设置后的输出维度默认为下一层的输入维度,因此下一层可以不用设置input_dim属性,举例:

model.add(Dense(units=10, input_dim=1))
model.add(Dense(units=1))
# 默认下一层的输入是上一层的输入,所以第二层此时等效于:input_dim=10
2.在构建模型的时候添加

通过一个列表传入,举例:

model = Sequential([
  Dense(units=1, input_dim=1, activation='tanh'),
  Dense(...),
  ...
])

注:
这里介绍的是使用序列模型的添加层方式,可以看出使用十分方便,但是对于输入值我们不能很好的控制,因此对于一些多输入、多输出模型,keras提供了函数式api方式来实现,参考:
https://keras.io/zh/getting-started/functional-api-guide/

全连接层

Dense(),属性介绍:

batch_size           一次训练批次大小(默认None)
input_dim            输入维度
units                输出维度
activation           激活函数(默认None)
use_bias             是否使用偏置值(默认True)
kernel_initializer   权值初始化方式
bias_initializer     偏置初始化方式,例如:'zeros'则为0、'ones'则为1
kernel_regularizer   权值正则化
编译模型

需要配置模型的优化器、损失函数以及以下返回的数据等,举例:

model.compile(optimizer='sgd', loss='mse', metrics=['accuracy'])
# optimizer:设置优化器sgd(Stochastic gradient descent):随机梯度下降法
# loss:损失函数mse(mean squared error):均方误差
# metrics返回的数据属性:accuracy为准确率
训练模型

主要有两种训练方式:

1.使用train_on_batch()按批次训练

按批次大小循环一次,因此迭代次数需要自己用循环来设置,举例:

for i in range(2000):
    loss = model.train_on_batch(x_train, y_train)
    # 训练模型,默认返回loss值,如果设置了metrics属性,则会多返回对应值
    if i % 500 == 0:
        print(loss)
2.使用fit()训练

设置好批次大小和迭代次数后会自动进行训练,并且会输出每次的loss值、metrics属性里值的变化,举例:

model.fit(x_train, y_train, batch_size=200, epochs=10)

batch_sizeepochs理解:比如有1000个数据,设置batch_size=100,那么训练一次就100个数据,训练10次为一个迭代周期,再设置epochs=10,则要再重复这种训练10次,总的就是100次)
注:
fit()返回一个对象存储了迭代次数、loss值变化、模型、训练参数配置等内容,举例:

mf = model.fit(x_train, y_train, epochs=5)
print(mf.epoch, mf.history, mf.model, mf.params)
# 输出:迭代索引、loss值变化、模型、训练参数配置

注:
当模型的损失值无法下降时中断训练,参考:
https://keras-cn.readthedocs.io/en/latest/for_beginners/FAQ/#loss

训练回调

在训练模型当中,可以设置一些回调函数用于进行训练过程当中的操作,下面介绍一些常用的回调

  • 提前结束训练
from keras.callbacks import EarlyStopping
early_stop = EarlyStopping(monitor='val_loss',  # 以验证集的loss为基准判断
                           min_delta=0.001,
                           patience=15, # 如果连续15次loss不下降就直接结束训练
                           mode='min',
                           verbose=1)
  • 自动保存模型
from keras.callbacks import ModelCheckpoint
checkpoint = ModelCheckpoint('best.h5', 
                             monitor='val_loss',  # 以验证集的loss为基准判断
                             verbose=1, 
                             save_best_only=True,   # 保存最好的一版模型
                             mode='min',   # loss最低的时候保存
                             period=1)

使用回调训练示例:

history = model.fit_generator(
                    generator = train_batch,   # 训练集数据
                    steps_per_epoch  = len(train_batch), 
                    epochs           = 200,
                    verbose          = 0,
                    validation_data  = valid_batch,  # 验证集数据
                    validation_steps = len(valid_batch),
                    callbacks        = [early_stop, checkpoint],   # 这里使用回调,传入一组配置好的回调方法
                    max_queue_size   = 3
)

注:
verbose参数参考:https://www.jianshu.com/p/159a9ac413fa

评估模型

可以计算测试模型的loss值大小以及准确率,举例:

loss, accuracy = model.evaluate(x_test, y_test)
测试模型:

对于训练好的模型,可以使用测试数据去测试结果,举例:

y = model.predit(x_test)
# 根据x_test去预测y的值
其他
获取某一层权值和偏置值

可以索引到第i层并使用get_weights()方法获取对应权值和偏置值,举例:

W, b = model.layers[0].get_weights()
# 获取第一层权值和偏置值
模型保存

举例:

# 构建、训练模型等一系列步骤
...
model.save('xxx.h5')
# 保存的是hdf5文件,可以安装h5py模块(pip install h5py)来读取
模型载入

举例:

from keras.models import load_model
# 载入模型方法
model = load_model('xxx.h5')
# 载入模型,接下来就可以直接使用或者继续进行训练等一系列操作
...
参数保存和载入

举例:

model.save_weights('xxx.h5')
# 只保存了参数
model.load_weights('xxx.h5')
# 载入参数
打印网络结构
model.summary()
模型转成json格式(网络结构)、载入json

举例:

s_json = model.to_json()
# 转成json格式,包括各项配置
...
from keras.models import model_from_json
# 载入json方法
model = model_from_json(s_json)
# 将json字符串转成模型
绘制json数据(网络结构),即将json数据转成的模型以图形方式展示

使用前需要进行以下操作:
1.pip install pydot
2.下载安装graphviz软件
完成上述步骤即可进行模型网络结构绘制,举例:

from keras.utils.vis_utils import plot_model
# 导入绘图工具包

# 构建模型,只用构建层等就行了
...
plot_model(model, to_file="xxx.png", show_shapes=True, 
          show_layer_names=False, rankdir='TB')
# 绘制模型
# 传入参数:模型、图片名、图片内是否显示各层输入输出形状、
# 是否显示各层名、方向(TB代表top->bottom,左右就可以:LR)

基本配置

优化器

编译模型时可以通过引用优化器的字符串来使用优化器,也可以通过导入相关优化器后自定义修改这些优化器,举例:

from keras.optimizers import SGD
# 导入sgd优化器
sgd = SGD(lr=0.1)
# 设置优化器的学习率为0.1,默认0.01
model.compile(optimizer=sgd, loss='mse')
# 使用自定义的优化器

自定义优化器参考:
https://blog.csdn.net/wangdongwei0/article/details/82563689

交叉熵

如若使用交叉熵,则在编译模型中配置loss如下:

model.compile(optimizer='sgd', loss='categorical_crossentropy')
# 使用交叉熵
激活函数

有两种添加方法

1.单独一层用来作为激活函数
from keras.layers import Activation
...
model.add(Dense(input_dim=1, units=1)
model.add(Activation('tanh'))
2.在某个层里定义运算后执行的激活函数
model.add(Dense(input_dim=1, units=1, activation='relu')
dropout

需要使用dropout时,则添加层如下:

from keras.layers import Dropout
...
model.add(Dropout(0.4))
# 随机选取40%的神经元工作
正则化

需要对数据使用正则化时,举例如下:

from keras.regularizers import l2
# 导入l2正则化
...
model.add(Dense(input_dim=1, units=1, activation='relu', kernel_regularizer=l2(0.0003))
# 权值正则化,使用l2正则化,正则化系数为0.0003
CNN

使用卷积神经网络,举例如下:

from keras.layers import Convolution2D, MaxPooling2D, Flatten
# 导入二维卷积、二维最大池化、扁平化(转成一维数据)模块
...
model.add(Convolution2D(  # 添加卷积层
  input_shape=(28, 28, 1),  # 数据格式:(行, 列, 通道数)
  filters=32,  # 滤波器个数
  kernel_size=5, # 卷积窗口大小,这里是5*5
  strides=2, # 步长
  padding='same', # padding方式:same/valid
  activation='adam' # 激活函数
))
model.add(MaxPooling2D(  # 添加池化层
  pool_size=2, # 池化窗口大小:2*2
  strides=2, # 步长
  padding='same'  # padding方式
))
...
# 重复几次卷积和池化
...
model.add(Flatten())
# 扁平化处理
...
# 循环几次(添加卷积层->添加池化层)->扁平化->全连接层输出
RNN

使用循环神经网络,举例如下:

from keras.layers.recurrent import SimpleRNN, LSTM, GRU
# 导入最普通的RNN、LSTM和GRU,三种RNN使用方法差不多
...
model.add(SimpleRNN(  # 添加RNN层
  units=50, # 隐藏层个数,也是输出个数
  input_size=(28, 28) # 行列数
))
...
model.add(Dense(10, activation='softmax'))
LSTM

参考:https://blog.csdn.net/qq_35649669/article/details/89575949

mnist数据集实例1-基于全连接层
# 导入相关模块
import numpy as np
from keras.models import Sequential
from keras.layers import Dense
from keras.optimizers import Adam
from keras.utils import np_utils
from keras.datasets import mnist

# 数据预处理
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train = x_train.reshape(x_train.shape[0], 784) / 255.0
x_test = x_test.reshape(x_test.shape[0], 784) / 255.0
# 修改数据形状,并将所有输入数据0~1化
y_train = np_utils.to_categorical(y_train, num_classes=10)
y_test = np_utils.to_categorical(y_test, num_classes=10)
# 将所有结果数据设置为独热编码,范围为0~9

# 构建模型
model = Sequential()
model.add(Dense(units=16, input_dim=784, bias_initializer="one", activation='tanh'))
# 输入层图片时784数据,设置偏置默认为1
model.add(Dense(units=32, activation='tanh'))
model.add(Dense(units=64, activation='tanh'))
model.add(Dense(units=32, activation='tanh'))
model.add(Dense(units=10, activation='tanh'))
adam = Adam(lr=0.001)
model.compile(optimizer=adam, loss='mse', metrics=["accuracy"])
model.summary()

# 训练数据
model.fit(x_train, y_train, batch_size=32, epochs=10)
# 结果大概95+

# 评估模型
model.evaluate(x_test, y_test)
# 结果大概94+

# 预测数据
print(model.predict(x_train[0].reshape(1, -1)).argmax())
# argmax输出最大值的索引,即准确率最高的
print(y_train.argmax())
# 可以发现两个结果都为5,说明预测正确
mnist数据集实例2-基于卷积层
# 导入相关模块
import numpy as np
from keras.models import Sequential
from keras.layers import Dense, Convolution2D, MaxPooling2D, Flatten, Dropout
from keras.optimizers import Adam
from keras.utils import np_utils
from keras.datasets import mnist

# 数据预处理
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train = x_train.reshape(-1, 28, 28, 1) / 255.0
x_test = x_test.reshape(-1, 28, 28, 1) / 255.0
# 修改数据形状,并将所有输入数据0~1化
y_train = np_utils.to_categorical(y_train, num_classes=10)
y_test = np_utils.to_categorical(y_test, num_classes=10)
# 将所有结果数据设置为独热编码,范围为0~9

# 构建模型
model = Sequential()
# 输入层图片时784数据,设置偏置默认为1
model.add(Convolution2D(  # 添加卷积层
  input_shape=(28, 28, 1),  # 数据格式:(行, 列, 通道数)
  filters=32,  # 滤波器个数
  kernel_size=5, # 卷积窗口大小,这里是5*5
  strides=2, # 步长
  padding='same', # padding方式:same/valid
  bias_initializer="one",
  activation='tanh' # 激活函数
))
model.add(MaxPooling2D(  # 添加池化层
  pool_size=2, # 池化窗口大小:2*2
  strides=2, # 步长
  padding='same'  # padding方式
))
model.add(Convolution2D(filters=64, kernel_size=5, strides=1, padding='same', activation='tanh'))
# 第二次特征图变小了,因此增加滤波器并减小步长
model.add(MaxPooling2D(pool_size=2, strides=2, padding='same'))
model.add(Flatten())
# model.add(Dropout(0.5))
model.add(Dense(units=10, activation='softmax'))
adam = Adam(lr=0.001)
model.compile(optimizer=adam, loss='mse', metrics=["accuracy"])
# model.summary()

# 训练数据
model.fit(x_train, y_train, batch_size=64, epochs=10)
# 速度会慢点,结果大概99+

# 评估模型
model.evaluate(x_test, y_test)
# 结果大概98+

# 预测数据
print(model.predict(x_train[0].reshape(1, 28, 28, 1)).argmax())
print(y_train.argmax())
# 可以发现两个结果都为5,说明预测正确

其他教程参考

https://github.com/erhwenkuo/deep-learning-with-keras-notebooks/blob/master/1.1-keras-functional-api.ipynb

实例参考

验证码识别

https://nbviewer.jupyter.org/github/erhwenkuo/deep-learning-with-keras-notebooks/blob/master/2.5-use-keras-break-captcha.ipynb
https://ypw.io/captcha/

你可能感兴趣的:(Keras框架使用)