小书匠深度学习

文章太长,放个目录:

1.优化函数的选择

先写结论,后面再补上每个优化函数的详细解释:

  1. 如果你的数据很稀疏,那应该选择有自适应性的优化函数。并且你还可以减少调参的时间,用默认参数取得好的结果。 

  2. RMSprop是adagrad的一个拓展,旨在解决它提前结束的问题。 

  3. 而RMSprop和Adadelta类似,只是adadelta采用了RMS的方法更新参数。 

  4. 在RMSprop基础上增加了偏差校正和momentum,形成了Adam。 

  5. 综上,RMSprop、Adadelta、Adam都是类似的。 

  6. Kingma【Kingma, D. P., & Ba, J. L. (2015). Adam: a Method for Stochastic Optimization. International Conference on Learning Representations, 1–13.】的实验表示,偏差校正使得Adam在优化到后面梯度变的稀疏的时候使得其优化性能最好。 

  7. 所以,可能Adam是最好的优化函数。 

  8. 所以,如果你希望你的训练能变的更快,或者你要训练的是一个复杂的深度的网络,尽量选择自适应的优化函数。 

摘自:深度学习各种优化函数详解

2.损失函数的选择

编译模型必须的两个参数之一:

model.compile(loss='mean_squared_error', optimizer='sgd')

  1. from keras import losses 

  2. model.compile(loss=losses.mean_squared_error, optimizer='sgd') 

2.2常用的损失函数

mean_squared_error或mse

mean_absolute_error或mae

mean_absolute_percentage_error或mape

mean_squared_logarithmic_error或msle

squared_hinge

hinge

categorical_hinge

logcosh

categorical_crossentropy:亦称作多类的对数损失,注意使用该目标函数时,需要将标签转化为形如(nb_samples, nb_classes)的二值序列

sparse_categorical_crossentropy:如上,但接受稀疏标签。注意,使用该函数时仍然需要你的标签与输出值的维度相同,你可能需要在标签数据上增加一个维度:np.expand_dims(y,-1)

binary_crossentropy:(亦称作对数损失,logloss)

kullback_leibler_divergence:从预测值概率分布Q到真值概率分布P的信息增益,用以度量两个分布的差异

poisson:即(predictions - targets * log(predictions))的均值

cosine_proximity:即预测值与真实标签的余弦距离平均值的相反数

注:当使用”categorical_crossentropy”作为目标函数时,标签应该为多类模式,即one-hot编码的向量,而不是单个数值. 可以使用工具中的to_categorical函数完成该转换.示例如下:

  1. from keras.utils.np_utils import to_categorical 

  2. categorical_labels = to_categorical(int_labels, num_classes=None) 

摘自:目标函数objectives

2.2自定义函数

keras的Losses部分的源码是这样的:


部分losses

可以看出,每次计算loss时,会传给损失函数两个值,一个是正确的标签(y_true),一是模型预测的标签(y_pred),这两个值是shape相同的Theano/TensorFlow张量,根据这一规则,可以设计自己的损失函数.

2.1实践

(1)基本用法

自定义一个,对真实和预测的差距求4次方的损失函数:

  1. #自定义损失函数 

  2. def myloss(pred,true): 

  3. result = np.power(pred-true,4) 

  4. return result.mean() 

  5. #编译模型 

  6. model.compile(optimizer='adam',loss=myloss) 

(2)实际例子

使用one hot分类时,拟合one hot分布的同时,还你拟合均匀分布

自定义的函数是:

实际用keras是这样的:

  1. #自定义损失函数 

  2. def mycrossentropy(y_true, y_pred, e=0.1): 

  3. return (1-e)*K.categorical_crossentropy(y_pred,y_true) + e*K.categorical_crossentropy(y_pred, K.ones_like(y_pred)/nb_classes) 

  4. #编译模型  

  5. model.compile(optimizer='adam', loss=mycrossentropy) 

例子来源Keras中自定义复杂的loss函数

2.2将损失函数自定义为网络层

使用均方差和KL散度定义损失函数

  1. class CustomVariationalLayer(Layer): 

  2. def __init__(self, **kwargs): 

  3. self.is_placeholder = True 

  4. super(CustomVariationalLayer, self).__init__(**kwargs) 


  5. def vae_loss(self, x, x_decoded_mean): 

  6. xent_loss = original_dim * metrics.binary_crossentropy(x, x_decoded_mean)#Square Loss 

  7. kl_loss = - 0.5 * K.sum(1 + z_log_var - K.square(z_mean) - K.exp(z_log_var), axis=-1)# KL-Divergence Loss 

  8. return K.mean(xent_loss + kl_loss) 


  9. def call(self, inputs): 

  10. x = inputs[0] 

  11. x_decoded_mean = inputs[1] 

  12. loss = self.vae_loss(x, x_decoded_mean) 

  13. self.add_loss(loss, inputs=inputs) 

  14. # We won't actually use the output. 

  15. return x 


  16. y = CustomVariationalLayer()([x, x_decoded_mean]) 

  17. vae = Model(x, y) 

  18. vae.compile(optimizer='rmsprop', loss=None) 

