神经网络只有在数据云接近 0 时才会收敛

数据挖掘 机器学习 神经网络 回归
2022-03-01 03:04:12

我是 tensorflow 的新手,目前正在学习基础知识,所以请多多包涵。

我的问题涉及神经网络的奇怪的非收敛行为,当提出一个简单的任务时,即为仅由以下内容组成的小型训练集找到回归函数m=100数据点{(x1,y1),(x2,y2),...,(x100,y100)}, 在哪里xiyi是实数。

我首先构建了一个函数,该函数自动生成对应于经典全连接前馈神经网络的计算图:

import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
import math

def neural_network_constructor(arch_list = [1,3,3,1], 
                               act_func = tf.nn.sigmoid, 
                               w_initializer = tf.contrib.layers.xavier_initializer(), 
                               b_initializer = tf.zeros_initializer(),
                               loss_function = tf.losses.mean_squared_error,
                               training_method = tf.train.GradientDescentOptimizer(0.5)):

    n_input = arch_list[0]
    n_output = arch_list[-1]

    X = tf.placeholder(dtype = tf.float32, shape = [None, n_input])

    layer = tf.contrib.layers.fully_connected(
            inputs = X,
            num_outputs = arch_list[1],
            activation_fn = act_func,
            weights_initializer = w_initializer,
            biases_initializer = b_initializer)

    for N in arch_list[2:-1]:
        layer = tf.contrib.layers.fully_connected(
                inputs = layer,
                num_outputs = N,
                activation_fn = act_func,
                weights_initializer = w_initializer,
                biases_initializer = b_initializer)

    Phi = tf.contrib.layers.fully_connected(
            inputs = layer,
            num_outputs = n_output,
            activation_fn = tf.identity,
            weights_initializer = w_initializer,
            biases_initializer = b_initializer)


    Y = tf.placeholder(tf.float32, [None, n_output])

    loss = loss_function(Y, Phi)
    train_step = training_method.minimize(loss)

    return [X, Phi, Y, train_step]

使用上述参数的默认值,此函数将构建一个计算图,该计算图对应于具有 1 个输入神经元、2 个隐藏层、每个具有 3 个神经元和 1 个输出神经元的神经网络。激活函数默认为 sigmoid 函数。X 对应于输入张量,Y 对应于训练数据的标签,Phi 对应于神经网络的前馈输出。train_step 操作在会话环境中执行时执行一个梯度下降步骤。

到现在为止还挺好。如果我现在测试一个特定的神经网络(用这个函数和上面给出的参数的确切默认值构建),让它学习一个从正弦波中提取的人工数据的简单回归函数,就会发生奇怪的事情:

训练前

在此处输入图像描述

在训练之前,网络似乎是一条平坦的线。经过 100.000 次训练迭代后,它设法部分学习了函数,但只学习了更接近 0 的部分。在此之后,它再次变得平坦。进一步的训练不再减少损失函数。

当我采用完全相同的数据集时,这变得更加奇怪,但是通过添加 500 来移动所有 x 值:

在此处输入图像描述 在此处输入图像描述

在这里,网络完全拒绝学习。我不明白为什么会这样。我曾尝试改变网络的架构及其学习率,但观察到类似的效果:数据云的 x 值越接近原点,网络就越容易学习。到原点一定距离后,学习完全停止。将激活函数从 sigmoid 更改为 ReLu 只会让事情变得更糟;在这里,无论数据云处于什么位置,网络都倾向于收敛到平均值。

我的神经网络构造函数的实现有问题吗?还是这与初始化值有关?很长一段时间以来,我一直试图更深入地了解这个问题,并非常感谢一些建议。这可能是什么原因?非常欢迎所有关于为什么会发生这种行为的想法!

谢谢,小丑

2个回答

梯度下降(神经网络依赖于学习)对特征缩放很敏感;您可能应该首先标准化 x 值。

在您特定的 shift-by-500 情况下,我猜最佳权重位于接近零数字的小范围内,因此梯度下降很难找到那些合适的权重。那么,也许不是一个局部最小值,而是一个高原,即 sigmoids 正在饱和?
https://datascience.stackexchange.com/a/13221/55122

输入根本不足以正确预测输出,模型无法学习输出条件分布 P(y|x)。

您必须向 Naive NN 模型添加更多特征,例如将前一个 x 连接到当前 x 以预测当前 y 或使用类似 RNN 的模型将问题建模为
p(y_t|x_t,x_t-1,x_t-2 ,....x_t0)

请参阅使用 LSTM 进行时间序列预测