Perceptron

Sea una red neuronal con arquitectura perceptron(de una sola capa), cuya salida se calcula de la siguiente manera:

$$\mathbf{a} = \mathbf{f}(_{1}\mathbf{W} \, \mathbf{p} + \mathbf{b})$$

Donde:

$_{1}\mathbf{W}$: matriz de pesos (parámetro de la red)

$\mathbf{p}$: vector de entradas

$\mathbf{b}$: vector de bias (parámetro de la red)

$\mathbf{f}$: es una función de transferencia hardlim

y sea la siguiente regla de aprendizaje:

$$e = t - a$$$$_{1}\mathbf{W}^{new} = (_{1}\mathbf{W}^{old})+ e \, \mathbf{p} $$$$\mathbf{b}^{new} = \mathbf{b}^{old} + e $$

In [174]:
# Imports
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

In [175]:
# definimos la funcion de transferencia
hardlim = lambda t: .5 * (np.sign(t) + 1)

In [176]:
# Inputs
p_1 = np.array([1,1])
p_2 = np.array([1,-1])
p_3 = np.array([-1,1])
p_4 = np.array([-1,-1])

# Targets
t_1 = 1
t_2 = 0
t_3 = 0
t_4 = 0

In [177]:
# Conjunto de datos
data_set_2 = ((p_1,t_1),(p_2,t_2),(p_3,t_3),(p_4,t_4))

In [178]:
for data in data_set_2:
    print 'input:%s --> target:%s' % (data[0],data[1])


input:[1 1] --> target:1
input:[ 1 -1] --> target:0
input:[-1  1] --> target:0
input:[-1 -1] --> target:0

In [179]:
# Condicion inicial 
W = np.random.uniform(-1,1,size=2)
W


Out[179]:
array([ 0.88649679,  0.29474092])

In [180]:
# Condicion inicial
b = np.random.uniform(-1,1)
b


Out[180]:
-0.708079080099167

In [181]:
# Entrenamiento
flag = True
epocas = 0
while flag:
    flag = False
    for data in data_set_2:
        a = hardlim(np.dot(W,data[0]) + b)
        t = data[1]
        e = t - a 
        
        if np.abs(e) > 0:
            flag = True
            W = W + e * data[0]
            b = b + e
   
    epocas += 1

In [182]:
W


Out[182]:
array([ 0.88649679,  0.29474092])

In [183]:
b


Out[183]:
-0.708079080099167

In [184]:
np.arctan2(W[1],W[0])


Out[184]:
0.32098079759315368

In [185]:
# Verificacion
for data in data_set_2:
    a2 = hardlim(np.dot(W,data[0]) + b)
    print 'input:%s --> salida:%s --> target:%s' % (data[0],a2,data[1])
print 'Numero de epocas:', epocas


input:[1 1] --> salida:1.0 --> target:1
input:[ 1 -1] --> salida:0.0 --> target:0
input:[-1  1] --> salida:0.0 --> target:0
input:[-1 -1] --> salida:0.0 --> target:0
Numero de epocas: 1

In [186]:
# Funcion de la frontera de decision Wp + b = 0
def decision_boun(t,w,b):
    """
    Decision boundary 
    """
    
    return (-b - t * w[1])/(w[0])

In [187]:
t = np.linspace(-2,2)

In [189]:
# Plots
for data in data_set_2[1:]:
   
    plt.scatter(data[0][0],data[0][1],s=70)
    plt.xlim((-1.5,1.5))
    plt.ylim((-1.5,1.5))
    plt.grid()
plt.plot(data_set_2[0][0][0],data_set_2[0][0][1],'ro',markersize=10)
plt.plot(t,decision_boun(t,W,b),'g--',linewidth=4)
plt.fill_between(t,decision_boun(t,W,b),-1.5,facecolor='green')


Out[189]:
<matplotlib.collections.PolyCollection at 0x4fade90>

In [188]: