Keras基础

  1. Keras基础结构
  2. 以mnist数据库为例构建Keras神经网络

参考:

Keras官方文档

Keras中文文档

Sequential顺序模型

核心网络层

优化器(optimizer)

损失函数(loss)

模型方法(训练/测试等)

dropout中noise_shape参数的作用

环境:

操作系统:Ubuntu 18.04

CUDA: 10.0

TensorFLow: 1.13

Keras: 2.3.1

Keras构建神经网络框架

Sequential model (顺序模型)

顺序模型是多个神经网络层的堆叠.

构建方法:
1
2
1. 将网络层构建成列表, 作为参数传入model.Sequential()
 	2. 创建空的Sequential模型后使用model.add()方法向其中添加层
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from keras.models import Sequential
from keras.layers import Dense, Activation

# 方法1
model = Sequential([
    Dense(32, input_shape=(784,)),
    Activation('relu'),
    Dense(10),
    Activation('softmax'),
])

# 方法2
model = Sequential()
model.add(Dense(32, input_dim=784))
model.add(Activation('relu'))
设定输入数据维数

向Sequential模型添加网络层时, 需要在第一层定义输入数据的维数. (仅在第一层需要, 因为后面的层可以自动获取前一层的输出维度)

有以下几种方法:

  1. 在第一层的参数中定义, input_shape = (x, y)
  2. 类似Dense这种2维的层支持通过参数input_dim指定输入尺寸. 某些3维层支持input_dim和input_length参数
  3. 如果需要为输入的数据指定一个固定的batch大小, 可以给层传递一个参数batch_size. 例如: 在第一层的参数中包含 (batch_size = 32, input_shape=(6, 8)), 那么每一批输入第一层的数据维度就是(32, 6, 8)

因此, 下面两种方法是等价的:

1
2
3
4
5
6
7
# 方法1
model = Sequential()
model.add(Dense(32, input_shape=(784,)))

# 方法2
model = Sequential()
model.add(Dense(32, input_dim=784))
模型编译

在训练模型之前, 需要配置学习过程. 这个过程通过compile方法完成. 他接收三个参数:

  1. 优化器(optimizer)
  2. 损失函数(loss)
  3. 评估标准(metrics)

这三个参数可以是现有优化器的字符串标识符, 也可以是具体的函数.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 多分类问题
model.compile(optimizer='rmsprop',
              loss='categorical_crossentropy',
              metrics=['accuracy'])

# 二分类问题
model.compile(optimizer='rmsprop',
              loss='binary_crossentropy',
              metrics=['accuracy'])

# 均方误差回归问题
model.compile(optimizer='rmsprop',
              loss='mse')

# 自定义评估标准函数
import keras.backend as K

def mean_pred(y_true, y_pred):
    return K.mean(y_pred)

model.compile(optimizer='rmsprop',
              loss='binary_crossentropy',
              metrics=['accuracy', mean_pred])
模型训练和验证

使用model.fit()进行模型训练. fit函数的参数包括训练集数据,标签等

使用model.evaluate()进行模型验证, 参数使用测试集数据和标签.

参数versbose用于设置日志现实方式:

  • 0: 不在标准输出流输出日志信息
  • 1: 输出进度条记录
  • 2: 每个epoch输出一行记录
1
2
3
4
5
6
# 训练模型,以 32 个样本为一个 batch 进行迭代
model.fit(data, labels, epochs=10, batch_size=32)

# 模型验证
model.evaluate(x_test, y_test, verbose=2)

模型

自定义模型

给定输入和输出的的张量, 可以创建一个新的模型:

1
2
3
4
5
6
from keras.models import Model
from keras.layers import Input, Dense

a = Input(shape=(32,))
b = Dense(32)(a)
model = Model(inputs=a, outputs=b)

对于多个输入和输出数据, 可以使用列表进行创建:

1
model = Model(inputs=[a1, a2], outputs=[b1, b2, b3])

核心网络层

常用核心层包括 Dense/Activation/Dropout/Flatten. 其余核心层查看官方文档.

Dense

全连接层. 实现以下操作:

1
output = activation(dot(input, kernel) + bias)

其中, activation是激活函数, kernal和bias分别是由网络层创建的权重矩阵和偏置向量.

参数:

  • units: 正整数,输出空间维度。
  • activation: 激活函数 (详见 activations)。 若不指定,则不使用激活函数 (即,「线性」激活: a(x) = x)。
  • use_bias: 布尔值,该层是否使用偏置向量。
  • kernel_initializer: kernel 权值矩阵的初始化器 (详见 initializers)。
  • bias_initializer: 偏置向量的初始化器 (see initializers).
  • kernel_regularizer: 运用到 kernel 权值矩阵的正则化函数 (详见 regularizer)。
  • bias_regularizer: 运用到偏置向的的正则化函数 (详见 regularizer)。
  • activity_regularizer: 运用到层的输出的正则化函数 (它的 “activation”)。 (详见 regularizer)。
  • kernel_constraint: 运用到 kernel 权值矩阵的约束函数 (详见 constraints)。
  • bias_constraint: 运用到偏置向量的约束函数 (详见 constraints)。
Activation

激活函数. 输入尺寸和输出尺寸一致, 都和上一层的输出尺寸相同.

1
keras.layers.Activation(activation)
Dropout

按比例将输入下一层的数据随机设置为0. 有助于防止过拟合.

参数:

Flatten

将输入层展平, 不影响批量的大小

参数:

  • data_format:一个字符串,其值为 channels_last(默认值)或者 channels_first。它表明输入的维度的顺序。此参数的目的是当模型从一种数据格式切换到另一种数据格式时保留权重顺序。channels_last 对应着尺寸为 (batch, ..., channels) 的输入,而 channels_first 对应着尺寸为 (batch, channels, ...) 的输入。默认为 image_data_format 的值,你可以在 Keras 的配置文件 ~/.keras/keras.json 中找到它。如果你从未设置过它,那么它将是 channels_last
1
2
3
4
5
6
7
model = Sequential()
model.add(Conv2D(64, (3, 3),
                 input_shape=(3, 32, 32), padding='same',))
# 现在:model.output_shape == (None, 64, 32, 32)

model.add(Flatten())
# 现在:model.output_shape == (None, 65536)

构建mnist神经网络

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#!/usr/bin/env python
# -*- coding:utf-8 -*-

from keras.models import Sequential
import keras.layers

import numpy as np

path = ".../mnist/data"

# 获取数据集 
x_train = np.load(path + "/x_train.npy")
y_train = np.load(path + "/y_train.npy")
x_test = np.load(path + "/x_test.npy")
y_test = np.load(path + "/y_test.npy")

print(x_train.shape, y_train.shape)

# 数据归一化
x_train, x_test = x_train / 255.0, x_test / 255.0

# 构建模型
model = Sequential([
    keras.layers.Flatten(input_shape=(28, 28)),
    keras.layers.Dense(128, activation='relu'),
    keras.layers.Dropout(0.2),
    keras.layers.Dense(10, activation='softmax')
])

model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

# 训练并验证模型
model.fit(x_train, y_train, epochs=5)

model.evaluate(x_test, y_test, verbose=1)

# 模型结构
model.summary()

# 预测
print(np.argmax(model.predict(x_test)[0]), y_test[0])