【问题标题】:Tensorflow ReLu doesn't work?TensorFlow ReLu 不起作用?
【发布时间】:2018-11-23 02:28:45
【问题描述】:

我在 tensorflow 中编写了一个卷积网络,使用 relu 作为激活函数,但它不是学习的(评估和训练数据集的损失都是恒定的)。 对于不同的激活函数,一切正常。

这里是创建 nn 的代码:

def _create_nn(self):
    current = tf.layers.conv2d(self.input, 20, 3, activation=self.activation)
    current = tf.layers.max_pooling2d(current, 2, 2)
    current = tf.layers.conv2d(current, 24, 3, activation=self.activation)
    current = tf.layers.conv2d(current, 24, 3, activation=self.activation)
    current = tf.layers.max_pooling2d(current, 2, 2)
    self.descriptor = current = tf.layers.conv2d(current, 32, 5, activation=self.activation)
    if not self.drop_conv:
        current = tf.layers.conv2d(current, self.layer_7_filters_n, 3, activation=self.activation)
    if self.add_conv:
        current = tf.layers.conv2d(current, 48, 2, activation=self.activation)

    self.descriptor = current

    last_conv_output_shape = current.get_shape().as_list()
    self.descr_size = last_conv_output_shape[1] * last_conv_output_shape[2] * last_conv_output_shape[3]

    current = tf.layers.dense(tf.reshape(current, [-1, self.descr_size]), 100, activation=self.activation)
    current = tf.layers.dense(current, 50, activation=self.last_activation)

    return current

self.activiation 设置为 tf.nn.relu,self.last_activiation 设置为 tf.nn.softmax

损失函数和优化器在这里创建:

    self._nn = self._create_nn()

    self._loss_function = tf.reduce_sum(tf.squared_difference(self._nn, self.Y), 1)

    optimizer = tf.train.AdamOptimizer()
    self._train_op = optimizer.minimize(self._loss_function)

我尝试通过将 tf.random_normal_initializer(0.1, 0.1) 作为初始化器传递来更改变量初始化,但它并没有导致损失函数发生任何变化。

如果能帮助我使这个神经网络与 ReLu 一起工作,我将不胜感激。

编辑:Leaky ReLu 也有同样的问题

编辑:我设法复制相同错误的小例子:

x = tf.constant([[3., 211., 123., 78.]])
v = tf.Variable([0.5, 0.5, 0.5, 0.5])
h_d = tf.layers.Dense(4, activation=tf.nn.leaky_relu)
h = h_d(x)
y_d = tf.layers.Dense(4, activation=tf.nn.softmax)
y = y_d(h)
d = tf.constant([[.5, .5, 0, 0]])

h_d 和 y_d 内核和偏差的梯度(使用 tf.gradients 计算)等于或接近 0

【问题讨论】:

    标签: python tensorflow neural-network conv-neural-network relu


    【解决方案1】:

    在极不可能的情况下,某个层中的所有激活对于所有样本都可能为负。它们被 ReLU 设置为零并且没有学习进度,因为在 ReLU 的负部分中梯度为零。

    使这种情况更有可能发生的原因是数据集小、输入特征的奇怪缩放、不适当的权重初始化和/或中间层中的通道太少。

    这里你使用random_normal_initializermean=0.1,所以你的输入可能都是负数,因此被映射到负值。尝试mean=0,或重新调整输入功能。

    您也可以尝试 Leaky ReLU。也可能学习率太小或太大。

    【讨论】:

    • 所有输入都是正数,值在 0 到 255 之间。Leaky relu 有同样的问题(还有 elu)
    【解决方案2】:

    看起来问题出在输入数据的规模上。值在 0 到 255 之间时,尺度或多或少保留在下一层中,从而使最后一层的预激活输出具有足够大的差异以将 softmax 梯度降低到(几乎)0。 只有使用类似 relu 的激活函数才能观察到,因为其他的,如 sigmoid 或 softsign,使网络中的值范围更小,数量级为 1,而不是几十或几百。

    这里的解决方案是仅乘以输入以将其重新缩放为 0-1,如果是字节,则乘以 1/255。

    【讨论】:

    • 我在之前的回答中介绍了“输入特征的奇怪缩放”。
    猜你喜欢
    • 2016-12-03
    • 1970-01-01
    • 2021-04-10
    • 2017-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-07
    • 2022-11-14
    相关资源
    最近更新 更多