訓練模型過程中哮内,會遇到很多的隨機性設置溶弟,設置隨機性并多次實驗的結果更加有說服力。但是現(xiàn)在發(fā)論文越來越要求模型的可復現(xiàn)性胖翰,這時候不得不控制代碼的隨機性問題臼节,小編最近也遇上這些問題撬陵,所以在這里總結一下如何控制模型的隨機性珊皿,但是我用的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的設置蟋定,均無法復現(xiàn),只有這種shuffle可以復現(xiàn)結果
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的相關資料后發(fā)現(xiàn)灶芝,該初始化是具有一定的隨機性的郑原,所以需要設置其隨機性種子
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多線程的隨機問題犯犁,所以你會發(fā)現(xiàn)相同模型和數據的結果還是不一樣,這是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上發(fā)現(xiàn)了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()
這個東西很管用的簇捍,真的非常管用!G喂啊暑塑!
總結
以上就是我總計的深度學習模型訓練中涉及到的隨機性,希望對大家有所幫助锅必,如果有其他需要注意的內容事格,歡迎大家?guī)臀已a充!