这里归纳了Keras使用过程中的一些常见陷阱和解决方法,如果你的模型怎么调都搞不对,或许你有必要看看是不是掉进了哪个猎人的陷阱,成为了一只嗷嗷待宰(?)的猎物
Keras陷阱不多,我们保持更新,希望能做一个陷阱大全
内有恶犬,小心哟
Keras提供了两套后端,Theano和Tensorflow,这是一件幸福的事,就像手中拿着馒头,想蘸红糖蘸红糖,想蘸白糖蘸白糖
如果你从无到有搭建自己的一套网络,则大可放心。但如果你想使用一个已有网络,或把一个用th/tf 训练的网络以另一种后端应用,在载入的时候你就应该特别小心了。
卷积核与所使用的后端不匹配,不会报任何错误,因为它们的shape是完全一致的,没有方法能够检测出这种错误。
在使用预训练模型时,一个建议是首先找一些测试样本,看看模型的表现是否与预计的一致。
如需对卷积核进行转换,可以使用utils.np_utils.kernel_convert,或使用utils.layer_utils.convert_all_kernels_in_model来对模型的所有卷积核进行转换
如果你不知道从哪里淘来一个预训练好的BN层,想把它的权重载入到Keras中,要小心参数的载入顺序。
一个典型的例子是,将caffe的BN层参数载入Keras中,caffe的BN由两部分构成,bn层的参数是mean,std,scale层的参数是gamma,beta
按照BN的文章顺序,似乎载入Keras BN层的参数应该是[mean, std, gamma, beta]
然而不是的,Keras的BN层参数顺序应该是[gamma, beta, mean, std],这是因为gamma和beta是可训练的参数,而mean和std不是
Keras的可训练参数在前,不可训练参数在后
错误的权重顺序不会引起任何报错,因为它们的shape完全相同
模型的fit函数有两个参数,shuffle用于将数据打乱,validation_split用于在没有提供验证集的时候,按一定比例从训练集中取出一部分作为验证集
这里有个陷阱是,程序是先执行validation_split,再执行shuffle的,所以会出现这种情况:
假如你的训练集是有序的,比方说正样本在前负样本在后,又设置了validation_split,那么你的验证集中很可能将全部是负样本
同样的,这个东西不会有任何错误报出来,因为Keras不可能知道你的数据有没有经过shuffle,保险起见如果你的数据是没shuffle过的,最好手动shuffle一下
如果你在使用Keras中遇到难以察觉的陷阱,请发信到moyan_work@foxmail.com说明~赠人玫瑰,手有余香,前人踩坑,后人沾光,有道是我不入地狱谁入地狱,愿各位Keras使用者积极贡献Keras陷阱。老规矩,陷阱贡献者将被列入致谢一栏
Keras有两种类型的模型,顺序模型(Sequential)和泛型模型(Model)
两类模型有一些方法是相同的:
model.summary()
:打印出模型概况model.get_config()
:返回包含模型配置信息的Python字典。模型也可以从它的config信息中重构回去config = model.get_config()
model = Model.from_config(config)# or, for Sequentialmodel = Sequential.from_config(config)
model.get_weights()
:返回模型权重张量的列表,类型为numpy arraymodel.set_weights()
:从numpy array里将权重载入给模型,要求数组具有与model.get_weights()
相同的形状。model.to_json
:返回代表模型的JSON字符串,仅包含网络结构,不包含权值。可以从JSON字符串中重构原模型:from models import model_from_json
json_string = model.to_json()
model = model_from_json(json_string)
model.to_yaml
:与model.to_json
类似,同样可以从产生的YAML字符串中重构模型from models import model_from_yaml
yaml_string = model.to_yaml()
model = model_from_yaml(yaml_string)
model.save_weights(filepath)
:将模型权重保存到指定路径,文件类型是HDF5(后缀是.h5)model.load_weights(filepath, by_name=False)
:从HDF5文件中加载权重到当前模型中, 默认情况下模型的结构将保持不变。如果想将权重载入不同的模型(有些层相同)中,则设置by_name=True
,只有名字匹配的层才会载入权重模型 »Sequential模型
如果刚开始学习Sequential模型,请首先移步这里阅读文档
model.layers
是添加到模型上的层的listcompile(self, optimizer, loss, metrics=[], sample_weight_mode=None)
编译用来配置模型的学习过程,其参数有
metrics=['accuracy']
fit
函数的解释中有相关的参考内容。model = Sequential()
model.add(Dense(32, input_shape=(500,)))
model.add(Dense(10, activation='softmax'))
model.compile(optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['accuracy'])
fit(self, x, y, batch_size=32, nb_epoch=10, verbose=1, callbacks=[], validation_split=0.0, validation_data=None, shuffle=True, class_weight=None, sample_weight=None)
本函数将模型训练nb_epoch
轮,其参数有:
keras.callbacks.Callback
的对象。这个list中的回调函数将会在训练过程中的适当时机被调用,参考回调函数sample_weight_mode='temporal'
。fit
函数返回一个History
的对象,其History.history
属性记录了损失函数和其他指标的数值随epoch变化的情况,如果有验证集的话,也包含了验证集的这些指标变化情况
evaluate(self, x, y, batch_size=32, verbose=1, sample_weight=None)
本函数按batch计算在某些输入数据上模型的误差,其参数有:
fit
一样,是numpy array或numpy array的listfit
的同名参数fit
的同名参数,但只能取0或1fit
的同名参数本函数返回一个测试误差的标量值(如果模型没有其他评价指标),或一个标量的list(如果模型还有其他的评价指标)。model.metrics_names
将给出list中各个值的含义。
如果没有特殊说明,以下函数的参数均保持与fit
的同名参数相同的含义
如果没有特殊说明,以下函数的verbose参数(如果有)均只能取0或1
predict(self, x, batch_size=32, verbose=0)
本函数按batch获得输入数据对应的输出,其参数有:
函数的返回值是预测值的numpy array
predict_classes(self, x, batch_size=32, verbose=1)
本函数按batch产生输入数据的类别预测结果
函数的返回值是类别预测结果的numpy array或numpy
predict_proba(self, x, batch_size=32, verbose=1)
本函数按batch产生输入数据属于各个类别的概率
函数的返回值是类别概率的numpy array
train_on_batch(self, x, y, class_weight=None, sample_weight=None)
本函数在一个batch的数据上进行一次参数更新
函数返回训练误差的标量值或标量值的list,与evaluate的情形相同。
test_on_batch(self, x, y, sample_weight=None)
本函数在一个batch的样本上对模型进行评估
函数的返回与evaluate的情形相同
predict_on_batch(self, x)
本函数在一个batch的样本上对模型进行测试
函数返回模型在一个batch上的预测结果
fit_generator(self, generator, samples_per_epoch, nb_epoch, verbose=1, callbacks=[], validation_data=None, nb_val_samples=None, class_weight=None, max_q_size=10)
利用Python的生成器,逐个生成数据的batch并进行训练。生成器与模型将并行执行以提高效率。例如,该函数允许我们在CPU上进行实时的数据提升,同时在GPU上进行模型训练
函数的参数是:
samples_per_epoch
时,记一个epoch结束validation_data
是生成器时使用,用以限制在每个epoch结束时用来验证模型的验证集样本数,功能类似于samples_per_epoch
函数返回一个History
对象
例子:
def generate_arrays_from_file(path):
while 1:
f = open(path) for line in f: # create numpy arrays of input data
# and labels, from each line in the file
x, y = process_line(line) yield (x, y)
f.close()
model.fit_generator(generate_arrays_from_file('/my_file.txt'),
samples_per_epoch=10000, nb_epoch=10)
evaluate_generator(self, generator, val_samples, max_q_size=10)
本函数使用一个生成器作为数据源评估模型,生成器应返回与test_on_batch
的输入数据相同类型的数据。该函数的参数与fit_generator
同名参数含义相同