同或逻辑运算
在吴恩达的机器学习教程中,讲解了同或逻辑运算的神经网络实现原理,我将其用python语言实现一下。异或即相同取1,不同取0,真值表如下:
x1 | x2 | x1 XNOR x2 |
0 | 0 | 1 |
1 | 0 | 0 |
0 | 1 | 0 |
1 | 1 | 1 |
神经网络的设计
同或运算的神经网络包括三层:输入层、隐藏层、输出层。首先需要实现以下三个部分:
(1)x1 AND x2
与运算的真值表如下:
x1 | x2 | x1 AND x2 |
0 | 0 | 0 |
1 | 0 | 0 |
0 | 1 | 0 |
1 | 1 | 1 |
使用神经网络来实现的话,其权重矩阵为:[-30,20,20]。示意图如下:
假设输入的x1和x2为[1,0],加上偏置项后与权重向量相乘:1*(-30)+1*20+0*20=(-10),而-10经过激活函数后输出近似为0。假设输入的是[1,1],加上偏置项后与权重向量相乘:1*(-30)+1*20+1*20=10,经过激活函数后输出近似为1,这样就实现了与运算。
(2)(NOT x1) AND (NOT x2)
该运算的真值表如下:
x1 | x2 | (NOT x1) AND (NOT x2) |
0 | 0 | 1 |
1 | 0 | 0 |
0 | 1 | 0 |
1 | 1 | 0 |
使用神经网络来实现,其权重矩阵为:[10,-20,-20]。示意图如下:
假设输入的x1和x2为[0,0],加上偏置项后与权重向量相乘:1*10+0*(-20)+0*(-20)=10,经激活函数后输出近似为1。假设输入的为[1,0],加上偏置项后与权重向量相乘:1*10+1*(-20)+0*(-20)=-10,经激活函数后输出近似为0。
(3)x1 OR x2。
或运算的真值表如下:
x1 | x2 | x1 OR x2 |
0 | 0 | 0 |
1 | 0 | 1 |
0 | 1 | 1 |
1 | 1 | 1 |
使用神经网络来实现,其权重矩阵为:[-10,20,20],示意图如下:
假设输入的x1和x2为[0,0],加上偏置项后与权重向量相乘:1*(-10)+0*20+0*20=(-10),经激活函数后输出近似为0;假设输入的是[1,1],加上偏置项后与权重向量相乘:1*(-10)+1*20+1*20=30,经激活函数后输出近似为1。
神经网络的实现
将上述实现的三个部分组合起来,如下图所示:
神经网络中的三个参数矩阵分别对应了上面实现的三个神经网络的参数矩阵。其计算过程为:
x1 | x2 | a1 | a2 | h(x) |
0 | 0 | 0 | 1 | 1 |
1 | 0 | 0 | 0 | 0 |
0 | 1 | 0 | 0 | 0 |
1 | 1 | 1 | 0 | 1 |
python实现
在将一个单元的输出作为另一个单元的输入时,由于激活函数的影响,输出的值并不是准确的0或1,而直接使用python中的int()函数会将数值的小数部分直接舍掉。这时可以用计算机中的四舍五入来将其规范为整数值,即int(x+0.5)。
import numpy as np
# 激活函数
def sigmoid(x):
return 1 / (1 + np.exp(-x))
class Neuron():
def __init__(self, weights1,weights2,weights3):
self.weights1=weights1
self.weights2=weights2
self.weights3=weights3
def XNOR(self, inputs):
inputs=np.insert(inputs,0,1)
a1=np.dot(self.weights1,inputs)
a2=np.dot(self.weights2,inputs)
g=[1,int(sigmoid(a1)+0.5),int(sigmoid(a2)+0.5)]
b=np.dot(self.weights3,g)
return sigmoid(b)
weights1 = np.array([-30,20,20])
weights2 = np.array([10,-20,-20])
weights3 = np.array([-10,20,20])
n = Neuron(weights1,weights2, weights3)
# inputs
x = np.array([0,0])
print(n.XNOR(x))