在使用 tensorflow 时,我通常会为实验的可重复性设置种子。在这种情况下,我的代码如下:
class DeepNetworkModel(tf.keras.Model):
def __init__(self,
seed: int,
input_shape: int,
hidden_units: list,
num_actions: int,
batch_norm_input: bool,
batch_norm_hidden: bool,
activation: str,
kernel_initializer: str,
modelname: str = 'Deep Q Network'):
# call the parent constructor
super(DeepNetworkModel, self).__init__(name=modelname)
# set dimensionality of input/output depending on the model
inp_shape = input_shape
out_shape = num_actions
# set random seed
tf.random.set_seed(seed)
# set flag for batch norm as attribute
self.bnflag_input = batch_norm_input
self.batch_norm_hidden = batch_norm_hidden
# In setting input_shape, the batch dimension is not included.
# input layer
self.input_layer = InputLayer(input_shape=inp_shape)
# batch norm layer for inputs
if self.bnflag_input:
self.bnorm_layer = BatchNormalization(center=False,scale=False)
# set of hidden layers
self.hids = []
for i in hidden_units:
self.hids.append(Dense(i, kernel_initializer=kernel_initializer))
# check what type of activation is set
if activation == 'leaky_relu':
leaky_relu = tf.nn.leaky_relu
self.hids.append(Activation(leaky_relu))
elif activation == 'relu6':
relu6 = tf.nn.relu6
self.hids.append(Activation(relu6))
elif activation == 'elu':
elu = tf.nn.elu
self.hids.append(Activation(elu))
else:
self.hids.append(Activation(activation))
if self.batch_norm_hidden:
self.hids.append(BatchNormalization())
# output layer with linear activation by default
self.output_layer = Dense(out_shape)
def call(self,
inputs: Union[np.ndarray or tf.Tensor],
training: bool = True,
store_intermediate_outputs: bool = False):
if store_intermediate_outputs:
# build the input layer
if self.bnflag_input:
z = self.input_layer(inputs)
self.inputs = z
z = self.bnorm_layer(z, training)
self.bninputs = z
else:
z = self.input_layer(inputs)
self.inputs = z
# build the hidden layer
for layer in self.hids:
if 'batch' in layer.name:
z = layer(z, training)
else:
z = layer(z)
layer.out = z
# build the output layer
z = self.output_layer(z)
self.output_layer.out = z
else:
# build the input layer
if self.bnflag_input:
z = self.input_layer(inputs)
z = self.bnorm_layer(z, training)
else:
z = self.input_layer(inputs)
# build the hidden layer
for layer in self.hids:
if 'batch' in layer.name:
z = layer(z, training)
else:
z = layer(z)
# build the output layer
z = self.output_layer(z)
return z
为这个简单的 DNN 模型设置种子,哪些操作会影响优化?我想到的唯一步骤是网络参数的初始化。选择小批量以执行 SGD 更新(或任何其他优化器选择)所涉及的随机性在这里并不重要,因为我正在实现 DQN,因此我将缓冲区中随机选择的批次作为输入传递(不设置种子) .
有没有其他方法可以修复使用此代码的随机性?当我传递不同的种子作为输入时,我的问题与理解不同实验的结果有关。现在我想改变种子只会改变权重的初始化,但我想确定这一点。
我已经阅读了tensorflow 的文档大量随机种子,但它并没有多大帮助。