Keras FAQ: Frequently Asked Keras Questions


How should I cite Keras?

如果它有助于您的研究,请在您的出版物中引用Keras. 这是一个BibTeX条目示例:

@misc{chollet2015keras,
  title={Keras},
  author={Chollet, Fran\c{c}ois and others},
  year={2015},
  howpublished={\url{https://keras.io}},
}

How can I run Keras on GPU?

如果您在TensorFlowCNTK后端上运行,则如果检测到任何可用的GPU,则代码将自动在GPU上运行.

If you are running on the Theano backend, you can use one of the following methods:

方法1 :使用Theano标志.

THEANO_FLAGS=device=gpu,floatX=float32 python my_keras_script.py

名称" gpu"可能必须根据设备的标识符(例如gpu0gpu1等)进行更改.

方法2 :设置您的.theanorc说明

方法3 :在代码的开头手动设置theano.config.devicetheano.config.floatX

import theano
theano.config.device = 'gpu'
theano.config.floatX = 'float32'

How can I run a Keras model on multiple GPUs?

我们建议使用TensorFlow后端这样做. 在多个GPU上运行单个模型的方法有两种: 数据并行性设备并行性 .

在大多数情况下,您最需要的是数据并行性.

Data parallelism

数据并行性在于在每个设备上复制一次目标模型,并使用每个副本来处理输入数据的不同部分. Keras有一个内置实用程序keras.utils.multi_gpu_model ,可以生成任何模型的数据并行版本,并在多达8个GPU上实现准线性加速.

有关更多信息,请参见multi_gpu_model的文档. 这是一个简单的示例:

from keras.utils import multi_gpu_model

# Replicates `model` on 8 GPUs.
# This assumes that your machine has 8 available GPUs.
parallel_model = multi_gpu_model(model, gpus=8)
parallel_model.compile(loss='categorical_crossentropy',
                       optimizer='rmsprop')

# This `fit` call will be distributed on 8 GPUs.
# Since the batch size is 256, each GPU will process 32 samples.
parallel_model.fit(x, y, epochs=20, batch_size=256)

Device parallelism

设备并行性在于在不同设备上运行同一模型的不同部分. 它最适合具有并行架构的模型,例如具有两个分支的模型.

这可以通过使用TensorFlow设备范围来实现. 这是一个简单的示例:

# Model where a shared LSTM is used to encode two different sequences in parallel
input_a = keras.Input(shape=(140, 256))
input_b = keras.Input(shape=(140, 256))

shared_lstm = keras.layers.LSTM(64)

# Process the first sequence on one GPU
with tf.device_scope('/gpu:0'):
    encoded_a = shared_lstm(tweet_a)
# Process the next sequence on another GPU
with tf.device_scope('/gpu:1'):
    encoded_b = shared_lstm(tweet_b)

# Concatenate results on CPU
with tf.device_scope('/cpu:0'):
    merged_vector = keras.layers.concatenate([encoded_a, encoded_b],
                                             axis=-1)

What does "sample", "batch", "epoch" mean?

以下是正确理解Keras所需了解和理解的一些常见定义:

  • 样本 :数据集的一个元素.
  • 示例:一个图像是卷积网络中的样本
  • 示例:一个音频文件是语音识别模型的样本
  • 批次 :一组N个样本. 一批中的样品被独立,并行处理. 如果进行训练,则批次只会对模型进行一次更新.
  • 批处理通常比单个输入更好地近似输入数据的分布. 批次越大,近似值越好; 但是,也确实,该批处理将花费更长的时间,并且仍然只会导致一次更新. 为了进行推断(评估/预测),建议选择一个尽可能大的批处理大小,而不用占用内存(因为较大的批处理通常会导致更快的评估/预测).
  • 时代 :任意截止时间,通常定义为"一次遍历整个数据集",用于将训练分为不同的阶段,这对日志记录和定期评估很有用.
  • 当通过Keras模型的fit方法使用validation_datavalidation_split时,评估将在每个时期结束时运行.
  • 在Keras中,可以添加专门设计用于在epoch末尾运行的回调的功能. 这些示例包括学习率更改和模型检查点(保存).

How can I save a Keras model?

Saving/loading whole models (architecture + weights + optimizer state)

不建议使用pickle或cPickle保存Keras模型.

您可以使用model.save(filepath)model.save(filepath)模型保存到单个HDF5文件中,该文件包含:

  • 模型的架构,从而可以重新创建模型
  • 模型的权重
  • 训练配置(损失,优化器)
  • 优化程序的状态,从而可以从您上次中断的地方继续正确地进行训练.

然后,您可以使用keras.models.load_model(filepath)重新实例化模型. load_model还将负责使用保存的训练配置来编译模型(除非从未首先编译过模型).

Example:

from keras.models import load_model

model.save('my_model.h5')  # creates a HDF5 file 'my_model.h5'
del model  # deletes the existing model

# returns a compiled model
# identical to the previous one
model = load_model('my_model.h5')

另请参阅如何安装HDF5或h5py将模型保存在Keras中? 有关如何安装h5py .

Saving/loading only a model's architecture

如果只需要保存模型体系结构 ,而不是模型的权重或训练配置,则可以执行以下操作:

# save as JSON
json_string = model.to_json()

# save as YAML
yaml_string = model.to_yaml()

生成的JSON / YAML文件是人类可读的,并且可以根据需要进行手动编辑.

然后,您可以根据以下数据构建新的模型:

# model reconstruction from JSON:
from keras.models import model_from_json
model = model_from_json(json_string)

# model reconstruction from YAML:
from keras.models import model_from_yaml
model = model_from_yaml(yaml_string)

Saving/loading only a model's weights

如果您需要保存模型权重 ,则可以在HDF5中使用以下代码进行保存:

model.save_weights('my_model_weights.h5')

假设您有用于实例化模型的代码,然后可以将保存的权重加载到具有相同架构的模型中:

model.load_weights('my_model_weights.h5')

如果您需要将权重加载到不同的体系结构(共有一些层)中,例如进行微调或转移学习,则可以按层名称加载它们:

model.load_weights('my_model_weights.h5', by_name=True)

Example:

"""
Assuming the original model looks like this:
    model = Sequential()
    model.add(Dense(2, input_dim=3, name='dense_1'))
    model.add(Dense(3, name='dense_2'))
    ...
    model.save_weights(fname)
"""

# new model
model = Sequential()
model.add(Dense(2, input_dim=3, name='dense_1'))  # will be loaded
model.add(Dense(10, name='new_dense'))  # will not be loaded

# load weights from first model; will only affect the first layer, dense_1.
model.load_weights(fname, by_name=True)

另请参阅如何安装HDF5或h5py将模型保存在Keras中? 有关如何安装h5py .

Handling custom layers (or other custom objects) in saved models

如果要加载的模型包括自定义图层或其他自定义类或函数,则可以通过custom_objects参数将它们传递给加载机制:

from keras.models import load_model
# Assuming your model includes instance of an "AttentionLayer" class
model = load_model('my_model.h5', custom_objects={'AttentionLayer': AttentionLayer})

另外,您可以使用自定义对象范围

from keras.utils import CustomObjectScope

with CustomObjectScope({'AttentionLayer': AttentionLayer}):
    model = load_model('my_model.h5')

自定义对象处理的工作方式与load_modelmodel_from_jsonmodel_from_yaml

from keras.models import model_from_json
model = model_from_json(json_string, custom_objects={'AttentionLayer': AttentionLayer})

Why is the training loss much higher than the testing loss?

Keras模型具有两种模式:训练和测试. 在测试时会关闭诸如Dropout和L1 / L2权重正则化的正则化机制.

此外,训练损失是每批训练数据损失的平均值. 由于您的模型会随着时间而变化,因此,前几个时期的损失通常高于最后几个时期的损失. 另一方面,一个时期的测试损失是使用模型计算的,因为它处于该时期的末尾,因此损失较低.


How can I obtain the output of an intermediate layer?

一种简单的方法是创建一个新Model ,该Model将输出您感兴趣的图层:

from keras.models import Model

model = ...  # create the original model

layer_name = 'my_layer'
intermediate_layer_model = Model(inputs=model.input,
                                 outputs=model.get_layer(layer_name).output)
intermediate_output = intermediate_layer_model.predict(data)

或者,您可以构建Keras函数,该函数将在给定特定输入的情况下返回特定图层的输出,例如:

from keras import backend as K

# with a Sequential model
get_3rd_layer_output = K.function([model.layers[0].input],
                                  [model.layers[3].output])
layer_output = get_3rd_layer_output([x])[0]

同样,您可以直接构建Theano和TensorFlow函数.

请注意,如果您的模型在训练和测试阶段的行为不同(例如,如果使用DropoutBatchNormalization等),则需要将学习阶段标志传递给函数:

get_3rd_layer_output = K.function([model.layers[0].input, K.learning_phase()],
                                  [model.layers[3].output])

# output in test mode = 0
layer_output = get_3rd_layer_output([x, 0])[0]

# output in train mode = 1
layer_output = get_3rd_layer_output([x, 1])[0]

How can I use Keras with datasets that don't fit in memory?

你可以用做批量训练model.train_on_batch(x, y)model.test_on_batch(x, y) 请参阅模型文档 .

或者,您可以编写一个生成一批训练数据的生成器,并使用model.fit_generator(data_generator, steps_per_epoch, epochs) .

您可以在我们的CIFAR10示例中看到批量培训的实际效果 .


How can I interrupt training when the validation loss isn't decreasing anymore?

您可以使用EarlyStopping回调:

from keras.callbacks import EarlyStopping
early_stopping = EarlyStopping(monitor='val_loss', patience=2)
model.fit(x, y, validation_split=0.2, callbacks=[early_stopping])

回调文档中找到更多信息 .


How is the validation split computed?

如果将model.fitvalidation_split参数设置为例如0.1,则使用的验证数据将是数据的最后10% . 如果将其设置为0.25,则将是数据的最后25%,依此类推.请注意,在提取验证拆分之前,数据不会进行混洗,因此验证实际上只是输入中样本的最后 x%通过了.

所有纪元都使用相同的验证集(在一次调用fit ).


Is the data shuffled during training?

是的,如果将model.fitshuffle参数设置为True (这是默认值),则训练数据将在每个时期随机洗牌.

验证数据永不洗牌.


How can I record the training / validation loss / accuracy at each epoch?

model.fit方法返回一个History回调,该回调具有一个history属性,其中包含连续损失列表和其他度量.

hist = model.fit(x, y, validation_split=0.2)
print(hist.history)

How can I "freeze" Keras layers?

"冻结"层意味着将其从训练中排除,即其权重将永远不会更新. 这在微调模型或为文本输入使用固定嵌入的上下文中很有用.

您可以将trainable参数(布尔值)传递给图层构造函数,以将图层设置为不可训练:

frozen_layer = Dense(32, trainable=False)

此外,您可以在实例化后将图层的trainable属性设置为TrueFalse . 为了使此方法生效,您需要在修改trainable属性后在模型上调用compile() . 这是一个例子:

x = Input(shape=(32,))
layer = Dense(32)
layer.trainable = False
y = layer(x)

frozen_model = Model(x, y)
# in the model below, the weights of `layer` will not be updated during training
frozen_model.compile(optimizer='rmsprop', loss='mse')

layer.trainable = True
trainable_model = Model(x, y)
# with this model the weights of the layer will be updated during training
# (which will also affect the above model since it uses the same layer instance)
trainable_model.compile(optimizer='rmsprop', loss='mse')

frozen_model.fit(data, labels)  # this does NOT update the weights of `layer`
trainable_model.fit(data, labels)  # this updates the weights of `layer`

How can I use stateful RNNs?

使RNN为有状态意味着每个批次的样品状态将重新用作下一批样品的初始状态.

因此,在使用有状态RNN时,假定:

  • 所有批次的样品数量均相同
  • 如果x1x2是连续的样本批次,则x2[i]是每个ix1[i]的后续序列.

要在RNN中使用有状态性,您需要:

  • 通过将batch_size参数传递到模型的第一层,显式指定您正在使用的批处理大小. 例如,对于具有10个时间步长的序列的32个样本的批次,每个时间步长具有16个特征,例如batch_size=32 .
  • 在您的RNN图层中设置stateful=True .
  • 在调用fit()时指定shuffle=False .

要重置累积的状态:

  • 使用model.reset_states()重置模型中所有图层的状态
  • 使用layer.reset_states()重置特定状态RNN层的状态

Example:

x  # this is our input data, of shape (32, 21, 16)
# we will feed it to our model in sequences of length 10

model = Sequential()
model.add(LSTM(32, input_shape=(10, 16), batch_size=32, stateful=True))
model.add(Dense(16, activation='softmax'))

model.compile(optimizer='rmsprop', loss='categorical_crossentropy')

# we train the network to predict the 11th timestep given the first 10:
model.train_on_batch(x[:, :10, :], np.reshape(x[:, 10, :], (32, 16)))

# the state of the network has changed. We can feed the follow-up sequences:
model.train_on_batch(x[:, 10:20, :], np.reshape(x[:, 20, :], (32, 16)))

# let's reset the states of the LSTM layer:
model.reset_states()

# another way to do it in this case:
model.layers[0].reset_states()

请注意,这些方法predictfittrain_on_batchpredict_classes等将全部更新模型中的状态层的状态. 这样,您不仅可以进行状态训练,还可以进行状态预测.


How can I remove a layer from a Sequential model?

您可以通过调用.pop()来删除顺序模型中最后添加的图层:

model = Sequential()
model.add(Dense(32, activation='relu', input_dim=784))
model.add(Dense(32, activation='relu'))

print(len(model.layers))  # "2"

model.pop()
print(len(model.layers))  # "1"

How can I use pre-trained models in Keras?

代码和预先训练的权重可用于以下图像分类模型:

  • Xception
  • VGG16
  • VGG19
  • ResNet
  • ResNet v2
  • ResNeXt
  • 盗梦空间v3
  • Inception-ResNet v2
  • MobileNet v1
  • MobileNet v2
  • DenseNet
  • NASNet

可以从模块keras.applications导入它们:

from keras.applications.xception import Xception
from keras.applications.vgg16 import VGG16
from keras.applications.vgg19 import VGG19
from keras.applications.resnet import ResNet50
from keras.applications.resnet import ResNet101
from keras.applications.resnet import ResNet152
from keras.applications.resnet_v2 import ResNet50V2
from keras.applications.resnet_v2 import ResNet101V2
from keras.applications.resnet_v2 import ResNet152V2
from keras.applications.resnext import ResNeXt50
from keras.applications.resnext import ResNeXt101
from keras.applications.inception_v3 import InceptionV3
from keras.applications.inception_resnet_v2 import InceptionResNetV2
from keras.applications.mobilenet import MobileNet
from keras.applications.mobilenet_v2 import MobileNetV2
from keras.applications.densenet import DenseNet121
from keras.applications.densenet import DenseNet169
from keras.applications.densenet import DenseNet201
from keras.applications.nasnet import NASNetLarge
from keras.applications.nasnet import NASNetMobile

model = VGG16(weights='imagenet', include_top=True)

有关一些简单的用法示例,请参见Applications模块的文档 .

有关如何使用这种经过预训练的模型进行特征提取或微调的详细示例,请参阅此博客文章 .

VGG16模型也是几个Keras示例脚本的基础:


How can I use HDF5 inputs with Keras?

您可以使用HDF5Matrix类从keras.utils . 有关详细信息,请参见HDF5Matrix文档 .

您还可以直接使用HDF5数据集:

import h5py
with h5py.File('input/file.hdf5', 'r') as f:
    x_data = f['x_data']
    model.predict(x_data)

另请参阅如何安装HDF5或h5py将模型保存在Keras中? 有关如何安装h5py .


Where is the Keras configuration file stored?

存储所有Keras数据的默认目录是:

$HOME/.keras/

请注意,Windows用户应将$HOME替换$HOME %USERPROFILE% . 如果Keras无法创建上述目录(例如,由于权限问题), /tmp/.keras/用作备份.

Keras配置文件是存储在$HOME/.keras/keras.json的JSON文件. 默认配置文件如下所示:

{
    "image_data_format": "channels_last",
    "epsilon": 1e-07,
    "floatx": "float32",
    "backend": "tensorflow"
}

它包含以下字段:

  • 图像处理层和实用程序将默认使用的图像数据格式( channels_lastchannels_first ).
  • 在某些操作中,用于防止零除的epsilon数值模糊因子.
  • 默认的float数据类型.
  • 默认后端. 请参阅后端文档 .

同样,默认情况下,缓存的数据集文件(例如使用get_file()下载的数据集get_file()存储在$HOME/.keras/datasets/ .


How can I obtain reproducible results using Keras during development?

在模型开发过程中,有时可以从一次运行中获得可重复的结果,以确定性能变化是由于实际模型还是数据修改,还是仅仅是新随机样本的结果,这很有用.

首先,您需要在程序启动之前将PYTHONHASHSEED环境变量设置为0 (而不是在程序本身内部). 在Python 3.2.3及更高版本中,这对于使某些基于哈希的操作具有可复制的行为(例如,集合或dict中的项目顺序,请参阅Python的文档版本#2280以获得更多详细信息)是必需的. 设置环境变量的一种方法是在启动python时像这样:

$ cat test_hash.py
print(hash("keras"))
$ python3 test_hash.py                  # non-reproducible hash (Python 3.2.3+)
-8127205062320133199
$ python3 test_hash.py                  # non-reproducible hash (Python 3.2.3+)
3204480642156461591
$ PYTHONHASHSEED=0 python3 test_hash.py # reproducible hash
4883664951434749476
$ PYTHONHASHSEED=0 python3 test_hash.py # reproducible hash
4883664951434749476

此外,当使用TensorFlow后端并在GPU上运行时,某些操作具有不确定的输出,尤其是tf.reduce_sum() . 这是由于GPU并行运行许多操作,因此不能始终保证执行顺序. 由于浮点数的精度有限,因此即使将多个数字相加,其结果也可能略有不同,具体取决于添加顺序. 您可以尝试避免非确定性操作,但是TensorFlow可能会自动创建一些操作来计算梯度,因此仅在CPU上运行代码要简单得多. 为此,可以将CUDA_VISIBLE_DEVICES环境变量设置为空字符串,例如:

$ CUDA_VISIBLE_DEVICES="" PYTHONHASHSEED=0 python your_program.py

下面的代码片段提供了一个如何获得可重现结果的示例-面向Python 3环境的TensorFlow后端:

import numpy as np
import tensorflow as tf
import random as rn

# The below is necessary for starting Numpy generated random numbers
# in a well-defined initial state.

np.random.seed(42)

# The below is necessary for starting core Python generated random numbers
# in a well-defined state.

rn.seed(12345)

# Force TensorFlow to use single thread.
# Multiple threads are a potential source of non-reproducible results.
# For further details, see: https://stackoverflow.com/questions/42022950/

session_conf = tf.ConfigProto(intra_op_parallelism_threads=1,
                              inter_op_parallelism_threads=1)

from keras import backend as K

# The below tf.set_random_seed() will make random number generation
# in the TensorFlow backend have a well-defined initial state.
# For further details, see:
# https://www.tensorflow.org/api_docs/python/tf/set_random_seed

tf.set_random_seed(1234)

sess = tf.Session(graph=tf.get_default_graph(), config=session_conf)
K.set_session(sess)

# Rest of code follows ...

How can I install HDF5 or h5py to save my models in Keras?

为了将keras.callbacks.ModelCheckpoint模型保存为HDF5文件,例如通过keras.callbacks.ModelCheckpoint ,Keras使用h5py Python包. 它是Keras的依赖项,应默认安装. 在基于Debian的发行版上,您将必须另外安装libhdf5

sudo apt-get install libhdf5-serial-dev

如果不确定是否安装了h5py,则可以打开Python shell并通过以下方式加载模块

import h5py

如果导入时没有错误,则说明已安装,否则,您可以在此处找到详细的安装说明:http://docs.h5py.org/en/latest/build.html