Нейронные сети. Эволюция
Шрифт:
Давайте разбираться что же мы тут написали.
В любом классе можно определить функцию __init__. Эта функция всегда вызывается, когда мы создаем реальный объект класса, с изначально заданными атрибутами. Атрибут – это переменная, которая относится к классу, в котором она определена. В нашем случае, при создании объекта, мы сразу можем указать его атрибуты – кличку и количество лет, которые сразу присваиваются этому объекту. Через созданный нами метод status, мы можем вывести информацию о количестве лет и кличке нашего объекта. Метод number_of_years (self, years), принимает число и изменяет атрибут класса – количество лет. Метод says,
ГЛАВА 3
Рождение искусственного нейрона
Моделирование нейрона как линейного классификатора
Настало время практически реализовать линейную классификацию. Для этого в Python смоделируем работу искусственного нейрона. Попробуем решить нашу задачу, найдя промежуточные значения, при заданном наборе входных и соответствующим им выходным (целевым) параметрам. Как мы помним – это были высота и длина двух разных видов животных. Это может быть и любой другой условный набор данных, которые можно представить, как параметры размеров одежды, предметов, насекомых, веса, стоимости, градусов и любых других. Отобразим наше задание – список с параметрами двух видов животных:
В дальнейшем все данные, которые надо анализировать при помощи искусственных нейронов и их сетей, будем называть – обучающей выборкой. А процесс изменения коэффициентов, в нашем случае – коэффициент А, в зависимости от функции ошибки на выходе, будем называть – процессом обучения.
Примем за значение х – длины животных, а Y – высота. Так как Y (игрек большое) – это и есть ответ: Y = Ax, то условимся что он и будет целевым значением для нашего нейрона (правильным ответом), а входными данными будут все значения переменной х.
Отобразим для лучшего представления входных данных, график обучающей выборки:
Видно, что наши данные напоминают прямую линию, уравнение которой Y = = 2*x. Данные находятся около значений этой функции, но не повторяют их. Задача нашего нейрон суметь с большой точностью провести эту прямую, несмотря на то, что данные по остальным точкам отсутствуют (например, нет данных о Y координате с точкой с x = 5).
Cмоделируем такую структуру, для чего подадим на вход нейрона (дендрит у биологического нейрона), значение x, и меняя коэффициент A (синапс у биологического нейрона), по правилам, которые мы вывели с линейным классификатором, будем получать выходные значения нейрона y (аксон у биологического нейрона). Так же условимся, что Y (большое) – правильный ответ (целевое значение), а y (малое) – ответ нейрона (его выход).
Визуализируем структуру нейрона, которую будем моделировать:
Запрограммировав
в Python эту структуру, попробуем добиться прямой, которая максимально точно разделит входные параметры.Программа
Действовать будем так же, как мы действовали, рассчитывая линейный классификатор.
Создадим переменную А, являющейся коэффициентом крутизны наклона прямой, и зададим ей любое значение, пусть это будет всё те же А=0.4.
A = 0.4
Запомним начальное значение коэффициента А:
A_vis = A
Покажем функцию начальной прямой:
print('Начальная прямая: ', A, '* X')
Укажем значение скорости обучения:
lr = 0.001
Зададим количество эпох:
epochs = 3000
Эпоха – значение количества проходов по обучающей выборке. Если в нашей выборке девять наборов, то одна эпоха – это один проход в цикле всех девяти наборов данных.
Зададим наш набор данных, используя массивы. Создадим два массива. В один массив поместим все входные данные – x, а в другой целевые значения (ответы) – Y.
Создадим массив входных данных х:
arr_x = [1, 2, 3, 3.5, 4, 6, 7.5, 8.5, 9]
Создадим массив целевых значений (ответы Y):
arr_y = [2.4, 4.5, 5.5, 6.4, 8.5, 11.7, 16.1, 16.5, 18.3]
Задаем в цикле эпох, вложенный цикл – for i in range(len(arr)), который будет последовательно пробегать по входным данным, от начала до конца. А циклом – for e in range(epochs), мы как раз указываем количество таких пробегов (итераций):
for e in range(epochs):
for i in range(len(arr)):
Функция len(arr) возвращает длину массива, в нашем случае возвращает девять.
Получаем x координату точки из массива входных значений x:
x = arr_x[i]
А затем действуем как в случае с линейным классификатором:
# Получить расчетную y, координату точки
y = A * x
# Получить целевую Y, координату точки
target_Y = arr_y[i]
# Ошибка E = целевое значение – выход нейрона
E = target_Y – y
# Меняем коэффициент при x, в соответствии с правилом A+дельтаA = A
A += lr*(E/x)
Напомню, процессом изменения коэффициентов в ходе выполнения цикла программы, называют – процессом обучения.
Выведем результат после обучения:
print('Готовая прямая: y = ', A, '* X')
Полный текст программы:
# Инициализируем любым числом коэффициент крутизны наклона прямой
A = 0.4
A_vis = A # Запоминаем начальное значение крутизны наклона
# Вывод данных начальной прямой
print('Начальная прямая: ', A, '* X')
# Скорость обучения
lr = 0.001
# Зададим количество эпох
epochs = 3000
# Создадим массив входных данных x
arr_x = [1, 2, 3, 3.5, 4, 6, 7.5, 8.5, 9]
# Создадим массив целевых значений (ответы Y)
arr_y = [2.4, 4.5, 5.5, 6.4, 8.5, 11.7, 16.1, 16.5, 18.3]
<