我是 tensorflow 的新手,目前正在学习基础知识,所以请多多包涵。
我的问题涉及神经网络的奇怪的非收敛行为,当提出一个简单的任务时,即为仅由以下内容组成的小型训练集找到回归函数数据点, 在哪里和是实数。
我首先构建了一个函数,该函数自动生成对应于经典全连接前馈神经网络的计算图:
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 只会让事情变得更糟;在这里,无论数据云处于什么位置,网络都倾向于收敛到平均值。
我的神经网络构造函数的实现有问题吗?还是这与初始化值有关?很长一段时间以来,我一直试图更深入地了解这个问题,并非常感谢一些建议。这可能是什么原因?非常欢迎所有关于为什么会发生这种行为的想法!
谢谢,小丑



