开始使用 Keras 顺序 (Sequential) 模型

顺序模型是多个网络层的线性堆叠。

你可以通过将层的列表传递给 Sequential 的构造函数,来创建一个 Sequential 模型:

  1. from keras.models import Sequential
  2. from keras.layers import Dense, Activation
  3. model = Sequential([
  4. Dense(32, input_shape=(784,)),
  5. Activation('relu'),
  6. Dense(10),
  7. Activation('softmax'),
  8. ])

也可以使用 .add() 方法将各层添加到模型中:

  1. model = Sequential()
  2. model.add(Dense(32, input_dim=784))
  3. model.add(Activation('relu'))

指定输入数据的尺寸

模型需要知道它所期望的输入的尺寸。出于这个原因,顺序模型中的第一层(只有第一层,因为下面的层可以自动地推断尺寸)需要接收关于其输入尺寸的信息。有几种方法来做到这一点:

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

因此,下面的代码片段是等价的:

  1. model = Sequential()
  2. model.add(Dense(32, input_shape=(784,)))
  1. model = Sequential()
  2. model.add(Dense(32, input_dim=784))

编译

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

  • 优化器 optimizer。它可以是现有优化器的字符串标识符,如 rmspropadagrad,也可以是 Optimizer 类的实例。详见:optimizers
  • 损失函数 loss,模型试图最小化的目标函数。它可以是现有损失函数的字符串标识符,如 categorical_crossentropymse,也可以是一个目标函数。详见:losses
  • 评估标准 metrics。对于任何分类问题,你都希望将其设置为 metrics = ['accuracy']。评估标准可以是现有的标准的字符串标识符,也可以是自定义的评估标准函数。
  1. # 多分类问题
  2. model.compile(optimizer='rmsprop',
  3. loss='categorical_crossentropy',
  4. metrics=['accuracy'])
  5. # 二分类问题
  6. model.compile(optimizer='rmsprop',
  7. loss='binary_crossentropy',
  8. metrics=['accuracy'])
  9. # 均方误差回归问题
  10. model.compile(optimizer='rmsprop',
  11. loss='mse')
  12. # 自定义评估标准函数
  13. import keras.backend as K
  14. def mean_pred(y_true, y_pred):
  15. return K.mean(y_pred)
  16. model.compile(optimizer='rmsprop',
  17. loss='binary_crossentropy',
  18. metrics=['accuracy', mean_pred])

训练

Keras 模型在输入数据和标签的 Numpy 矩阵上进行训练。为了训练一个模型,你通常会使用 fit 函数。文档详见此处

  1. # 对于具有2个类的单输入模型(二进制分类):
  2. model = Sequential()
  3. model.add(Dense(32, activation='relu', input_dim=100))
  4. model.add(Dense(1, activation='sigmoid'))
  5. model.compile(optimizer='rmsprop',
  6. loss='binary_crossentropy',
  7. metrics=['accuracy'])
  8. # 生成虚拟数据
  9. import numpy as np
  10. data = np.random.random((1000, 100))
  11. labels = np.random.randint(2, size=(1000, 1))
  12. # 训练模型,以 32 个样本为一个 batch 进行迭代
  13. model.fit(data, labels, epochs=10, batch_size=32)
  1. # 对于具有10个类的单输入模型(多分类分类):
  2. model = Sequential()
  3. model.add(Dense(32, activation='relu', input_dim=100))
  4. model.add(Dense(10, activation='softmax'))
  5. model.compile(optimizer='rmsprop',
  6. loss='categorical_crossentropy',
  7. metrics=['accuracy'])
  8. # 生成虚拟数据
  9. import numpy as np
  10. data = np.random.random((1000, 100))
  11. labels = np.random.randint(10, size=(1000, 1))
  12. # 将标签转换为分类的 one-hot 编码
  13. one_hot_labels = keras.utils.to_categorical(labels, num_classes=10)
  14. # 训练模型,以 32 个样本为一个 batch 进行迭代
  15. model.fit(data, one_hot_labels, epochs=10, batch_size=32)

例子

这里有几个可以帮助你开始的例子!

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

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

