Нейронная сеть с 1 скрытым слоем не может изучить функцию шахматной доски?

Я только начинаю изучать нейронные сети, чтобы посмотреть, могут ли они быть полезными для меня.

Я скачал этот простой код Python из 3-х слойной нейронной сети с прямой связью

и я просто изменил шаблон обучения на шахматную доску вместо XOR и количество узлов в скрытом слое до 10. Если я понимаю теорему универсального приближения, эта трехслойная сеть (один скрытый слой) должна быть способна изучать любую функцию от R2 до R, включая мою функция шахматной доски. ... но это не так.

Что случилось?

  • Я неправильно понимаю теорему об универсальном приближении - может быть, функция должна быть монотонной или выпуклой? (Площадь должна быть линейно отделимой?).
  • Мне нужен другой слой (2 скрытых слоя), чтобы приблизить такую ​​невыпуклую, нелинейно отделимую функцию?
  • Сеть просто поймана в какой-то локальный минимум? (но я так не думаю? Я пробовал несколько прогонов, начальный вес случайный, но результат тот же)
  • 10 узлов в скрытом слое не достаточно? Я пробовал другой номер - с 5 это почти то же самое. С 30 это не

Есть ли общий подход, как модифицировать схему оптимизации (обучения), чтобы она сходилась к любой функции, которая теоретически может быть описана данной сетью в соответствии с теоремой универсального приближения?

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

Это результаты с 10 нейронами в скрытом слое:

 train it with some patterns 
error 3.14902
error 1.37104
error 1.35305
error 1.30453
error 1.28329
error 1.27599
error 1.27275
error 1.27108
error 1.27014
error 1.26957
 test it 
([0.0, 0.0], '->', [0.019645293674000152])
([0.0, 0.5], '->', [0.5981006916165954])
([0.0, 1.0], '->', [0.5673621981298169])
([0.5, 0.0], '->', [0.5801274708105488])
([0.5, 0.5], '->', [0.5475774428347904])
([0.5, 1.0], '->', [0.5054692523873793])
([1.0, 0.0], '->', [0.5269586801603834])
([1.0, 0.5], '->', [0.48368767897171666])
([1.0, 1.0], '->', [0.43916379836698244])

Это определение тестового прогона (только часть кода, который я изменил):

def demo():
    # Teach network checkerboard function
    pat = [
        [ [0.0,0.0], [0.0] ],
        [ [0.0,0.5], [1.0] ],
        [ [0.0,1.0], [0.0] ],

        [ [0.5,0.0], [1.0] ],
        [ [0.5,0.5], [0.0] ],
        [ [0.5,1.0], [1.0] ],

        [ [1.0,0.0], [0.0] ],
        [ [1.0,0.5], [1.0] ],
        [ [1.0,1.0], [0.0] ]
        ]

    # create a network with two input, 10 hidden, and one output nodes
    n = NN(2, 10, 1)
    print " train it with some patterns "
    n.train(pat)
    print " test it "
    n.test(pat)

1 ответ

Теорема универсального приближения показывает, что любая непрерывная функция может быть произвольно аппроксимирована одним скрытым слоем. Это не требует какого-либо разделения данных, речь идет о произвольных функциях.

В частности, если у вас есть N скрытых узлов, где N - количество обучающих выборок, то всегда можно отлично выучить ваш тренировочный набор (он может просто запомнить все пары ввода-вывода).

Однако нет никаких гарантий относительно обобщения таких объектов, равно как и нет гарантий обучения меньших сетей. Нейронные сети не являются "универсальными ответами", с ними довольно сложно справиться правильно.

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

  • ошибка реализации
  • отсутствие правильных функций активации в нейронах (и / или смещения)
Другие вопросы по тегам