Keras Sequential顺序模型

Keras Sequential顺序模型

keras是基于tensorflow封装的的高级API,Keras的优点是可以快速的开发实验,它能够以TensorFlowCNTK, 或者 Theano 作为后端运行。

模型构建

最简单的模型是 Sequential 顺序模型,它由多个网络层线性堆叠。对于更复杂的结构,你应该使用 Keras 函数式 API,它允许构建任意的神经网络图。

用Keras定义网络模型有两种方式,

1、Sequential 顺序模型

from keras.models import Sequential

model = Sequential()

我们可以通过将网络层实例的列表传递给 Sequential 的构造器,来创建一个 Sequential模型,:

from keras.models import Sequential
from keras.layers import Dense, Activation

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

也可以通过 .add()的方法将各层添加到网络中

from keras.layers import Dense
from keras.model import Sequential

model = Sequential()
model.add(Dense(units=64, activation='relu', input_dim=100))
model.add(Dense(units=10, activation='softmax'))

模型需要知道它所期望的出入尺寸,所以模型中的第一层需要接收关于出入尺寸的信息

  • 传递一个 input_shape 参数给第一层。它是一个表示尺寸的元组 (一个整数或 None 的元组,其中 None 表示可能为任何正整数)。在 input_shape 中不包含数据的 batch 大小。
  • 某些 2D 层,例如 Dense,支持通过参数 input_dim 指定输入尺寸,某些 3D 时序层支持 input_dim 和 input_length 参数。
  • 如果你需要为你的输入指定一个固定的 batch 大小(这对 stateful RNNs 很有用),你可以传递一个 batch_size 参数给一个层。如果你同时将 batch_size=32 和 input_shape=(6, 8) 传递给一个层,那么每一批输入的尺寸就为 (32,6,8)
model.add(Dense(32, input_shape=(784,)))
# 这两段代码是等价的 
model.add(Dense(32, input_dim=784))

 Dense的参数

activation: **函数

kernel_initializer和bias_initializer: 创建层权重的初始化方案

kernel_initializer和bias_initializer: 应用层权重的正则方案,L1或L2

Keras Sequential顺序模型Keras Sequential顺序模型
layers.Dense(64, activation='sigmoid')
# 或者
layers.Dense(64, activation=tf.sigmoid)

# 一个线性层,系数0.01的l1正则化权重
layers.Dense(64, kernel_regularizer=tf.keras.regularizers.l1(0.01))
# 将因子0.01的L2正则化的线性层应用于偏置项
layers.Dense(64, bias_regularizer=tf.keras.regularizers.l2(0.01))
# 初始化为随机正交矩阵的线性层
layers.Dense(64, kernel_initializer='orthogonal')    
# 一个线性层,偏置项初始化为2.0s
layers.Dense(64, bias_initializer=tf.keras.initializers.constant(2.0))    
View Code

Model类模型的方法

Model主要有以下方法 compile、fit、evaluate、predict...

在函数式API中,给定一些输入张量和输出张量,可以实例化一个Model:

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)

这个model模型包含从a到b计算的所有网络层

在多输入或多输出模型的情况下,我们可以使用以下列表

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

模型编译

我们需要配置模型的学习过程,这是通过 compile() 方法

参数

  • 优化器 optimizer。它可以是现有优化器的字符串标识符。详见:optimizers
  • 损失函数 loss,模型试图最小化的目标函数。它可以是现有损失函数的字符串标识符,也可以是一个目标函数。常见的选择包括均方误差(mse)、categorical_crossentropy 和 binary_crossentropy,详见:losses
  • 评估标准 metrics。对于任何分类问题,你都希望将其设置为 metrics = ['accuracy']。评估标准可以是现有的标准的字符串标识符,也可以是自定义的评估标准函数。
# 多分类问题
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])

自定义评估标准方法,传了两个方法进去,那到底该用哪个呢?

模型训练

