Tensorflow 2.x代码中如何控制随机性以保证结果可重复性

引言

控制实验的随机性非常有必要:(1) 保证结果的可复现/重复性一直都是研究中的一个基本问题; (2)在验证所提方法/系统中往往需要做分离/消融实验来对结果进行拆分,以验证各个模块是否有效以及对总体结果的贡献,控制随机性可以消除因随机性的引入产生的影响。基于此,在此总结tensorflow2.x实验环境的随机性控制方法。

随机性控制

基本常用包中的随机性

numpyrandom, os中的随机性控制:

import numpy as np
import random

seed_value = 0
random.seed(seed_value )
np.random.seed(seed_value) 
os.environ['PYTHONHASHSEED'] = str(seed_value)

在重复实验时,往往需要利用随机性来产生数据集的不同划分,例如:
(基于sklearn通过控制随机性来产生不同的划分)

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=seed_value)
cv = StratifiedKFold(n_splits=10, random_state=seed_value) # 10折

Tensorflow中的随机性

tensorflow2.x中的随机性控制

import tensorflow as tf
tf.random.set_seed(0)

tensorflow2.x 中各层的随机性控制
(1)各层初始化过程中的随机性
1D conv.为例,其API格式为:

tf.keras.layers.Conv1D(kernel_initializer=None, ....)

可以看到kernel_initializer默认为Null, 如何控制初始化中的随机性?

tn_initializer = tf.initializers.TruncatedNormal(seed=seed_value)
conv_1d_f_pointwise = tf.keras.layers.Conv1D(filters=1, kernel_size=1, activation=None, kernel_initializer=tn_initializer)

注:Conv1D还有其他参数初始化会引入随机性,此处仅以kernel_initializer为例.
(2)Dropout
Dropout层的构造函数如下:

__init__(self, rate=0.5, noise_shape=None, seed=None, name=None, **kwargs)

在使用过程中需要指定随机种子来控制dropout操作本身带来的随机性:

tf.keras.layers.Dropout(rate=self.drop_rate, seed=self.random_seed_alg_part)

(3) 训练过程中的随机性
如果调用model.fit()进行训练,API接口如下:

fit(self,x=None, y=None, batch_size=None,  epochs=1, verbose=1, shuffle=True, **kwargs)

其中参数shuffle默认True会带来随机性,需要将参数shuffle显式置为False.

(4) GPU多线程训练中的随机性
tensorflow-determinism包(https://github.com/NVIDIA/framework-determinism):该包解决了GPU上训练时不确定性的问题。注意:安装时通过命令:pip install tensorflow-determinism 安装, 安装后调用如下:

from tfdeterminism import patch
patch()

可惜的是:tfdeterminism 暂时只适用于小于2.1的tensorflow版本,因为目前没有适用于TensorFlow 2.1版或更高版本的修补程序

对于Tensorflow2.3版本(通过命令:pip package tensorflow=2.3.0安装),因为其本身实现了大多数当前可用的GPU确定性操作解决方案, 因此可以通过如下代码控制GPU中的不确定性:

import tensorflow as tf
import os
os.environ['TF_DETERMINISTIC_OPS'] = '1'

另外, 还看到如下代码: os.environ['TF_CUDNN_DETERMINISTIC'] = str(seed_value), 暂时还不清楚其适用场景。

总结

未完待续。

References

1.https://github.com/NVIDIA/framework-determinism
2.https://zhuanlan.zhihu.com/p/95416326
3.https://stackoverflow.com/questions/50744565/how-to-handle-non-determinism-when-training-on-a-gpu

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MasterQKK 被注册

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值