深度学习模型训练中如何控制随机性

训练模型过程中,会遇到很多的随机性设置,设置随机性并多次实验的结果更加有说服力。但是现在发论文越来越要求模型的可复现性,这时候不得不控制代码的随机性问题,小编最近也遇上这些问题,所以在这里总结一下如何控制模型的随机性,但是我用的tensorflow的框架,适用于keras框架:

1.设置numpy, random, os的随机性
全局中固定numpy, random, os的随机性

import numpy as np
import random
np.random.seed(seed) # seed是一个固定的整数即可
random.seed(seed)
os.environ['PYTHONHASHSEED'] = str(seed)

有时候也会经常用到shuffle打乱顺序,这时候也需要设置shuffle的随机性

import random
random.Random(seed).shuffle(arr) 

试验过其他shuffle的设置,均无法复现,只有这种shuffle可以复现结果

  1. 划分训练集和测试集时random_state的设置
    在模型的训练中,会划分训练集和测试集。无论是使用train_test_split还是KFold划分,都需要设置random_state的具体数值
from sklearn.model_selection import train_test_split, StratifiedKFold
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=2020)
cv = StratifiedKFold(n_splits=10, random_state=2020) # 10折

3.设置tensorflow的随机性

import tensorflow as tf
tf.random.set_seed(seed) # tensorflow2.0版本的设置,较早版本的设置方式不同,可以自查

4.设置深度学习中各层的随机性
在我的深度学习框架中,会用到Conv2D和Dense层(tensorflow2.0中Keras的API)。在官方的文档中,这两个层的初始化也存在一定的随机性。
Conv2D层的官网说明

Conv2D层的初始化参数

__init__(
    filters,
    kernel_size,
    strides=(1, 1),
    padding='valid',
    data_format=None,
    dilation_rate=(1, 1),
    activation=None,
    use_bias=True,
    kernel_initializer='glorot_uniform',
    bias_initializer='zeros',
    kernel_regularizer=None,
    bias_regularizer=None,
    activity_regularizer=None,
    kernel_constraint=None,
    bias_constraint=None,
    **kwargs
)

从上面的初始化参数中可以看见

kernel_initializer='glorot_uniform'

查阅glorot_uniform的相关资料后发现,该初始化是具有一定的随机性的,所以需要设置其随机性种子

from tensorflow.keras.layers import Conv2D
from tensorflow.keras.initializers import glorot_normal
conv = Conv2D(kernel_initializer=glorot_normal(seed=seed))  

卷积层的其他参数自己设置,只需要注意kernel_initializer的参数设置即可

同样的设置也存在于Dense层和Dropout层

from tensorflow.keras.layers import Dense, Dropout
from tensorflow.keras.initializers import glorot_normal
dense = Dense(kernel_initializer=glorot_normal(seed=seed))
drop = Dropout(seed=seed)

5.深度学习训练过程中的随机性

model.fit(X_train, y_train, shuffle=False) # 注意shuffle=False

当然如果使用GPU训练模型的话,因为cudnn中分配GPU多线程的随机问题,所以你会发现相同模型和数据的结果还是不一样,这是stackoverflow上的大神对该问题的解答。
How to handle non-determinism when training on a GPU?

6.GPU多线程训练的随机性

session_conf = tf.compat.v1.ConfigProto(intra_op_parallelism_threads=1, inter_op_parallelism_threads=1)
sess = tf.compat.v1.Session(graph=tf.compat.v1.get_default_graph(), config=session_conf)
tf.compat.v1.keras.backend.set_session(sess)

tensorflow是无法控制GPU多线程的随机性的,但是pytorch是可以的

torch.manual_seed(SEED)
torch.cuda.manual_seed_all(SEED)
torch.backends.cudnn.deterministic=True

7.tensorflow-determinism项目
在github上发现了tensorflow-determinism的项目,这个项目的官方解释为:

This repository serves three purposes:
1.Provide up-to-date information (in this file) about non-determinism sources and solutions in TensorFlow and beyond, with a focus on determinism when running on GPUs.
2.Provide a patch to attain various levels of GPU-specific determinism in stock TensorFlow, via the installation of the tensorflow-determinism pip package.
3.Be the location where a TensorFlow determinism debug tool will be released as part of the tensorflow-determinism pip package.

修复了GPU上no-determinism的问题。有需要的可以自行pip安装

pip install tensorflow-determinism

调用格式

from tfdeterminism import patch
patch()

这个东西很管用的,真的非常管用!!!

总结
以上就是我总计的深度学习模型训练中涉及到的随机性,希望对大家有所帮助,如果有其他需要注意的内容,欢迎大家帮我补充!

作者:Lighthouse_hang
链接:https://www.jianshu.com/p/d135b2ead899
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值