训练模型过程中,会遇到很多的随机性设置,设置随机性并多次实验的结果更加有说服力。但是现在发论文越来越要求模型的可复现性,这时候不得不控制代码的随机性问题,小编最近也遇上这些问题,所以在这里总结一下如何控制模型的随机性,但是我用的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()
这个东西很管用的,真的非常管用!!!
总结
以上就是我总计的深度学习模型训练中涉及到的随机性,希望对大家有所帮助,如果有其他需要注意的内容,欢迎大家帮我补充!
网友评论