…等等。

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

  1. import keras
  2. from keras.models import Sequential
  3. from keras.layers import Dense, Dropout, Activation
  4. from keras.optimizers import SGD
  5. # 生成虚拟数据
  6. import numpy as np
  7. x_train = np.random.random((1000, 20))
  8. y_train = keras.utils.to_categorical(np.random.randint(10, size=(1000, 1)), num_classes=10)
  9. x_test = np.random.random((100, 20))
  10. y_test = keras.utils.to_categorical(np.random.randint(10, size=(100, 1)), num_classes=10)
  11. model = Sequential()
  12. # Dense(64) 是一个具有 64 个隐藏神经元的全连接层。
  13. # 在第一层必须指定所期望的输入数据尺寸:
  14. # 在这里,是一个 20 维的向量。
  15. model.add(Dense(64, activation='relu', input_dim=20))
  16. model.add(Dropout(0.5))
  17. model.add(Dense(64, activation='relu'))
  18. model.add(Dropout(0.5))
  19. model.add(Dense(10, activation='softmax'))
  20. sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
  21. model.compile(loss='categorical_crossentropy',
  22. optimizer=sgd,
  23. metrics=['accuracy'])
  24. model.fit(x_train, y_train,
  25. epochs=20,
  26. batch_size=128)
  27. score = model.evaluate(x_test, y_test, batch_size=128)

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

  1. import numpy as np
  2. from keras.models import Sequential
  3. from keras.layers import Dense, Dropout
  4. # 生成虚拟数据
  5. x_train = np.random.random((1000, 20))
  6. y_train = np.random.randint(2, size=(1000, 1))
  7. x_test = np.random.random((100, 20))
  8. y_test = np.random.randint(2, size=(100, 1))
  9. model = Sequential()
  10. model.add(Dense(64, input_dim=20, activation='relu'))
  11. model.add(Dropout(0.5))
  12. model.add(Dense(64, activation='relu'))
  13. model.add(Dropout(0.5))
  14. model.add(Dense(1, activation='sigmoid'))
  15. model.compile(loss='binary_crossentropy',
  16. optimizer='rmsprop',
  17. metrics=['accuracy'])
  18. model.fit(x_train, y_train,
  19. epochs=20,
  20. batch_size=128)
  21. score = model.evaluate(x_test, y_test, batch_size=128)

类似 VGG 的卷积神经网络:

  1. import numpy as np
  2. import keras
  3. from keras.models import Sequential
  4. from keras.layers import Dense, Dropout, Flatten
  5. from keras.layers import Conv2D, MaxPooling2D
  6. from keras.optimizers import SGD
  7. # 生成虚拟数据
  8. x_train = np.random.random((100, 100, 100, 3))
  9. y_train = keras.utils.to_categorical(np.random.randint(10, size=(100, 1)), num_classes=10)
  10. x_test = np.random.random((20, 100, 100, 3))
  11. y_test = keras.utils.to_categorical(np.random.randint(10, size=(20, 1)), num_classes=10)
  12. model = Sequential()
  13. # 输入: 3 通道 100x100 像素图像 -> (100, 100, 3) 张量。
  14. # 使用 32 个大小为 3x3 的卷积滤波器。
  15. model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(100, 100, 3)))
  16. model.add(Conv2D(32, (3, 3), activation='relu'))
  17. model.add(MaxPooling2D(pool_size=(2, 2)))
  18. model.add(Dropout(0.25))
  19. model.add(Conv2D(64, (3, 3), activation='relu'))
  20. model.add(Conv2D(64, (3, 3), activation='relu'))
  21. model.add(MaxPooling2D(pool_size=(2, 2)))
  22. model.add(Dropout(0.25))
  23. model.add(Flatten())
  24. model.add(Dense(256, activation='relu'))
  25. model.add(Dropout(0.5))
  26. model.add(Dense(10, activation='softmax'))
  27. sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
  28. model.compile(loss='categorical_crossentropy', optimizer=sgd)
  29. model.fit(x_train, y_train, batch_size=32, epochs=10)
  30. score = model.evaluate(x_test, y_test, batch_size=32)

