当前位置: 首页 > 知识库问答 >
问题:

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

宗政颖逸
2023-03-14

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

with tf.variable_scope('critic'):

        self.batch_size = tf.shape(self.tfs)[0]

        l_out_x = denseWN(x=self.tfs, name='l3', num_units=self.cell_size, nonlinearity=tf.nn.tanh, trainable=True,shape=[det*step*2, self.cell_size])

        l_out_x1 = denseWN(x=l_out_x, name='l3_1', num_units=32, trainable=True,nonlinearity=tf.nn.tanh, shape=[self.cell_size, 32])
        l_out_x2 = denseWN(x=l_out_x1, name='l3_2', num_units=32, trainable=True,nonlinearity=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_out_x3, name='l4', num_units=1,  trainable=True, shape=[32, 1])

下面是基层施工规范:

def get_var_maybe_avg(var_name, ema,  trainable, shape):
    if var_name=='V':
        initializer = tf.contrib.layers.xavier_initializer()
        v = tf.get_variable(name=var_name, initializer=initializer, trainable=trainable, shape=shape)
    if var_name=='g':
        initializer = tf.constant_initializer(1.0)
        v = tf.get_variable(name=var_name, initializer=initializer, trainable=trainable, shape=[shape[-1]])
    if var_name=='b':
        initializer = tf.constant_initializer(0.1)
        v = tf.get_variable(name=var_name, initializer=initializer, trainable=trainable, shape=[shape[-1]])
    if ema is not None:
        v = ema.average(v)
    return v

def get_vars_maybe_avg(var_names, ema, trainable, shape):
    vars=[]
    for vn in var_names:
        vars.append(get_var_maybe_avg(vn, ema, trainable=trainable, shape=shape))
    return vars

def denseWN(x, name, num_units, trainable, shape, nonlinearity=None, ema=None, **kwargs):
    with tf.variable_scope(name):
        V, g, b = get_vars_maybe_avg(['V', 'g', 'b'], ema, trainable=trainable, shape=shape)
        x = tf.matmul(x, V)
        scaler = g/tf.sqrt(tf.reduce_sum(tf.square(V),[0]))
        x = tf.reshape(scaler,[1,num_units])*x + tf.reshape(b,[1,num_units])
        if nonlinearity is not None:
            x = nonlinearity(x)
        return x

以下是培训网络的代码:

self.tfdc_r = tf.placeholder(tf.float32, [None, 1], 'discounted_r')
self.advantage = self.tfdc_r - self.v
l1_regularizer = tf.contrib.layers.l1_regularizer(scale=0.005, scope=None)
self.weights = tf.trainable_variables()
regularization_penalty_critic = tf.contrib.layers.apply_regularization(l1_regularizer, self.weights)
self.closs = tf.reduce_mean(tf.square(self.advantage))
self.optimizer = tf.train.RMSPropOptimizer(0.0001, 0.99, 0.0, 1e-6)
self.grads_and_vars = self.optimizer.compute_gradients(self.closs)
self.grads_and_vars = [[tf.clip_by_norm(grad,5), var] for grad, var in self.grads_and_vars if grad is not None]
self.ctrain_op = self.optimizer.apply_gradients(self.grads_and_vars, global_step=tf.contrib.framework.get_global_step())

共有1个答案

那弘
2023-03-14

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

您在不同的层中为变量使用Xavier初始化,这确实适用于逻辑乙状结肠激活(参见Xavier Glorot和Yoshua Bengio的论文),或者换句话说,适用于tanh。

ReLU激活功能(及其变体,包括ELU)的首选初始化策略是He初始化。在tensorflow中,它是通过tf实现的。variance\u scaling\u初始值设定项:

initializer = tf.variance_scaling_initializer()
v = tf.get_variable(name=var_name, initializer=initializer, ...)

您可能还想尝试为变量b和g取较小的值,但仅通过查看模型很难说出确切的值。如果没有任何帮助,请考虑向模型中添加批处理规范层以控制激活分布。

 类似资料:
  • 我计划编写一个国际象棋引擎,它使用深度卷积神经网络来评估国际象棋的位置。我将使用位板来表示棋盘状态,这意味着输入层应该有12*64个神经元用于位置,1个用于玩家移动(0表示黑色,1表示白色)和4个神经元用于铸币权(wks、bks、wqs、bqs)。将有两个隐藏层,每个层有515个神经元,一个输出神经元的值介于-1表示黑色获胜,1表示白色获胜,0表示相等的位置。所有神经元都将使用tanh()激活函数

  • 浏览训练视图 在训练期间您可利用向上/向下按钮浏览训练视图。请注意,可显示的训练视图与信息取决于您所选择的运动和您对所选运动内容的编辑。 在手表 Polar Flow 应用和网络服务中,您可添加运动内容以及针对每项运动内容进行具体设置。您可以为各项运动创建自定义训练视图,并选择训练期间想要看到的数据。有关更多信息,请参见 Flow 中的运动内容。 例如,训练视图可以显示以下信息: Your hea

  • 浏览训练视图 在训练期间您可利用向上/向下按钮浏览训练视图。请注意,可显示的训练视图与信息取决于您所选择的运动和您对所选运动内容的编辑。 在手表 Polar Flow 应用和网络服务中,您可添加运动内容以及针对每项运动内容进行具体设置。您可以为各项运动创建自定义训练视图,并选择训练期间想要看到的数据。有关更多信息,请参见 Flow 中的运动内容。 例如,训练视图可以显示以下信息: Your hea

  • 训练视图 您可以通过手腕姿势来启动显示屏并通过上下滑动显示屏来浏览训练视图.显示屏自动关闭以节约电池电量。在训练模式期间,您可以设置不关闭显示屏:通过轻触并按住触摸屏,直到您看到一个灯泡关闭图标。若要关闭此功能,请轻触并再次按住触摸屏,直到您看到一个灯泡关闭图标。 您可以看到以下训练视图。 有心率显示的训练 以当前心率区的颜色显示的当前心率。 到目前为止您的训练的时长。 当日时间。 到目前为止在训

  • 训练视图 您可以通过向上/向下按钮浏览训练视图。您可以看到以下训练视图。 有心率显示的训练 您的当前心率 到目前为止您的训练的时长。 您的当前心率 图表中的数字 130 显示 EnergyPointer 的内容, EnergyPointer 是个人化转折点,在该转折点您的训练的主要作用从燃烧脂肪转为提高健康水平。心形符号告诉您,您是在燃烧脂肪还是在提高健康水平。在图表中,该符号位于左侧,表示您正在

  • 本文向大家介绍relu为何好过sigmoid和tanh?相关面试题,主要包含被问及relu为何好过sigmoid和tanh?时的应答技巧和注意事项,需要的朋友参考一下 先看sigmoid、tanh和RelU的函数图: 第一,采用sigmoid等函数,算激活函数时(指数运算),计算量大,反向传播求误差梯度时,求导涉及除法和指数运算,计算量相对大,而采用Relu激活函数,整个过程的计算量节省很多。 第