☰ Оглавление

Пример обучения нейрона

Обучение нейрона, как вы уже поняли, заключается в «подборе» весов входных сигналов.

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

Здесь всё кажется понятным, кроме, возможно, последнего пункта. Его логика проста. Чем больше ошибка, тем больше должна быть поправка. Чем больше сигнал на входе (чем больше был вклад этого входа в ответ), тем сильнее корректируем вес этого входа. А «константа обучения» задаёт скорость, с которой нейрон делает выводы. Если эта константа мала, то нейрон будет обучаться медленно. Если она слишком велика, то нейрон будет делать слишком поспешные выводы и впадать в крайности.

Итак обучающая процедура будет выглядеть так:

def learn(x, y, desired):
    global wx, wy, wb
    learning_constant = 0.1
    error = desired - neuron(x, y)
    wx += error * x * learning_constant
    wy += error * y * learning_constant
    wb += error * 1 * learning_constant # bias = 1

а цикл обучения можно записать так:

def one_step_of_learning():
    y = 0
    for line in problem:
        x = 0
        for char in line:
            if char == '.':
                learn(x, y, -1)
            if char == '#':
                learn(x, y, 1)
            x += 1
        y += 1

print_solution()
for i in range(100):
    one_step_of_learning()
    print_solution()

Здесь мы используем вспомогательную функцию вывода решения, код которой может быть таким (это не принципиальный момент):

def print_solution():
    y = 0
    for line in problem:
        x = 0
        new_line = ''
        for char in line:
            if char == '?':
                r = neuron(x, y)
                if r < 0:
                    char = '!'
                else:
                    char = '%'
            new_line += char
            x += 1
        print new_line
        y += 1

А принципиальным тут является то, что мы используем и для обучения и для анализа степени обученности один и тот же набор данных. В нашем случае так поступать можно, но в реальных условиях — это было бы грубой ошибкой. Мы ещё вернёмся к этому вопросу, но если вы не дочитаете все заметки, то просто запомните, что обучать сеть и анализировать качество обучения надо на разных данных.

Думаю, что вы получите удовольствие, играя с этим кодом, варьируя задачу, коэффициент обучения, начальный веса…

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

В самом начале (до обучения). Нейрон отвечает всегда одно и то же (чёрное):

...%.....%............#
......%.......%....####
.%........%.....#####%#
.......%.....#####%####
..%..%....#############
.......######%######%##
....#####%#######%#####
.###################%##

После третьего урока в ответах нейрона начинает появляться разнообразие:

...%.....%............#
......%.......%....####
.!........%.....#####%#
.......%.....#####%####
..%..%....#############
.......######%######%##
....#####%#######%#####
.###################%##

После 25 уроков ситуацию получше:

...!.....%............#
......!.......%....####
.!........%.....#####%#
.......%.....#####%####
..!..%....#############
.......######%######%##
....#####%#######%#####
.###################%##

После 32 уроков все ответы правильные:

...!.....!............#
......!.......!....####
.!........!.....#####%#
.......!.....#####%####
..!..!....#############
.......######%######%##
....#####%#######%#####
.###################%##

Итак, наш нейрон обучился. То есть, мы нашли веса, с которыми нейрон выдаёт правильный ответ.

Но мы сделали много упрощений и допущений, которые я вынес в отдельный рассказ. И сейчас самое время к нему перейти.