Simple Neural Network [Preview]

来源:互联网 发布:淘宝上七天无理由退货 编辑:程序博客网 时间:2024/04/27 18:56
import mathimport randomimport stringrandom.seed(0)# 生成区间[a, b)内的随机数def rand(a, b):    return (b-a)*random.random() + a# 生成大小 I*J 的矩阵,默认零矩阵 (当然,亦可用 NumPy 提速)def makeMatrix(I, J, fill=0.0):    m = []    for i in range(I):        m.append([fill]*J)    return m# 函数 sigmoid,这里采用 tanh,因为看起来要比标准的 1/(1+e^-x) 漂亮些def sigmoid(x):    return math.tanh(x)# 函数 sigmoid 的派生函数, 为了得到输出 (即:y)def dsigmoid(y):    return 1.0 - y**2class NN:    ''' 三层反向传播神经网络 '''    def __init__(self, inputLayer, hiddenLayer, outputLayer):        # 输入层、隐藏层、输出层的节点(数)        self.inputLayer = inputLayer + 1 # 增加一个偏差节点        self.hiddenLayer = hiddenLayer        self.outputLayer = outputLayer        # 激活神经网络的所有节点(向量)        self.inputNodes = [1.0]*self.inputLayer        self.hiddenNodes = [1.0]*self.hiddenLayer        self.outputNodes = [1.0]*self.outputLayer        # 建立权重(矩阵)        self.weightInput = makeMatrix(self.inputLayer, self.hiddenLayer)        self.weightOutput = makeMatrix(self.hiddenLayer, self.outputLayer)        # 设为随机值        for i in range(self.inputLayer):            for j in range(self.hiddenLayer):                self.weightInput[i][j] = rand(-0.2, 0.2)        for j in range(self.hiddenLayer):            for k in range(self.outputLayer):                self.weightOutput[j][k] = rand(-0.2, 0.2)        # 最后建立动量因子(矩阵)        self.ci = makeMatrix(self.inputLayer, self.hiddenLayer)        self.co = makeMatrix(self.hiddenLayer, self.outputLayer)    def update(self, inputs):        if len(inputs) != self.inputLayer-1:            raise ValueError('与输入层节点数不符!')        # 激活输入层        for i in range(self.inputLayer-1):            self.inputNodes[i] = sigmoid(inputs[i]) #High efficiency            #self.inputNodes[i] = inputs[i] #Low efficiency        # 激活隐藏层        for j in range(self.hiddenLayer):            sum = 0.0            for i in range(self.inputLayer):                sum = sum + self.inputNodes[i] * self.weightInput[i][j]            self.hiddenNodes[j] = sigmoid(sum)        # 激活输出层        for k in range(self.outputLayer):            sum = 0.0            for j in range(self.hiddenLayer):                sum = sum + self.hiddenNodes[j] * self.weightOutput[j][k]            self.outputNodes[k] = sigmoid(sum)        return self.outputNodes[:]    def backPropagate(self, targets, N, M):        ''' 反向传播 '''        if len(targets) != self.outputLayer:            raise ValueError('与输出层节点数不符!')        # 计算输出层的误差        output_deltas = [0.0] * self.outputLayer        for k in range(self.outputLayer):            error = targets[k]-self.outputNodes[k]            output_deltas[k] = dsigmoid(self.outputNodes[k]) * error        # 计算隐藏层的误差        hidden_deltas = [0.0] * self.hiddenLayer        for j in range(self.hiddenLayer):            error = 0.0            for k in range(self.outputLayer):                error = error + output_deltas[k]*self.weightOutput[j][k]            hidden_deltas[j] = dsigmoid(self.hiddenNodes[j]) * error        # 更新输出层权重        for j in range(self.hiddenLayer):            for k in range(self.outputLayer):                change = output_deltas[k]*self.hiddenNodes[j]                self.weightOutput[j][k] = self.weightOutput[j][k] + N*change + M*self.co[j][k]                self.co[j][k] = change                #print(N*change, M*self.co[j][k])        # 更新输入层权重        for i in range(self.inputLayer):            for j in range(self.hiddenLayer):                change = hidden_deltas[j]*self.inputNodes[i]                self.weightInput[i][j] = self.weightInput[i][j] + N*change + M*self.ci[i][j]                self.ci[i][j] = change        # 计算误差        error = 0.0        for k in range(len(targets)):            error = error + 0.5*(targets[k]-self.outputNodes[k])**2        return error    def test(self, patterns):        for p in patterns:            print(p[0], '->', self.update(p[0]))    def weights(self):        print('输入层权重:')        for i in range(self.inputLayer):            print(self.weightInput[i])        print()        print('输出层权重:')        for j in range(self.hiddenLayer):            print(self.weightOutput[j])    def train(self, patterns, iterations=1000, N=0.5, M=0.1):        # N: 学习速率(learning rate)        # M: 动量因子(momentum factor)        for i in range(iterations):            error = 0.0            for p in patterns:                inputs = p[0]                targets = p[1]                self.update(inputs)                error = error + self.backPropagate(targets, N, M)            if i % 100 == 0:                print('误差 %-.5f' % error)def demo():    # 一个演示:教神经网络学习逻辑异或(XOR)------------可以换成你自己的数据试试    pat = [        [[0,0], [0]],        [[0,1], [1]],        [[1,0], [1]],        [[1,1], [0]]    ]    # 创建一个神经网络:输入层有两个节点、隐藏层有两个节点、输出层有一个节点    n = NN(2, 2, 1)    # 用一些模式训练它    n.train(pat)    # 测试训练的成果(不要吃惊哦)    n.test(pat)    # 看看训练好的权重(当然可以考虑把训练好的权重持久化)    #n.weights()if __name__ == '__main__':    demo()
0 0
原创粉丝点击