训练网络模型时,我们通常会使用 fit() 函数,keras.Model.fit()包含三个重要的参数,文档详见此处

  • epochs:训练的轮次,每一轮对整个输入数据进行一次迭代
  • batch_size:将模型数据分成n个较小的批次,注意:如果样本总数不能被批次大小整除,则最后一个批次可能更小
  • validation_data:验证数据的准确率 输入和标签的元组

训练模型:现在我们可以批量地在训练数据上迭代了:

model.fit(x_train, y_train, epochs=5, batch_size=32)

或者我们可以手动的将批次的数据提供给模型:

model.train_on_batch(x_batch, y_batch)

对于具有 2 个类的单输入模型(二进制分类):

model = Sequential()
model.add(Dense(32, activation='relu', input_dim=100))
model.add(Dense(1, activation='sigmoid'))
model.compile(optimizer='rmsprop',
              loss='binary_crossentropy',
              metrics=['accuracy'])

# 生成虚拟数据
import numpy as np
data = np.random.random((1000, 100))    # 0~1之间的随机数
# 生成2个类别的(1000,1)的数组
labels = np.random.randint(2, size=(1000, 1))

# 训练模型,以 32 个样本为一个 batch 进行迭代
model.fit(data, labels, epochs=10, batch_size=32)

对于具有 10 个类的单输入模型(多分类分类):

model = Sequential()
model.add(Dense(32, activation='relu', input_dim=100))
model.add(Dense(10, activation='softmax'))
model.compile(optimizer='rmsprop',
              loss='categorical_crossentropy',
              metrics=['accuracy'])

# 生成虚拟数据
import numpy as np
data = np.random.random((1000, 100))
labels = np.random.randint(10, size=(1000, 1))

# 将标签转换为分类的 one-hot 编码
one_hot_labels = keras.utils.to_categorical(labels, num_classes=10)

# 训练模型,以 32 个样本为一个 batch 进行迭代
model.fit(data, one_hot_labels, epochs=10, batch_size=32)

模型评估

evaluate

model.evaluate(x=None, y=None, batch_size=None, verbose=1, sample_weight=None, steps=None)

loss_and_metrics = model.evaluate(x_test, y_test, batch_size=128)

在测试模式下返回模型的误差值和评估标准值,计算是分批次进行的

参数

X: 测试数据的Numpy数组

y: 目标(标签)数据的Numpy数组或列表

batch_size: 整数或None,每次评估的样本数,如果未指定,默认为32

vebose: 0或1,日志显示模型,0=安静模型,1=进度条

steps: 声明评估结束之前的总步数(批次样本)。默认值 None

返回

测试数据的误差值

predict

predict(x, batch_size=None, verbose=0, steps=None)

classes = model.predict(x_test, batch_size=128)
# [11.43181880315145, 0.18333333333333332]

为输入样本生成输出预测,计算是分批进行的

参数

X: 输入数据的Numpy数组

batch_size: 整数,如果未指定,默认为32

verbose: 日志显示模式,0或1

steps: 声明预测结束之前的总步数,默认为 None

返回:

预测的Numpy数组

train_on_batch

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

train_on_batch(x_train, y_train)

进行一批样本的单次梯度更新,在一批样本上训练数据

参数

X: 训练数据的Numpy数组

Y: 目标(标签)的Numpy数组

sample_weight: 可选数组,与x长度相同,包含应用到模型损失函数的每个样本的权重

chass_weight: 可选字典,以在训练时对模型的损失函数加权

返回

训练数据的误差值

test_on_batch

test_on_batch(x_test, y_teat, sample_weight=None)

在一批样本上测试模型

参数

X: 测试数据的Numpy数组

y: 目标(标签)数据的numpy数组

返回

测试数据的误差值

predict_on_batch

predict_on_batch(x)

返回一批样本的模型预测值

参数

X: 输入数据的Numpy

返回:

预测值的Numpy数组

样例

在 examples 目录 中,你可以找到真实数据集的示例模型:

  • CIFAR10 小图片分类:具有实时数据增强的卷积神经网络 (CNN)
  • IMDB 电影评论情感分类:基于词序列的 LSTM
  • Reuters 新闻主题分类:多层感知器 (MLP)
  • MNIST 手写数字分类:MLP & CNN
  • 基于 LSTM 的字符级文本生成

