Keras系列(二)
Keras基础指南
建立一个简单的模型
SEQUENTIAL MODEL
在Keras中,可以通过组装层(layer)来构建模型(models)。模型(通常)是层的图形。最常见的模型类型是层的堆栈:序列模型(sequential model)。
下面的代码构建了一个简单的、完全连接(layer_dense)的网络(即一个多层感知器):
model %>%
layer_dense(units = 64, activation = 'relu') %>% # Adds a densely-connected layer with 64 units to the model
layer_dense(units = 64, activation = 'relu') %>% # Add another densely-connected layer with 64 units to the model
layer_dense(units = 10, activation = 'softmax') # Add a softmax layer with 10 output units
CONFIGURE THE LAYERS
有许多层可以使用一些常见的构造函数参数(constructor parameters):
-
activation: 设置层的激活函数(activation function),缺省情况下,未应用激活函数。
-
kernel_initializer 和 bias_initializer: 创建层的权重值(包括内核(kernek)和偏差(bias))的初始化方案。这默认为 Glorot uniform 初始化工具。
-
kernel_regularizer 和 bias_regularizer: 适用于层的权重值(核和偏差)的正则化(regularization)方案,如L1或L2正则化。缺省情况下,不应用正则化。
下面的例子使用构造函数参数来实例化一组密集层:
layer_dense(units = 64, activation ='sigmoid')
# A linear layer with L1 regularization of factor 0.01 applied to the kernel matrix:
layer_dense(units = 64, kernel_regularizer = regularizer_l1(0.01))
# A linear layer with L2 regularization of factor 0.01 applied to the bias vector:
layer_dense(units = 64, bias_regularizer = regularizer_l2(0.01))
# A linear layer with a kernel initialized to a random orthogonal matrix:
layer_dense(units = 64, kernel_initializer = 'orthogonal')
# A linear layer with a bias vector initialized to 2.0
layer_dense(units = 64, kernel_initializer = c(2.0))
训练和评估
SET UP TRAINING
型构建完成后,通过调用compile方法配置其学习过程:
optimizer = 'adam',
loss = 'categorical_crossentropy',
metrics = list('accuracy')
compile接受三个重要参数:
-
optimizer: 优化器,设定用来加速训练的优化方法,基本都是基于梯度下降的,只是细 节上有些差异。常用的优化器有adam、rmsprop或sgd。
-
loss: 损失函数,指定优化过程中最小化的函数(即指示优化的指标)。常见的选择包括均方误差(mean square erro,mse)、分类交叉熵(categorical_crossentropy)和二进制交叉熵(binary_crossentropy)。
-
metrics: 用来监督训练过程,在分类问题中,通常设置为准确性(accuracy)。
以下是一些配置训练模型的示例:
model %>% compile(
optimizer = 'adam',
# mean squared error
loss = 'mse',
# mean absolute error
metrics = list('mae')
)
# Configure a model for categorical classification.
model %>% compile(
optimizer = optimizer_rmsprop(lr = 0.01),
loss = "categorical_crossentropy",
metrics = list("categorical_accuracy")
)
INPUT DATA
您可以直接在R矩阵(matrices)和数组(array)(可能从R data.frames创建)上训练keras模型。使用fit方法对训练数据拟合模型:
labels <- matrix(rnorm(1000 * 10), nrow = 1000, ncol = 10)
model %>% fit( data, labels, epochs = 10, batch_size = 32)
fit有三个重要的参数:
-
epochs: epoch是指对整个输入数据的一次迭代(以较小的批量完成),即当一个完整的数据集通过了神经网络一次并且返回了一次,这个过程称为一个 epoch。关于epochs,batchs和 iterations的区别,例如训练集有1000个样本,batchsize=10,那么对整个样本集进行1次epoch需要100次iteration。
-
batch_size: 当传递矩阵或数组数据时,模型将数据分割成指定大小的batch,并在训练期间迭代(iteration)这些batch。batch_size就是指定每个batch的大小。注意,如果样品总数不能被batch大小整除,最后一batch数据量可能会更小。
-
validation_data: 用来设定作为验证数据的训练数据的分比例。设计的函数确保数据以这样一种方式分离,即它总是针对每个epoch训练数据的相同部分。如果该选项被选择,那么所有的洗牌都是在两个epochs之间的训练样本内完成的。
下面是一个使用validation_data的例子:
labels <- matrix(rnorm(1000 * 10), nrow = 1000, ncol = 10)
val_data <- matrix(rnorm(1000 * 32), nrow = 100, ncol = 32)
val_labels <- matrix(rnorm(100 * 10), nrow = 100, ncol = 10)
model %>%
fit(data, labels, epochs = 10, batch_size = 32, validation_data = list(val_data, val_label))
EVALUATE AND PREDICT
与fit一样,评估(evaluate)和预测(predict)方法既可以使用原始数据,也可以使用数据集。
建立复杂的模型
FUNCTIONAL API
sequential 模型是一个简单的层堆栈,不能表示任意模型。使用Keras的 functional API 构建复杂的模型拓扑,例如:
-
多输入模型(multi-input models)
-
多输出模型(multi-output models)
-
具有共享层的模型(同一层多次调用)(models with shared layers)
-
具有非顺序数据流的模型(例如,剩余连接)(models with non-sequential data flows)
使用functional API构建模型的工作原理如下:
-
实例是可调用的,并返回一个张量。
-
输入张量和输出张量用于定义keras_model实例。
-
这个模型就像sequential模型一样进行训练。
下面的例子使用functional API来构建一个简单的、完全连接的网络:
predictions <- inputs %>%
layer_dense(units = 64, activation = 'relu') %>%
layer_dense(units = 64, activation = 'relu') %>%
layer_dense(units = 10, activation = 'softmax')
# Instantiate the model given inputs and outputs.
model <- keras_model(inputs = inputs, outputs = predictions)
# The compile step specifies the training configuration.
model %>%
compile(
optimizer = optimizer_rmsprop(lr = 0.001),
loss = 'categorical_crossentropy',
metrics = list('accuracy') )
# Trains for 5 epochs
model %>%
fit( data, labels, batch_size = 32, epochs = 5)
CUSTOM LAYERS
要创建自定义Keras层,需要创建从KerasLayer派生的R6类(R6 class)。有三个方法需要实现(所有类型的层只需要一个call()函数):
-
build(input_shape): 在这里,您将定义你的权重。 请注意,如果您的图层未定义可训练的权重,则无需实现此方法。
-
call(x): 这就是层的逻辑所在。 除非您希望您的图层支持遮罩,否则您只需关心传递给调用的第一个参数:输入张量。
-
compute_output_shape(input_shape): 如果您的图层修改了其输入的形状,则应在此处指定形状转换逻辑。 这使Keras可以进行自动形状推断。 如果您不修改输入的形状,则无需实现此方法。
下面是一个执行矩阵乘法的自定义层示例:
CustomLayer <- R6::R6Class("CustomLayer",
inherit = KerasLayer,
public = list(
output_dim = NULL,
kernel = NULL,
initialize = function(output_dim) {
self$output_dim <- output_dim
},
build = function(input_shape) {
self$kernel <- self$add_weight(
name = 'kernel',
shape = list(input_shape[[2]], self$output_dim),
initializer = initializer_random_normal(),
trainable = TRUE)
},
call = function(x, mask = NULL) {
k_dot(x, self$kernel)
},
compute_output_shape = function(input_shape) {
list(input_shape[[1]], self$output_dim)
}
))
为了在Keras模型中使用自定义层,您还需要创建一个包装器函数,该函数使用create_layer()函数实例化该层。例如:
layer_custom <- function(object, output_dim, name = NULL, trainable = TRUE) {
create_layer(CustomLayer,
object,
list(output_dim = as.integer(output_dim),
name = name,
trainable = trainable))
}
您现在可以像往常一样在模型中使用该层
model %>%
layer_dense(units = 32, input_shape = c(32,32)) %>%
layer_custom(units = 32, input_shape = c(32,32))
CUSTOM MODELS
除了创建自定义层之外,您还可以创建自定义模型。如果您想要将TensorFlow急切执行与命令式向前传递结合使用,这可能是必要的。
如果不需要这样做,但需要在构建体系结构时保持灵活性,那么建议只使用functional API。
自定义模型是通过调用keras_model_custom()传递一个函数来定义的,该函数指定要创建的层和要在向前传递时执行的操作。
# define and return a custom model
keras_model_custom(name = name, function(self) {
# create layers we'll need for the call (this code executes once) # note: the layers have to be created on the self object!
self$dense1 <- layer_dense(units = 64, activation = 'relu', input_shape = input_dim)
self$dense2 <- layer_dense(units = 64, activation = 'relu')
self$dense3 <- layer_dense(units = 10, activation = 'softmax') # implement call (this code executes during training & inference)
function(inputs, mask = NULL) {
x <- inputs %>%
self$dense1() %>%
self$dense2() %>%
self$dense3()
x
}
})
model <- my_model(input_dim = 32, output_dim = 10)
model %>% compile(
optimizer = optimizer_rmsprop(lr = 0.001),
loss = 'categorical_crossentropy',
metrics = list('accuracy'))
# Trains for 5 epochs
model %>% fit(data, labels, batch_size = 32, epochs = 5)
回调函数
回调函数(Callbacks),是传递给模型的对象,用于在训练期间定制和扩展模型的行为。你可以编写自己的自定义回调函数,或者使用内置的回调函数,包括:
-
callback_model_checkpoint:定期保存模型的检查点。
-
callback_learning_rate_scheduler:动态修改学习速率。
-
callback_early_stop:当验证性能停止改善时的中断训练。
-
callbacks_tensorboard:使用TensorBoard监视模型的行为。
要使用回调,请将它传递给模型的fit方法:
callbacks <- list(
callback_early_stopping(patience = 2, monitor = 'val_loss'),
callback_tensorboard(log_dir = './logs'))
model %>%
fit(data, labels,
batch_size = 32,
epochs = 5,
callbacks = callbacks,
validation_data = list(val_data, val_labels))
保存和恢复
WEIGHTS ONLY
使用save_model_weights_hdf5和 load_model_weights_hdf5 分别用来保存和加载模型的权重。
model %>% save_model_weights_tf('my_model/') # Restore the model's state, # this requires a model with the same architecture.
CONFIGURATION ONLY
模型的配置可以被保存——这样可以在没有任何权重的情况下序列化模型架构。保存的配置可以重新创建并初始化相同的模型,甚至不需要定义原始模型的代码。Keras支持JSON和YAML序列化格式:
json_string <- model %>% model_to_json()
# Recreate the model (freshly initialized)
fresh_model <- model_from_json(json_string)
# Serializes a model to YAML format
yaml_string <- model %>% model_to_yaml()
注意:自定义的模型是不可序列化的,因为它们的体系结构是由传递给keras_model_custom的函数中的R代码定义的。
ENTIRE MODEL
可以将整个模型保存到包含权重值、模型配置甚至优化器配置的文件中。这允许您检查模型并在以后恢复训练——从完全相同的状态——而不需要访问原始代码。
model %>% save_model_tf('my_model/') # Recreate the exact same model, including weights and optimizer.