我是tensorflow的新手,我正在学习基础知识,所以请耐心等待。
我的问题涉及神经网络奇怪的非收敛行为,当提出一个简单的任务,即找到一个只包含m = 100个数据点的小型训练集的回归函数{(x_1,y_1),(x_2,y_2) ),...,(x_100,y_100)},其中x_i和y_i是实数。
我首先构建了一个自动生成与经典完全连接的前馈神经网络相对应的计算图的函数:
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对应于训练数据的标签,Ph对应于神经网络的前馈输出。当在会话环境中执行时,操作train_step执行一个梯度下降步骤。
到目前为止,这么好。如果我现在通过使用从正弦波中提取的人工数据的简单回归函数来测试特定的神经网络(使用此函数和上面给出的参数构造的确切默认值),就会发生奇怪的事情:
在训练之前,网络似乎是一条扁平线。在100,000次训练迭代之后,它设法部分地学习该功能,但只有接近0的部分。此后,它再次变得平坦。进一步的训练不会再减少损失功能。
当我采用完全相同的数据集时,这甚至更奇怪,但是通过添加500来移动所有x值:
在这里,网络完全拒绝学习。我不明白为什么会这样。我已经尝试改变网络的体系结构及其学习速度,但观察到类似的效果:数据云的x值越接近原点,网络就越容易学习。离原点一定距离后,学习完全停止。将激活函数从sigmoid更改为ReLu只会使事情变得更糟;无论数据云处于什么位置,网络都倾向于收敛到平均值。
我的神经网络构造函数的实现有问题吗?或者这与初始化值有关吗?我试图在很长一段时间内对这个问题有更深入的了解,并且非常感谢一些建议。可能是什么原因造成的?关于为什么会发生这种行为的所有想法都非常受欢迎!
谢谢, 小丑