感知机英文是perceptron,神经网络中,感知机函数可以实现与门、非门、或门,却无法实现异或门,异或门的实现需要借助其他三种门电路,如下所示。
import numpy as np
def AND(x1, x2):
w1, w2, theta = 0.5, 0.5, 0.7
tmp = w1 * x1 + w2 * x2
if tmp <= theta:
return 0
elif tmp > theta:
return 1
def AND2(x1, x2):
x = np.array([x1, x2])
w = np.array([0.5, 0.5])
b = -0.7
tmp = np.sum(w * x) + b
if tmp <= 0:
return 0
else:
return 1
def NAND(x1, x2):
x = np.array([x1, x2])
w = np.array([-0.5, -0.5])
b = 0.7
tmp = np.sum(w * x) + b
if tmp <= 0:
return 0
else:
return 1
def OR(x1, x2):
x = np.array([x1, x2])
w = np.array([0.5, 0.5])
b = -0.2
tmp = np.sum(w * x) + b
if tmp <= 0:
return 0
else:
return 1
def XOR(x1, x2):
s1 = NAND(x1, x2)
s2 = OR(x1, x2)
return AND(s1, s2)
if __name__ == "__main__":
print('AND(1,1)', AND(1, 1))
print('AND(1,0)', AND(1, 0))
print('AND(0,1)', AND(0, 1))
print('AND(0,0)', AND(0, 0))
print('---------')
print('AND2(1,1)', AND2(1, 1))
print('AND2(1,0)', AND2(1, 0))
print('AND2(0,1)', AND2(0, 1))
print('AND2(0,0)', AND2(0, 0))
print('----------')
print('NAND(1,1)', NAND(1, 1))
print('NAND(1,0)', NAND(1, 0))
print('NAND(0,1)', NAND(0, 1))
print('NAND(0,0)', NAND(0, 0))
print('----------')
print('OR(1,1)', OR(1, 1))
print('OR(1,0)', OR(1, 0))
print('OR(0,1)', OR(0, 1))
print('OR(0,0)', OR(0, 0))
print('----------')
print('XOR(1,1)', XOR(1, 1))
print('XOR(1,0)', XOR(1, 0))
print('XOR(0,1)', XOR(0, 1))
print('XOR(0,0)', XOR(0, 0))
算法运行结果如下:
AND(1,1) 1
AND(1,0) 0
AND(0,1) 0
AND(0,0) 0
---------
AND2(1,1) 1
AND2(1,0) 0
AND2(0,1) 0
AND2(0,0) 0
----------
NAND(1,1) 0
NAND(1,0) 1
NAND(0,1) 1
NAND(0,0) 1
----------
OR(1,1) 1
OR(1,0) 1
OR(0,1) 1
OR(0,0) 0
----------
XOR(1,1) 0
XOR(1,0) 1
XOR(0,1) 1
XOR(0,0) 0
感知机如果没有激活函数,那么它就是一个线性叠加器,无论网络有多少层,最终结果都是线性的,而有了激活函数,那么结果就可以是非线性的,目标与变量的关系可以是一个曲线。
常用的激活函数有如下几种:sigmoid,tanh,relu,softmax,下面通过pytorch来展示一下这些激活函数的特点:
import torch
import torch.nn.functional as F
from torch.autograd import Variable
import matplotlib.pyplot as plt
x = torch.linspace(-5, 5, 200)
x = Variable(x)
x_np = x.data.numpy()
y_relu = torch.relu(x).data.numpy()
y_sigmoid = torch.sigmoid(x).data.numpy()
y_tanh = torch.tanh(x).data.numpy()
y_softplus = F.softplus(x).data.numpy()
plt.figure(1, figsize=(8, 6))
plt.subplot(221)
plt.plot(x_np, y_relu, c='red', label='relu')
plt.ylim((-1, 5))
plt.legend(loc='best')
plt.subplot(222)
plt.plot(x_np, y_sigmoid, c='red', label='sigmoid')
plt.ylim((-0.2,1.2))
plt.legend(loc='best')
plt.subplot(223)
plt.plot(x_np, y_tanh, c='red', label='tanh')
plt.ylim((-1.2, 1.2))
plt.legend(loc='best')
plt.subplot(224)
plt.plot(x_np, y_softplus, c='red', label='softplus')
plt.ylim((-0.2, 6))
plt.legend(loc='upper left')
plt.show()
运行程序,图表显示如下:
在神经网络中,使用最多的是relu激活函数,它的全称是Rectified Linear Units,函数表达式为y = max(0,x)。在x<0的时候,直接取0值。