基于 LSTM 的序列分类:

  1. from keras.models import Sequential
  2. from keras.layers import Dense, Dropout
  3. from keras.layers import Embedding
  4. from keras.layers import LSTM
  5. model = Sequential()
  6. model.add(Embedding(max_features, output_dim=256))
  7. model.add(LSTM(128))
  8. model.add(Dropout(0.5))
  9. model.add(Dense(1, activation='sigmoid'))
  10. model.compile(loss='binary_crossentropy',
  11. optimizer='rmsprop',
  12. metrics=['accuracy'])
  13. model.fit(x_train, y_train, batch_size=16, epochs=10)
  14. score = model.evaluate(x_test, y_test, batch_size=16)

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

  1. from keras.models import Sequential
  2. from keras.layers import Dense, Dropout
  3. from keras.layers import Embedding
  4. from keras.layers import Conv1D, GlobalAveragePooling1D, MaxPooling1D
  5. model = Sequential()
  6. model.add(Conv1D(64, 3, activation='relu', input_shape=(seq_length, 100)))
  7. model.add(Conv1D(64, 3, activation='relu'))
  8. model.add(MaxPooling1D(3))
  9. model.add(Conv1D(128, 3, activation='relu'))
  10. model.add(Conv1D(128, 3, activation='relu'))
  11. model.add(GlobalAveragePooling1D())
  12. model.add(Dropout(0.5))
  13. model.add(Dense(1, activation='sigmoid'))
  14. model.compile(loss='binary_crossentropy',
  15. optimizer='rmsprop',
  16. metrics=['accuracy'])
  17. model.fit(x_train, y_train, batch_size=16, epochs=10)
  18. score = model.evaluate(x_test, y_test, batch_size=16)

基于栈式 LSTM 的序列分类

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

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

stacked LSTM

  1. from keras.models import Sequential
  2. from keras.layers import LSTM, Dense
  3. import numpy as np
  4. data_dim = 16
  5. timesteps = 8
  6. num_classes = 10
  7. # 期望输入数据尺寸: (batch_size, timesteps, data_dim)
  8. model = Sequential()
  9. model.add(LSTM(32, return_sequences=True,
  10. input_shape=(timesteps, data_dim))) # 返回维度为 32 的向量序列
  11. model.add(LSTM(32, return_sequences=True)) # 返回维度为 32 的向量序列
  12. model.add(LSTM(32)) # 返回维度为 32 的单个向量
  13. model.add(Dense(10, activation='softmax'))
  14. model.compile(loss='categorical_crossentropy',
  15. optimizer='rmsprop',
  16. metrics=['accuracy'])
  17. # 生成虚拟训练数据
  18. x_train = np.random.random((1000, timesteps, data_dim))
  19. y_train = np.random.random((1000, num_classes))
  20. # 生成虚拟验证数据
  21. x_val = np.random.random((100, timesteps, data_dim))
  22. y_val = np.random.random((100, num_classes))
  23. model.fit(x_train, y_train,
  24. batch_size=64, epochs=5,
  25. validation_data=(x_val, y_val))

带有状态 (stateful) 的 相同的栈式 LSTM 模型

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

你可以在 FAQ 中查找更多关于 stateful RNNs 的信息。

  1. from keras.models import Sequential
  2. from keras.layers import LSTM, Dense
  3. import numpy as np
  4. data_dim = 16
  5. timesteps = 8
  6. num_classes = 10
  7. batch_size = 32
  8. # 期望输入数据尺寸: (batch_size, timesteps, data_dim)
  9. # 请注意,我们必须提供完整的 batch_input_shape,因为网络是有状态的。
  10. # 第 k 批数据的第 i 个样本是第 k-1 批数据的第 i 个样本的后续。
  11. model = Sequential()
  12. model.add(LSTM(32, return_sequences=True, stateful=True,
  13. batch_input_shape=(batch_size, timesteps, data_dim)))
  14. model.add(LSTM(32, return_sequences=True, stateful=True))
  15. model.add(LSTM(32, stateful=True))
  16. model.add(Dense(10, activation='softmax'))
  17. model.compile(loss='categorical_crossentropy',
  18. optimizer='rmsprop',
  19. metrics=['accuracy'])
  20. # 生成虚拟训练数据
  21. x_train = np.random.random((batch_size * 10, timesteps, data_dim))
  22. y_train = np.random.random((batch_size * 10, num_classes))
  23. # 生成虚拟验证数据
  24. x_val = np.random.random((batch_size * 3, timesteps, data_dim))
  25. y_val = np.random.random((batch_size * 3, num_classes))
  26. model.fit(x_train, y_train,
  27. batch_size=batch_size, epochs=5, shuffle=False,
  28. validation_data=(x_val, y_val))