Machine learning 对于深度学习,激活relu后,输出在训练期间变为NAN,而tanh则正常

Machine learning 对于深度学习,激活relu后,输出在训练期间变为NAN,而tanh则正常,machine-learning,tensorflow,neural-network,deep-learning,reinforcement-learning,Machine Learning,Tensorflow,Neural Network,Deep Learning,Reinforcement Learning,我训练的神经网络是深度强化学习的批评网络。问题是,当层的一个激活设置为relu或elu时,经过一些训练步骤后,输出将为nan,而如果激活为tanh,则输出正常。代码如下(基于tensorflow): 带有tf.variable_scope('critic')的: self.batch_size=tf.shape(self.tfs)[0] l\u out\u x=denseWN(x=self.tfs,name='l3',num\u units=self.cell\u size,非线性=tf.nn.

我训练的神经网络是深度强化学习的批评网络。问题是,当层的一个激活设置为relu或elu时,经过一些训练步骤后,输出将为nan,而如果激活为tanh,则输出正常。代码如下(基于tensorflow):

带有tf.variable_scope('critic')的
:
self.batch_size=tf.shape(self.tfs)[0]
l\u out\u x=denseWN(x=self.tfs,name='l3',num\u units=self.cell\u size,非线性=tf.nn.tanh,可训练=True,形状=[det*step*2,self.cell\u size])
l_out_x1=denseWN(x=l_out_x,name='l3_1',num_units=32,trainable=True,非线性=tf.nn.tanh,shape=[self.cell_size,32])
l_out_x2=denseWN(x=l_out_x1,name='l3_2',num_units=32,trainable=True,非线性=tf.nn.tanh,shape=[32,32])
l_out_x3=denseWN(x=l_out_x2,name='l3_3',num_units=32,trainable=True,shape=[32,32])
self.v=denseWN(x=l\u out\u x3,name='l4',num\u units=1,trainable=True,shape=[32,1])
以下是基本层施工规范:

def get_var_maybe_avg(var_name,ema,trainable,shape):
如果var_name='V':
initializer=tf.contrib.layers.xavier_initializer()
v=tf.get_变量(name=var_name,initializer=initializer,trainable=trainable,shape=shape)
如果var_name=='g':
初始值设定项=tf.常数\初始值设定项(1.0)
v=tf.get_变量(name=var_name,initializer=initializer,trainable=trainable,shape=[shape[-1]]))
如果var_name=='b':
初始值设定项=tf.常数\初始值设定项(0.1)
v=tf.get_变量(name=var_name,initializer=initializer,trainable=trainable,shape=[shape[-1]]))
如果ema不是无:
v=均线平均值(v)
返回v
def get_vars_maybe_avg(变量名称、ema、可培训、形状):
变量=[]
对于变量名称中的vn:
附加(获取变量可能平均值(vn,ema,可训练=可训练,形状=形状))
返回变量
def denseWN(x,名称,数量单位,可训练,形状,非线性=无,ema=无,**kwargs):
具有tf.variable_作用域(名称):
五、 g,b=获得变量可能平均值(['V','g','b',],ema,可训练=可训练,形状=形状)
x=tf.matmul(x,V)
scaler=g/tf.sqrt(tf.reduce_sum(tf.square(V),[0]))
x=tf.reformate(缩放器[1,num_单位])*x+tf.reformate(b[1,num_单位])
如果非线性不是无:
x=非线性(x)
返回x
以下是培训网络的代码:

self.tfdc\u r=tf.placeholder(tf.float32,[None,1],“折扣”)
self.advantage=self.tfdc\u r-self.v
l1_正则化器=tf.contrib.layers.l1_正则化器(比例=0.005,范围=无)
self.weights=tf.可训练的_变量()
正则化\u惩罚\u批评=tf.contrib.layers.apply\u正则化(l1\u正则化器,自权重)
self.closs=tf.reduce_均值(tf.square(self.advantage))
self.optimizer=tf.train.RMSPropOptimizer(0.0001,0.99,0.0,1e-6)
self.grads_和_vars=self.optimizer.compute_梯度(self.closs)
self.grads_和_vars=[[tf.clip_by_norm(grad,5),var]表示grad,如果grad不是None,则self.grads_和_vars中的var]
self.ctrain\u op=self.optimizer.apply\u梯度(self.grads\u和\u vars,global\u step=tf.contrib.framework.get\u global\u step())

看起来您正面临着使用ReLu激活功能(即
NaN
的意思——非常大的激活)来分解梯度的问题。有几种技术可以解决这个问题,例如(更改网络架构)或微妙的变量初始化(这是我首先尝试的)

您正在对不同层中的
V
变量使用Xavier初始化,这确实适用于逻辑乙状结肠激活(请参阅),或者换句话说,
tanh

ReLU激活功能(及其变体,包括ELU)的首选初始化策略是He初始化。在tensorflow中,它通过以下方式实现:

initializer=tf.variance\u scaling\u initializer()
v=tf.get_变量(name=var_name,initializer=initializer,…)
您可能还想尝试为
b
g
变量使用较小的值,但仅通过查看您的模型很难说出确切的值。如果没有帮助,请考虑将批处理规范层添加到模型中以控制激活分布。