(1)本文的实现为仅有一个隐层的
输入层-隐层-输出层
的三层简单神经网络(2)因为模型较为简单,参数较少,权值矩阵的更新我们采用的数值分析的方式,而不是反向传播。
import numpy as np
import operator
import random
import matplotlib.pyplot as plt
# S 型函数
def sigmoid(z):
return 1./(1.+np.exp(-z))
# 定义 list 的内积运算
def inner_prod(w, x):
return reduce(operator.add, map(operator.mul, w, x))
# 单个神经元
def neuron(w, x):
return sigmoid(w[0] + inner_prod(w[1:], x))
# 判别函数
def h(ws, x):
hidden1 = neuron(ws[:3], x)
hidden2 = neuron(ws[3:6], x)
return neuron(ws[6:], [hidden1, hidden2])
INPUTS = [[0, 0], [0, 1], [1, 0], [1, 1]]
OUTPUTS = [0, 1, 1, 0]
# 代价函数(全部样本)
def cost(ws):
return 1./2*sum((h(ws, x)-y)**2 for x, y in zip(INPUTS, OUTPUTS))
# 数值分析的方式计算偏导
def partial(f, k, ws):
ws_plus, ws_minus = ws[:], ws[:]
epsilon = 0.01
ws_plus[k] += epsilon
ws_minus[k] -= epsilon
return (f(ws_plus)-f(ws_minus))/2/epsilon
# 梯度下降求解最优化(最小化)问题
def gradient_descent(cost, eta, n):
costs = []
ws = [random.random()*2-1 for _ in xrange(9)]
for iter in xrange(n):
c = cost(ws)
print 'iter: ', iter, ', cost: ', c
costs.append(c)
grad = [partial(cost, k, ws) for k in xrange(9)]
ws = [ws[k]-eta*grad[k] for k in xrange(9)]
return ws, costs
def main():
ws, costs = gradient_descent(cost, 0.1, 10000)
print '\nFinal cost:', cost(ws)
print '\nFinal weights:', ws
print '\nPrediction: ', [h(ws, x) for x in INPUTS]
plt.plot(np.array(costs))
plt.xlabel('iteration')
plt.ylabel('cost')
plt.show()
if __name__ == '__main__':
main()
注:因为数据量较小,所以会对权值矩阵的初始化以及学习率 η 的设置较为敏感,如果学习速率较低,可适当增加学习率。