Приближенная логарифмическая функция с нейронной сетью

Я пытаюсь аппроксимировать логарифмическую функцию в домене от одного до ста с помощью нейронной сети. Я использую 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. ) Входы передаются на скрытый уровень с функциями активации выпрямителя и выходной уровень. Должна ли сеть придерживаться предыдущего или нет, определяется в строке y_out = deepnn(x_given, False).

Нейронная сеть без априорных ограничений дает (почти всегда) худшие результаты по сравнению с сетью с априорными. Сеть просто напоминает линейную функцию. Любопытно, что неограниченная сеть однажды дала очень хорошее решение, которое я не смог воспроизвести в последующих испытаниях. Результаты визуализированы на рисунке ниже. Аппроксимация функции с помощью нейронной сети

Может ли кто-нибудь объяснить, почему я не могу хорошо обучить сеть?


person fabian    schedule 22.11.2017    source источник


Ответы (1)


Я не проверял тщательно ваш код, но кажется, что вы не используете нелинейную сеть. Ваша сеть неглубокая (всего 1 скрытый слой), поэтому, чтобы быть глубокой (как вы упоминаете в функции), вам нужно больше слоев. Кроме того, я думаю, вам нужно больше узлов в вашем слое. Попробуйте хотя бы с двумя скрытыми слоями.

Кстати, есть функция, которая делает именно то, что написано: tf.nn.xw_plus_b< /а>

person Eypros    schedule 22.11.2017
comment
Спасибо вам за ваши предложения! Может быть, у вас есть идея, почему сеть, которую я использую без сильного предварительного предположения, не так хорошо обучается? Оцененные параметры нейронной сети не минимизируют функцию потерь. - person fabian; 23.11.2017