...以及更多。

基于多层感知器 (MLP) 的 softmax 多分类:

Keras Sequential顺序模型Keras Sequential顺序模型
import keras
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation
from keras.optimizers import SGD

# 生成虚拟数据
import numpy as np
x_train = np.random.random((1000, 20))
y_train = keras.utils.to_categorical(np.random.randint(10, size=(1000, 1)), num_classes=10)
x_test = np.random.random((100, 20))
y_test = keras.utils.to_categorical(np.random.randint(10, size=(100, 1)), num_classes=10)

model = Sequential()
# Dense(64) 是一个具有 64 个隐藏神经元的全连接层。
# 在第一层必须指定所期望的输入数据尺寸:
# 在这里,是一个 20 维的向量。
model.add(Dense(64, activation='relu', input_dim=20))
model.add(Dropout(0.5))
model.add(Dense(64, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(10, activation='softmax'))

sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='categorical_crossentropy',
              optimizer=sgd,
              metrics=['accuracy'])

model.fit(x_train, y_train,
          epochs=20,
          batch_size=128)
score = model.evaluate(x_test, y_test, batch_size=128)
View Code

基于多层感知机的二分类:

Keras Sequential顺序模型Keras Sequential顺序模型
import numpy as np
from keras.models import Sequential
from keras.layers import Dense, Dropout

# 生成虚拟数据
x_train = np.random.random((1000, 20))
y_train = np.random.randint(2, size=(1000, 1))
x_test = np.random.random((100, 20))
y_test = np.random.randint(2, size=(100, 1))

model = Sequential()
model.add(Dense(64, input_dim=20, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(64, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))

model.compile(loss='binary_crossentropy',
              optimizer='rmsprop',
              metrics=['accuracy'])

model.fit(x_train, y_train,
          epochs=20,
          batch_size=128)
score = model.evaluate(x_test, y_test, batch_size=128)
View Code

类似VGG的卷积神经网络:

Keras Sequential顺序模型Keras Sequential顺序模型
import numpy as np
import keras
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras.optimizers import SGD

# 生成虚拟数据
x_train = np.random.random((100, 100, 100, 3))
y_train = keras.utils.to_categorical(np.random.randint(10, size=(100, 1)), num_classes=10)
x_test = np.random.random((20, 100, 100, 3))
y_test = keras.utils.to_categorical(np.random.randint(10, size=(20, 1)), num_classes=10)

model = Sequential()
# 输入: 3 通道 100x100 像素图像 -> (100, 100, 3) 张量。
# 使用 32 个大小为 3x3 的卷积滤波器。
model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(100, 100, 3)))
model.add(Conv2D(32, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

model.add(Flatten())
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(10, activation='softmax'))

sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='categorical_crossentropy', optimizer=sgd)

model.fit(x_train, y_train, batch_size=32, epochs=10)
score = model.evaluate(x_test, y_test, batch_size=32)
View Code

基于LSTM的序列分类:

Keras Sequential顺序模型Keras Sequential顺序模型
from keras.models import Sequential
from keras.layers import Dense, Dropout
from keras.layers import Embedding
from keras.layers import LSTM

max_features = 1024

model = Sequential()
model.add(Embedding(max_features, output_dim=256))
model.add(LSTM(128))
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))

model.compile(loss='binary_crossentropy',
              optimizer='rmsprop',
              metrics=['accuracy'])

model.fit(x_train, y_train, batch_size=16, epochs=10)
score = model.evaluate(x_test, y_test, batch_size=16)
View Code

基于 1D 卷积的序列分类:

Keras Sequential顺序模型Keras Sequential顺序模型
from keras.models import Sequential
from keras.layers import Dense, Dropout
from keras.layers import Embedding
from keras.layers import Conv1D, GlobalAveragePooling1D, MaxPooling1D

