框架介绍
相当于封装后的神经网络框架,底层基于TensorFlow等其他神经网络框架运行(因此需要先安装对应的底层框架),使用该框架能够很简易的实现神经网络对应的代码、但相对的运行速度也会慢一些
安装
pip install keras
(需要先安装别的底层框架,如:pip install tensorflow
)
官方中文文档地址
https://keras.io/zh/
使用介绍
使用步骤
1.导入相关模块
from keras.models import Sequential
# 导入最简单的顺序模型(即按顺序一层一层的添加层的那种)
from keras.layers import Dense
# 导入全连接层
2.创建训练数据x_train
、y_train
以及测试数据x_test
、y_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_size
和epochs
理解:比如有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/