Нейронная сеть сходится только тогда, когда облако данных близко к 0 - PullRequest
0 голосов
/ 09 мая 2018

Я новичок в tenorflow и сейчас изучаю основы, поэтому, пожалуйста, потерпите меня.

Моя проблема связана со странным не сходящимся поведением нейронных сетей, когда перед ним ставится предположительно простая задача поиска функции регрессии для небольшого обучающего набора, состоящего только из 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 выходным нейроном. Функция активации по умолчанию является сигмоидальной функцией. X соответствует входному тензору, Y - меткам обучающих данных, а Phi - прямому выходу нейронной сети. Операция train_step выполняет один шаг градиентного спуска при выполнении в среде сеанса.

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

before training

enter image description here

Перед тренировкой сеть кажется плоской линией. После 100 000 обучающих итераций ему удается частично изучить функцию, но только ту часть, которая ближе к 0. После этого она снова становится плоской. Дальнейшее обучение больше не уменьшает функцию потерь.

Это становится еще более странным, когда я беру точно такой же набор данных, но сдвигаю все значения x, добавляя 500:

enter image description here enter image description here

Здесь сеть полностью отказывается учиться. Я не могу понять, почему это происходит. Я пытался изменить архитектуру сети и скорость ее обучения, но наблюдал аналогичные эффекты: чем ближе значения x облака данных к источнику, тем легче сеть может учиться. После определенного расстояния до начала обучения обучение полностью прекращается. Изменение функции активации с сигмоида на ReLu только ухудшило ситуацию; здесь сеть имеет тенденцию просто сходиться к среднему, независимо от того, в каком положении находится облако данных.

Что-то не так с моей реализацией нейронного сетевого конструктора? Или это как-то связано со значениями инициализации? Я довольно долго пытался глубже понять эту проблему и был бы очень признателен за некоторые советы. Что может быть причиной этого? Все мысли о том, почему это происходит, приветствуются!

Спасибо, Joker

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...