seq_length = 64

model = Sequential()
model.add(Conv1D(64, 3, activation='relu', input_shape=(seq_length, 100)))
model.add(Conv1D(64, 3, activation='relu'))
model.add(MaxPooling1D(3))
model.add(Conv1D(128, 3, activation='relu'))
model.add(Conv1D(128, 3, activation='relu'))
model.add(GlobalAveragePooling1D())
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))

model.compile(loss='binary_crossentropy',
              optimizer='rmsprop',
              metrics=['accuracy'])

model.fit(x_train, y_train, batch_size=16, epochs=10)
score = model.evaluate(x_test, y_test, batch_size=16)
View Code

基于栈式 LSTM 的序列分类:

在这个模型中,我们将 3 个 LSTM 层叠在一起,使模型能够学习更高层次的时间表示。

前两个 LSTM 返回完整的输出序列,但最后一个只返回输出序列的最后一步,从而降低了时间维度(即将输入序列转换成单个向量)。

Keras Sequential顺序模型

Keras Sequential顺序模型Keras Sequential顺序模型
from keras.models import Sequential
from keras.layers import LSTM, Dense
import numpy as np

data_dim = 16
timesteps = 8
num_classes = 10

# 期望输入数据尺寸: (batch_size, timesteps, data_dim)
model = Sequential()
model.add(LSTM(32, return_sequences=True,
               input_shape=(timesteps, data_dim)))  # 返回维度为 32 的向量序列
model.add(LSTM(32, return_sequences=True))  # 返回维度为 32 的向量序列
model.add(LSTM(32))  # 返回维度为 32 的单个向量
model.add(Dense(10, activation='softmax'))

model.compile(loss='categorical_crossentropy',
              optimizer='rmsprop',
              metrics=['accuracy'])

# 生成虚拟训练数据
x_train = np.random.random((1000, timesteps, data_dim))
y_train = np.random.random((1000, num_classes))

# 生成虚拟验证数据
x_val = np.random.random((100, timesteps, data_dim))
y_val = np.random.random((100, num_classes))

model.fit(x_train, y_train,
          batch_size=64, epochs=5,
          validation_data=(x_val, y_val))
View Code

"stateful" 渲染的的栈式 LSTM 模型

有状态 (stateful) 的循环神经网络模型中,在一个 batch 的样本处理完成后,其内部状态(记忆)会被记录并作为下一个 batch 的样本的初始状态。这允许处理更长的序列,同时保持计算复杂度的可控性。stateful RNNs

Keras Sequential顺序模型Keras Sequential顺序模型
from keras.models import Sequential
from keras.layers import LSTM, Dense
import numpy as np

data_dim = 16
timesteps = 8
num_classes = 10
batch_size = 32

# 期望输入数据尺寸: (batch_size, timesteps, data_dim)
# 请注意,我们必须提供完整的 batch_input_shape,因为网络是有状态的。
# 第 k 批数据的第 i 个样本是第 k-1 批数据的第 i 个样本的后续。
model = Sequential()
model.add(LSTM(32, return_sequences=True, stateful=True,
               batch_input_shape=(batch_size, timesteps, data_dim)))
model.add(LSTM(32, return_sequences=True, stateful=True))
model.add(LSTM(32, stateful=True))
model.add(Dense(10, activation='softmax'))

model.compile(loss='categorical_crossentropy',
              optimizer='rmsprop',
              metrics=['accuracy'])

# 生成虚拟训练数据
x_train = np.random.random((batch_size * 10, timesteps, data_dim))
y_train = np.random.random((batch_size * 10, num_classes))

# 生成虚拟验证数据
x_val = np.random.random((batch_size * 3, timesteps, data_dim))
y_val = np.random.random((batch_size * 3, num_classes))

model.fit(x_train, y_train,
          batch_size=batch_size, epochs=5, shuffle=False,
          validation_data=(x_val, y_val))
View Code

 

posted @ 2019-01-16 09:38 凌逆战 阅读(...) 评论(...) 编辑 收藏