一、Introduction
Perceptron can represent AND,OR,NOT
用初中的線性規划問題理解

異或的里程碑意義
想學的通透,先學歷史!
據說在人工神經網絡(artificial neural network, ANN)發展初期,由於無法實現對多層神經網絡(包括異或邏輯)的訓練而造成了一場ANN危機,到最后BP算法的出現,才讓訓練帶有隱藏層的多層神經網絡成為可能。因此異或的實現在ANN的發展史是也是具有里程碑意義的。異或之所以重要,是因為它相對於其他邏輯關系,例如與(AND), 或(OR)等,異或是線性不可分的。如下圖:

要解決非線性可分問題,需考慮使用多層功能神經元. 例如下圖中這個
簡單的兩層感知機就能解決異或問題。在圖中,輸出層與輸入層之間的一
層神經元,被稱為隱含層(hidden layer) ,隱含層和輸出層神經元都是擁
有激活函數的功能神經元.
能解決異或問題的兩層感知機
參考周志華老師西瓜書

二、Python 代碼實現
異或肯定是不能通過一條直線區分的,因此單層網絡無法實現異或,但兩層(包含一個隱藏層)就可以了。
在實際應用中,異或門(Exclusive-OR gate, XOR gate)是數字邏輯中實現邏輯異或的邏輯門,這一函數能實現模為2的加法。因此,異或門可以實現計算機中的二進制加法。
可以有多種方法實現Xor功能,本代碼采用的算法圖示如下

將上圖轉化為神經網絡層形式便於理解:

# ----------
#
# In this exercise, you will create a network of perceptrons that can represent
# the XOR function, using a network structure like those shown in the previous
# quizzes.
#
# You will need to do two things:
# First, create a network of perceptrons with the correct weights
# Second, define a procedure EvalNetwork() which takes in a list of inputs and
# outputs the value of this network.
#
# ----------
import numpy as np
class Perceptron:
"""
This class models an artificial neuron with step activation function.
"""
def __init__(self, weights = np.array([1]), threshold = 0):
"""
Initialize weights and threshold based on input arguments. Note that no
type-checking is being performed here for simplicity.
"""
self.weights = weights
self.threshold = threshold
def activate(self, values):
"""
Takes in @param values, a list of numbers equal to length of weights.
@return the output of a threshold perceptron with given inputs based on
perceptron weights and threshold.
"""
# First calculate the strength with which the perceptron fires
strength = np.dot(values,self.weights)
# Then return 0 or 1 depending on strength compared to threshold
return int(strength >= self.threshold)#this row changed by myself
# Part 1: Set up the perceptron network
Network = [
# input layer, declare input layer perceptrons here
[ Perceptron([1,0],1),Perceptron([1,1],2),Perceptron([0,1],1) ], \
# output node, declare output layer perceptron here
[ Perceptron([1, -2, 1], 1) ]
]
# Part 2: Define a procedure to compute the output of the network, given inputs
def EvalNetwork(inputValues, Network):
"""
Takes in @param inputValues, a list of input values, and @param Network
that specifies a perceptron network. @return the output of the Network for
the given set of inputs.
"""
# MY MAIN CODE HERE
# Be sure your output value is a single number
#Method1 :
return Network[1][0].activate([p.activate(inputValues) for p in Network[0]])
# p is an instance of Perceptron.
# inner brackets -->input layer
# Network[1][0] -->Perceptron([1, -2, 1], 1) -- Only one element
#Method2 :
# OutputValue = inputValues
# for layer in Network:
# OutputValue = map(lambda p:p.activate(OutputValue), layer)
# return OutputValue
## but warning:this method return a list ,not a single number
## to review Python Grammar?
def test():
"""
A few tests to make sure that the perceptron class performs as expected.
"""
print "0 XOR 0 = 0?:", EvalNetwork(np.array([0,0]), Network)
print "0 XOR 1 = 1?:", EvalNetwork(np.array([0,1]), Network)
print "1 XOR 0 = 1?:", EvalNetwork(np.array([1,0]), Network)
print "1 XOR 1 = 0?:", EvalNetwork(np.array([1,1]), Network)
if __name__ == "__main__":
test()
OUTPUT:
Running test()...
0 XOR 0 = 0?: 0
0 XOR 1 = 1?: 1
1 XOR 0 = 1?: 1
1 XOR 1 = 0?: 0
All done!
