首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >简单神经网络在Python中的实现

简单神经网络在Python中的实现
EN

Code Review用户
提问于 2018-08-30 18:58:19
回答 1查看 112关注 0票数 6

我用没有库的Python编写的一个简单的神经网络。我避免以矩阵形式实现它,因为我试图首先了解NN的工作方式。出于这个原因,我强烈支持易读性而不是效率。我试图保持我的代码可读性和仿生,任何风格的反馈将是特别感谢。

这种设计的一个奇怪之处是,它在每个训练示例的基础上进行反向传播,并使用动量来尝试和避免过度拟合特定的示例。另外,我意识到我从来没有给神经元增加过基值,如果没有它们,它似乎可以正常工作,但是如果有人对你为什么想要它们有更深入的理解的话,我会很好奇地知道这一点。

代码语言:javascript
复制
import math
import random

import data

def sigmoid(x):
    return 1 / (1 + math.exp(-x))

def sigmoid_prime(x):
    return x * (1.0 - x)

def loss(x,y):
    return sum([(a-b)**2 for (a,b) in zip(x,y)])

class Neuron():
    learning_rate = 0.015
    momentum_loss = 0.03

    def __init__(self, input_neurons):
        self.weights = [random.uniform(-1,1) for _ in range(input_neurons)]
        self.momentum = [0 for _ in range(input_neurons)]

    def forward(self, inputs):
        dot = sum([x*y for (x,y) in zip(inputs, self.weights)])
        self.output = sigmoid(dot) 
        return self.output

    def backpropagate(self, inputs, error):
        error_values = list()
        gradient = error * sigmoid_prime(self.output)
        for i, inp in enumerate(inputs):
            self.nudge_weight(i, gradient * inp)
            error_values.append(self.weights[i]  * gradient)
        return error_values

    def nudge_weight(self, weight, amount):
        change = amount * Neuron.learning_rate
        self.momentum[weight] += change
        self.momentum[weight] *= (1 - Neuron.momentum_loss)
        self.weights[weight] += change + self.momentum[weight] 

class Network():
    def __init__(self, topology):
        self.layers = list()
        for i in range(1,len(topology)):
            self.layers.append([Neuron(topology[i-1]) for _ in range(topology[i])])

    def forward(self, data):
        output = data
        for layer in self.layers:
            output = [neuron.forward(output) for neuron in layer]
        return output

    def backpropagate(self, data, output, target):
        error_values = [tval - output for (tval, output) in zip(target, output)]
        for i in range(len(self.layers)-1,0,-1): 
            layer_output = [neuron.output for neuron in self.layers[i-1]]
            error_values = self.backpropagate_layer(i, error_values, layer_output)
        self.backpropagate_layer(0, error_values, data)

    def backpropagate_layer(self, layer, error_values, inputs):
        next_errors = list()
        for neuron, error in zip(self.layers[layer], error_values):
            bp_error = neuron.backpropagate(inputs,error)
            if not next_errors:
                next_errors = bp_error
            else:
                next_errors = [a+b for a,b in zip(next_errors,bp_error)]
        return next_errors

项目的完整源代码(包括数据库和其他一些测试代码)可以在这里找到:https://github.com/RowanL3/Neural-Network

EN

回答 1

Code Review用户

发布于 2018-08-30 19:25:20

编写self.momentum = [0 for _ in range(input_neurons)]的一种更多的仿生方式是self.momentum = [0]*input_neurons

票数 4
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/202837

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档