Здравствуйте!
Запрограммировал нейросеть в соответствии со этой статьей. N слоев, M нейронов в каждом слое.
Делаю обучение. На вход много раз подаю вектор, например, такой: (2, 2, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1), использую учитель, например, такой: (0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 2, 2).
В результате на первом слове образуются одинаковые веса, такие, что сигма-функция от них = 0.5. То есть входной вектор просто сглаживается.
То же происходит и на прочих слоях, а на последнем веса такие, что формируют на выходе вектор-учитель.
То есть какой бы я не подал вектор на вход обученной сети, на выходе получаю "ОК".
В принципе, мне понятно, почему сеть так себя ведет. Но ведь так не должно быть.
Видимо, я что-то не понимаю, прошу помочь.
Получается сеть нашла самый простой способ достичь того, что от нее требуется (то есть обеспечить нужный результат на выходе)? 🙂
Получается, что так. Мне тут подсказали, что это потому, что я даю слишком примитивные наборы данных для обучения. А какие наборы - не примитивные? Второй ждень пытаюсь придумать.
Если рассуждать логически с точки зрения сети, то если от нее всегда требуют один и тот же выход, то ей проще всего независимо от входных данных всегда его и выдавать.
Чисто для теста, базовый вариант: f(x1, x2 ... xN) = y - на входе аргументы функции, на выходе результат вычисления. Подаем предварительно рассчитанные сеты - (x1, x2 ... xN, y), обучаем, затем подаем новый входной образец, и сеть должна правильно вычислить значение функции.
А какую функцию посоветуете?
Я сейчас делаю по-другому: генерирую случайные числа 0 ... 255, подаю на вход двоичное представление каждого числа, то есть 8 нулей и единиц. А на выходе ставлю 5 вариантов векторов, в зависимости от того, в каком диапазоне лежит число (0-50, 50-100, 100-150, 150-200, 200-255).
Не хочет правильно работать, все равно возникает "переобученность" сети.
Мне тут подсказали использовать метод Dropout, пока не сделал его. Неужели не получится подобрать пример, который работал бы без дропаута???
А обучающая выборка какого размера? На чем сеть написана кстати?
Пять разных векторов из 8 элементов (нулей или единиц) каждый. Каждый вектор соответствует интервалу, которому принадлежит число на входе.
То есть на входе - 256 разных бинарных векторов, на выходе - 5 шт.
C++, в среде Borland.
То есть на вход в бесконечном цикле подаю очень много случайных бинарных векторов, пока ошибка не перестает уменьшаться. Он перестает уменьшаться, но сеть не обучается должным образом. Большинство слоев "отмирает", последние формируют один и тот же усредненный выход, дающий не слишком большую ошибку для любого входа.
Надо на чем-то максимально примитивном попробовать, чтобы алгоритмы в целом проверить, из серии out = input_1 + 25 * input_2.
В общем, я сдаюсь. Перепробовал много вариантов, все время одно и то же. Усредняет и привет.
Кто бы мне помог, возможно платно, разобраться со всем этим. Отталкиваясь от моих исходников (лучше) или от чужих.
Старый стал, времени не хватает 🙂