用神经网络逼近对数函数
Approximate Logarithmic Function with a Neural Network
我正在尝试使用神经网络在从 1 到 100 的域上逼近对数函数。我使用 tensorflow
作为软件。结果不如我预期的好,我想了解原因。我使用以下代码:
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
## == data to be approximated == ##
x_grid = np.array([np.linspace(1, 100, 100)]).T
y_grid = np.log(x_grid)
def deepnn(x_val, prior):
"""
A neural network with input values x. Its parameters might be constraint according to a prior.
"""
## == input layer == ##
if prior:
w_in = tf.constant(1., shape=[1, 2]) #fixed to one
b_in = tf.constant([-1., -20.]) # fixed along kinks of the log function
else:
w_in = weight_variable([1, 2])
b_in = bias_variable([2])
f_in = tf.matmul(x_val, w_in) + b_in
## == first hidden layer == ##
g_1 = tf.nn.relu(f_in)
## == output layer == ##
w_out = weight_variable([2, 1])
b_out = bias_variable([1])
y_predict = tf.matmul(g_1, w_out) + b_out
return y_predict
def weight_variable(shape):
"""
generate a weight variable of a given shape
"""
initial = tf.truncated_normal(shape, stddev=0.1)
return tf.Variable(initial)
def bias_variable(shape):
"""
generates a bias variable of a given shape
"""
initial = tf.constant(0.1, shape=shape)
return tf.Variable(initial)
x_given = tf.placeholder(tf.float32, [None, 1])
y_out = deepnn(x_given, False)
y = tf.placeholder(tf.float32, [None, 1])
squared_deltas = tf.square(y_out - y)
loss = tf.reduce_sum(squared_deltas)
optimizer = tf.train.AdamOptimizer(1e-3)
train = optimizer.minimize(loss)
sess = tf.InteractiveSession()
init = tf.global_variables_initializer()
sess.run(init)
for i in range(50000):
sess.run(train, {x_given: x_grid, y: y_grid})
print(sess.run(loss, {x_given: x_grid, y: y_grid}))
sess.close()
神经网络deepnn(x_val, prior)
可以有两种形式:如果prior
为真,输入层函数tf.matmul(x_val, w_in) + b_in
的参数设置为w_in = 1
和b_in = [-1, -20]
。 b_in
的这些值将强制网络在 x = 20
处出现扭结。如果 prior
为假,则参数值被初始化为 w
和 b=0.1
的随机变量。 (这些值以及计算机代码的灵感来自 tensorflow guide。)输入被传递到具有整流器激活函数的隐藏层和输出层。网络是否应该遵循先验在 y_out = deepnn(x_given, False)
.
行中定义
与有先验的网络相比,没有先验限制的神经网络(几乎总是)产生较差的结果。网络就像一个线性函数。奇怪的是,不受限制的网络曾经产生了一个非常好的解决方案,但我无法在随后的试验中复制它。结果如下图所示。
有人可以解释一下为什么我不能很好地训练网络吗?
我没有仔细检查你的代码,但你似乎没有使用任何非线性网络。您的网络很浅(只有 1 个隐藏层),因此要深入(如您在函数中提到的那样),您需要更多层。另外,我认为您的图层中需要更多节点。至少尝试使用 2 个隐藏层。
顺便说一句,有一个功能完全符合所说:tf.nn.xw_plus_b
我正在尝试使用神经网络在从 1 到 100 的域上逼近对数函数。我使用 tensorflow
作为软件。结果不如我预期的好,我想了解原因。我使用以下代码:
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
## == data to be approximated == ##
x_grid = np.array([np.linspace(1, 100, 100)]).T
y_grid = np.log(x_grid)
def deepnn(x_val, prior):
"""
A neural network with input values x. Its parameters might be constraint according to a prior.
"""
## == input layer == ##
if prior:
w_in = tf.constant(1., shape=[1, 2]) #fixed to one
b_in = tf.constant([-1., -20.]) # fixed along kinks of the log function
else:
w_in = weight_variable([1, 2])
b_in = bias_variable([2])
f_in = tf.matmul(x_val, w_in) + b_in
## == first hidden layer == ##
g_1 = tf.nn.relu(f_in)
## == output layer == ##
w_out = weight_variable([2, 1])
b_out = bias_variable([1])
y_predict = tf.matmul(g_1, w_out) + b_out
return y_predict
def weight_variable(shape):
"""
generate a weight variable of a given shape
"""
initial = tf.truncated_normal(shape, stddev=0.1)
return tf.Variable(initial)
def bias_variable(shape):
"""
generates a bias variable of a given shape
"""
initial = tf.constant(0.1, shape=shape)
return tf.Variable(initial)
x_given = tf.placeholder(tf.float32, [None, 1])
y_out = deepnn(x_given, False)
y = tf.placeholder(tf.float32, [None, 1])
squared_deltas = tf.square(y_out - y)
loss = tf.reduce_sum(squared_deltas)
optimizer = tf.train.AdamOptimizer(1e-3)
train = optimizer.minimize(loss)
sess = tf.InteractiveSession()
init = tf.global_variables_initializer()
sess.run(init)
for i in range(50000):
sess.run(train, {x_given: x_grid, y: y_grid})
print(sess.run(loss, {x_given: x_grid, y: y_grid}))
sess.close()
神经网络deepnn(x_val, prior)
可以有两种形式:如果prior
为真,输入层函数tf.matmul(x_val, w_in) + b_in
的参数设置为w_in = 1
和b_in = [-1, -20]
。 b_in
的这些值将强制网络在 x = 20
处出现扭结。如果 prior
为假,则参数值被初始化为 w
和 b=0.1
的随机变量。 (这些值以及计算机代码的灵感来自 tensorflow guide。)输入被传递到具有整流器激活函数的隐藏层和输出层。网络是否应该遵循先验在 y_out = deepnn(x_given, False)
.
与有先验的网络相比,没有先验限制的神经网络(几乎总是)产生较差的结果。网络就像一个线性函数。奇怪的是,不受限制的网络曾经产生了一个非常好的解决方案,但我无法在随后的试验中复制它。结果如下图所示。
有人可以解释一下为什么我不能很好地训练网络吗?
我没有仔细检查你的代码,但你似乎没有使用任何非线性网络。您的网络很浅(只有 1 个隐藏层),因此要深入(如您在函数中提到的那样),您需要更多层。另外,我认为您的图层中需要更多节点。至少尝试使用 2 个隐藏层。
顺便说一句,有一个功能完全符合所说:tf.nn.xw_plus_b