Однослойный персептрон на языке Python без сторонних модулей
Ожидает приглашения
Я написал уникальный, не имеющий аналогов в мире однослойный персептрон без использования сторонних модулей. Для чего? Что бы всем показывать свою статью на Хабрахабре, очевидно же. Это не перевод и не копия чьей-нибудь статьи, всё своё.
Итак, весь код:
Функция train — обучает, predict — обрабатывает входные данные уже обученными синапсами и выдает ответ, trainmass — запускает обучение по всем входным данным(2 — это количество выходных данных, 4 — количество данных в примере, 1 — это лерн рейт, 60000 — количество циклов обучения), create — создает массив случайных синапсов для обучения.
В этом примере массив X имеет 4 набора данных и массив y 4 набора выходных данных.
После запуска имеем вывод:
Первый массив — это ответ на входные данные X[0] — [0.1, 0.2, 0.3, 0.4].
Второй массив — это ответ на данные которые не были в обучающей выборке [0.5, 0.6, 0.7, 0.8].
Как видите персептрон продолжил числовой ряд почти верно с небольшими отклонениями.
Немного разберем принцип его работы. Персептрон получает что-то похожее на систему линейных уравнений:
И методом обратного распространения ошибки находит соответствующие x1, x2, x3, x4.
Для второго выходного значения создаются другие y1, y2, y3, y4.
Я не стану описывать функцию активации — сигмоид. Если вы разберетесь в этом простом коде вам станет понятно.
Однослойный персептрон может решать только линейные задачи. Для нелинейности нужно добавить еще слой или несколько слоев. Если будет много комментариев, я напишу двухслойную модель.
Итак, весь код:
import random
def train(X, y, syn0, lens0, lens01, lr):
errorreturn = 0
for i in range(0, lens0):
a = 0
for j in range(0, lens01):
a = a + syn0[i][j] * X[j]
b = 1 / (1 + 2.718281828459045235360287471352662497757 ** -a)
error = y[i] - b
errorreturn = errorreturn + abs(error)
delta = (error) * 1 / (1 + 2.718281828459045235360287471352662497757 ** -b) * lr
for z in range(0, lens01):
syn0[i][z] = syn0[i][z] + X[z] * delta
return syn0, errorreturn
def predict(syn0, X, lens0, lens01):
ret = []
for i in range(0, lens0):
a = 0
for j in range(0, lens01):
a = a + syn0[i][j] * X[j]
b = 1 / (1 + 2.718281828459045235360287471352662497757 ** -a)
ret.append(b)
return ret
def trainmass(X, y, syn, lens0, lens01, lr, iter):
for i in range(iter):
for j in range(lens01):
syn, er = train(X[j], y[j], syn, lens0, lens01, lr)
return syn, er
def create(x, y):
syn0 = []
for z in range(0, x):
h = []
for i in range(0, y):
h.append(random.uniform(-0.1, 0.1))
syn0.append(h)
return syn0
syn = create(2, 4)
X = [[0.1, 0.2, 0.3, 0.4],[0.2, 0.3, 0.4, 0.5],[0.4, 0.5, 0.6, 0.7],[0.5,0.6,0.7,0.8]]
y = [[0.5, 0.6],[0.6, 0.7],[0.8, 0.9],[0.9, 1]]
g, r = trainmass(X, y, syn, 2, 4, 1, 60000)
h = predict(syn, X[0], 2, 4)
h2 = predict(syn, [0.5, 0.6, 0.7, 0.8], 2, 4)
print(h)
print(h2)
Функция train — обучает, predict — обрабатывает входные данные уже обученными синапсами и выдает ответ, trainmass — запускает обучение по всем входным данным(2 — это количество выходных данных, 4 — количество данных в примере, 1 — это лерн рейт, 60000 — количество циклов обучения), create — создает массив случайных синапсов для обучения.
В этом примере массив X имеет 4 набора данных и массив y 4 набора выходных данных.
После запуска имеем вывод:
[0.4835439912709079, 0.5593653075469635]
[0.8848108739666853, 0.9682956213528969]
Первый массив — это ответ на входные данные X[0] — [0.1, 0.2, 0.3, 0.4].
Второй массив — это ответ на данные которые не были в обучающей выборке [0.5, 0.6, 0.7, 0.8].
Как видите персептрон продолжил числовой ряд почти верно с небольшими отклонениями.
Немного разберем принцип его работы. Персептрон получает что-то похожее на систему линейных уравнений:
0.1*x1 + 0.2*x2 + 0.3*x3 + 0.4*x4 = 0.5
0.2*x1 + 0.3*x2 + 0.4*x3 + 0.5*x4 = 0.6
0.4*x1 + 0.5*x2 + 0.6*x3 + 0.7*x4 = 0.8
0.5*x1 + 0.6*x2 + 0.7*x3 + 0.8*x4 = 0.9
И методом обратного распространения ошибки находит соответствующие x1, x2, x3, x4.
Для второго выходного значения создаются другие y1, y2, y3, y4.
Я не стану описывать функцию активации — сигмоид. Если вы разберетесь в этом простом коде вам станет понятно.
Однослойный персептрон может решать только линейные задачи. Для нелинейности нужно добавить еще слой или несколько слоев. Если будет много комментариев, я напишу двухслойную модель.