Персептрон для функции OR не сходится

Я реализую простой персептрон для классификации функции ИЛИ в Python. однако ошибка не обратится. Любое предложение будет высоко оценено.

def activation_function(x):
    if x<0:
        return 0
    else:
        return 1

training_set = [((0, 0), 0), ((0, 1), 1), ((1, 0), 1), ((1, 1), 1)]

w = random.rand(2)
errors = [] 
eta = .2
n = 100

for i in range(n):
    for x, y in training_set:
        u = sum(x*w)        
        error = y - activation_function(u)       
        errors.append(error) 

        for index, value in enumerate(x):
            w[index] += eta * error * value

ylim([-1,1]) 
plot(errors)

Ошибка графика:

1 ответ

Решение

Я бы сказал, что вам не хватает предвзятости...

Если вы добавите его, он будет красиво сходиться.

import numpy as np
import matplotlib.pyplot as py

np.random.seed(42)
w = np.random.rand(2)
b = 0
errors = [] 
eta = .2
n = 10

for i in range(n):
    for x, y in training_set:
        u = np.sum(x*w)+b     
        error = y - activation_function(u)       
        errors.append(error) 

        for index, value in enumerate(x):
            #print(index, " ", value)
            w[index] += eta * error * value
            b += eta*error

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

И, кстати, это результат классификации. Я надеюсь, что цвета имеют смысл... Красный и синий цвета выглядят довольно броско, но вы поняли идею. Обратите внимание, что вы можете найти бесконечные решения этой проблемы. Поэтому, если вы измените случайное начальное число, вы получите другую линию, которая будет линейно разделять ваши точки.

Кроме того, ваш алгоритм не сходится, поскольку, когда ваша линия проходит через (0,0), хотя ваш прогноз неверен, веса не будут обновляться, так как value=0 для этого конкретного момента. Так что проблема в том, что ваше обновление ничего не сделает. Это является причиной колебаний вашей ошибки.

РЕДАКТИРОВАТЬ в соответствии с просьбой Я написал небольшое руководство (блокнот Jupyter) с некоторым примером того, как нарисовать границу решения классификатора. Вы можете найти его на GitHub

репозиторий github: https://github.com/michelucci/python-Utils

Надеюсь, это полезно.

РЕДАКТИРОВАТЬ 2: И если вы хотите быструю и очень грязную версию (ту, которую я использовал для сюжета красным и синим), вот код

lim = 3.0
X1 = [x1 for x1 in np.arange(-lim,lim,0.1)]
X2 = [x2 for x2 in np.arange(-lim,lim,0.1)]
XX = [(x1,x2) for x1 in np.arange(-lim,lim,0.1) for x2 in np.arange(-lim,lim,0.1)]
Xcolor = ["blue" if np.sum(w[0]*x1+w[1]*x2)+b > 0  else "red" for x1 in X1 for x2 in X2]
x,y = zip(*XX)
py.scatter(x,y, c = Xcolor)
py.scatter(0,0, c = "black")
py.scatter(1,0, c = "white")
py.scatter(0,1, c = "white")
py.scatter(1,1, c = "white")
py.show()
Другие вопросы по тегам