例子来源Keras自定义Loss函数

3.模型的保存

3.1同时保存结构和权重

官方保持模型的API是这样的:

def save_model(model, filepath, overwrite=True, include_optimizer=True)

调用这个函数保持的内容包括:

  • 模型的结构
  • 模型的权重
  • 优化器的状态(即保存时优化器的状态,一遍后面从该状态出发继续训练)
  1. from keras.models import load_model 


  2. #保持模型 

  3. model.save('my_model.h5')  


  4. #载入模型 

  5. model = load_model('my_model.h5') 

3.2模型结构的保存

如果只希望保持模型结构,可以使用以下方法保存和重建.

  1. # save as JSON 

  2. json_string = model.to_json() 


  3. # save as YAML 

  4. yaml_string = model.to_yaml() 


  5. # model reconstruction from JSON: 

  6. from keras.models import model_from_json 

  7. model = model_from_json(json_string) 


  8. # model reconstruction from YAML 

  9. model = model_from_yaml(yaml_string) 

3.3模型权重的保存

如果只希望保持权重,可以使用以下方法保持和载入.

  1. model.save_weights('my_model_weights.h5') 

  2. model.load_weights('my_model_weights.h5') 

3.5选择网络层载入

  1. """ 

  2. 假如原模型为: 

  3. model = Sequential() 

  4. model.add(Dense(2, input_dim=3, name="dense_1")) 

  5. model.add(Dense(3, name="dense_2")) 

  6. ... 

  7. model.save_weights(fname) 

  8. """ 

  9. # new model 

  10. model = Sequential() 

  11. model.add(Dense(2, input_dim=3, name="dense_1")) # will be loaded 

  12. model.add(Dense(10, name="new_dense")) # will not be loaded 


  13. # load weights from first model; will only affect the first layer, dense_1. 

  14. model.load_weights(fname, by_name=True) 

摘自:如何保存Keras模型

4.训练历史的保存

4.1检测运行过程的参数

深度学习像炼丹一样,有时候看见出现了仙丹(非常好的训练结果),但是忘记保持了,之后再怎么训练也找不回曾经的那个 .有没有有一种机制,检测训练过程中的参数,如果结果比前一次好,我就保存模型权重下来呢?

有的,官方提供回调函数检测训练参数.

定义好检测的参数和保存的格式,就可以将回调函数写到训练函数的callbacks即可:

  1. Checkpoint = keras.callbacks.ModelCheckpoint( 

  2. 'Train_record/{epoch:02d}.{val_acc:.2f}.V0.hdf5', 

  3. monitor='val_loss', 

  4. verbose=1, 

  5. save_best_only=True, 

  6. save_weights_only=False, 

  7. mode='auto', 

  8. period=1) 


  9. history = model.fit([train_X_lstm,train_X_resnet],train_y,verbose=1,epochs=150,batch_size=256,validation_data=([vali_X_lstm,vali_X_resnet],vali_y),shuffle=True,callbacks=[Checkpoint])  

回调函数Checkpoint设置:

filepath:保存模型的路径,你可以按照上面的方式自定义你的文件名,很直观

monitor: 被监测的数据,训练历史必须包含改值,比如:如果你的训练过程没有设置验证集,就无法检测val_acc

save_best_only:每次是否保存当前的最佳模型

mode:auto, min, max} 的其中之一。 如果 save_best_only=True,那么是否覆盖保存文件的决定就取决于被监测数据的最大或者最小值。 对于 val_acc,模式就会是 max,而对于 val_loss,模式就需要是 min.

save_weights_only: 如果 True,那么只有模型的权重会被保存 (model.save_weights(filepath)), 否则的话,整个模型会被保存 (model.save(filepath))。

