美文网首页
深度学习模型训练中如何控制随机性

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

作者: Lighthouse_hang | 来源:发表于2019-12-04 22:07 被阅读0次

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

    2. 划分训练集和测试集时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()
    

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

    总结

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

    相关文章

      网友评论

          本文标题:深度学习模型训练中如何控制随机性

          本文链接:https://www.haomeiwen.com/subject/svalgctx.html