period: 每个检查点之间的间隔(训练轮数

4.2保持训练过程得到的所有数据

这里的所有数据是指model.fit()返回的所有数据,包括acc(训练准确度),loss(训练损失),如果指定了验证集,还会有val_acc(验证集准确度),val_loss(训练集损失).保持方法是在训练完成后写入到文件中:

  1. history=model.fit(train_set_x,train_set_y,batch_size=256,shuffle=True,nb_epoch=nb_epoch,validation_split=0.1) 

  2. with open('train_history.txt','w') as f: 

  3. f.write(str(history.history)) 

5.陷阱:validation_split与shuffle

模型训练时,有一个参数可以从训练集抽取一定比例的数据做验证,这个参数是validation_split.

训练过程抽取训练数据的10%作验证

history = model.fit([train_X_lstm,train_X_resnet],train_y,verbose=1,epochs=150,batch_size=256,validation_split=0.1,shuffle=True,callbacks=[Checkpoint])

但是使用这个参数时,必须注意先对数据Shuffle,据说是因为validation_split只抽取训练集的后面10%数据作验证,如果你前面的数据没有打乱,这样抽取是可能只抽取到一个类别的样本,这样的验证集将没有意义.

所以,使用这个参数前,先将训练数据(标签同步)打乱.

例外需要关注的是:validation_split划分出来的验证集是固定的,不随每次epoch变化

官方文档-Losses

使用Keras训练神经网络备忘录的更多相关文章

  1. 使用Keras开发神经网络

    一.使用pip安装好tensorflow 二.使用pip安装好Keras 三.构建过程: 1 导入数据 2 定义模型 3 编译模型 4 训练模型 5 测试模型 6 写出程序 1.导入数据 使用皮马人糖 ...

  2. 使用Google Colab训练神经网络(二)

    Colaboratory 是一个 Google 研究项目,旨在帮助传播机器学习培训和研究成果.它是一个 Jupyter 笔记本环境,不需要进行任何设置就可以使用,并且完全在云端运行.Colaborat ...

  3. 用Keras搭建神经网络 简单模版(六)——Autoencoder 自编码

    import numpy as np np.random.seed(1337) from keras.datasets import mnist from keras.models import Mo ...

  4. keras人工神经网络构建入门

    //2019.07.29-301.Keras 是提供一些高度可用神经网络框架的 Python API ,能帮助你快速的构建和训练自己的深度学习模型,它的后端是 TensorFlow 或者 Theano ...

  5. stanford coursera 机器学习编程作业 exercise4--使用BP算法训练神经网络以识别阿拉伯数字(0-9)

    在这篇文章中,会实现一个BP(backpropagation)算法,并将之应用到手写的阿拉伯数字(0-9)的自动识别上. 训练数据集(training set)如下:一共有5000个训练实例(trai ...

  6. 机器学习入门15 - 训练神经网络 (Training Neural Networks)

    原文链接:https://developers.google.com/machine-learning/crash-course/training-neural-networks/ 反向传播算法是最常 ...

  7. keras训练cnn模型时loss为nan

    keras训练cnn模型时loss为nan 1.首先记下来如何解决这个问题的:由于我代码中 model.compile(loss='categorical_crossentropy', optimiz ...

  8. 怎么选取训练神经网络时的Batch size?

    怎么选取训练神经网络时的Batch size? - 知乎 https://www.zhihu.com/question/61607442 深度学习中的batch的大小对学习效果有何影响? - 知乎 h ...

  9. pytorch1.0批训练神经网络

    pytorch1.0批训练神经网络 import torch import torch.utils.data as Data # Torch 中提供了一种帮助整理数据结构的工具, 叫做 DataLoa ...

随机推荐

  1. Fiddler讲解2

    想要 浏览更多Fiddler内容:请点击进入Fiddler官方文档 阅读目录: 一.查看网络流量: 二.检查网络流量: 三.查看Web会话摘要: 四.查看Web会话统计信息: 五.查看Web会话内容: ...

  2. Bipartite Checking CodeForces - 813F (线段树按时间分治)

    大意: 动态添边, 询问是否是二分图. 算是个线段树按时间分治入门题, 并查集维护每个点到根的奇偶性即可. #include <iostream> #include <sstream ...

  3. jquery easyui form表单一开始就自动启用验证了,修改为form提交的时候在开启验证

    <form method="post" action="<%=path %>" class="easyui-form" d ...

  4. Python-demo(抖音)

    # -*- coding:utf-8 -*- from mitmproxy import ctx import json import requests import time import os p ...

  5. github新建远程仓库初始化记录

    …or create a new repository on the command line echo "# 输出内容" >> README.md git init ...

  6. Lucid Dream

    Lucid Dream 作者:Lo Stigmergy链接:https://www.zhihu.com/question/21260829/answer/35733194 清醒状态下时意识和潜意识基本 ...

  7. 单例模式详解以及需要注意的地方(Singleton)

    单例模式,顾名思义,就是在Java程序中只有唯一一个实例,这样做的好处是可以在不需要多个实例的对象采用单例模式可以节省内存,否则会造成不必要的内存浪费.单例模式的定义为:保证一个类只有一个实例,自己可 ...

  8. 关于iview下拉菜单无法添加点击事件的解决办法

    效果如下图所示,点击下拉菜单,点击退出,然后跳到登录界面 代码如下: <Dropdown trigger="click" style="margin-left: 2 ...

  9. Oracle GoldenGate(ogg)安装经验大汇总,采坑总结,绝对干货!

    一下是安装ogg过程中遇到的问题和解决办法,绝对良心干货,抽空会写更详细的安装教程.更多精彩内容请点击 OGG-00685 begin time prior to oldest log in log ...

  10. 记录java+testng运行selenium(四)--- 结构说明

    一图:主要是driver文件所在目录,及ini配置文件所在位置. 这两个文件一般我是放在其它目录下,不跟随项目所在目录 二图:用例操作类及用例执行类所在位置. 下图中有接口代码及功能代码组成,之前的文 ...