【问题标题】:Simple neural network "calibration" (python)简单的神经网络“校准”(python)
【发布时间】:2018-04-10 15:25:45
【问题描述】:

我开始使用神经网络和这类东西,我了解perceptron 的工作原理以及feed-forward and backpropagation 机制背后的逻辑,我现在正在尝试编写一个具有 3 个神经元的简单多层网络( 2 在隐藏层和 1 作为输出)应该足以执行xor operation

我以这种方式在 Python 中实现它(现在使用 v3.6.1):

import numpy as np

class Neuron():

    def __init__(self, n, w = None, b = None):
        #np.random.seed(46144492)
        #np.random.seed(23)
        self.weights = 2 * np.random.random((n)) - 1 if w == None else np.array(w)
        self.bias = 2 * np.random.random() - 1 if b == None else b
        self.learning_rate = 0.1
        self.weights_error = []
        for i in range(n):
            self.weights_error.append(0)
        self.bias_error = 0

    def learning_factor(self, output):
        return output * (1 - output)

    def fire(self, x):
        return 1 / (1 + np.exp(-x))

    def __call__(self, inputs):
        weighted = []
        for i in range(len(inputs)):
            weighted.append(inputs[i] * self.weights[i])
        weighted = np.array(weighted)
        return self.fire(weighted.sum() + self.bias)

    def adjust(self, n_weights):
        for i in range(n_weights):
            self.weights[i] -= self.weights_error[i]
        self.bias -= self.bias_error

class HiddenNeuron(Neuron):

    def calc_error(self, inputs, output, next_layer, number_in_layer):
        error = 0
        for n in range(len(next_layer)):
            error += next_layer[n].delta * next_layer[n].weights[number_in_layer - 1]
        derivative = self.learning_factor(output)
        self.delta = error * derivative
        self.weights_error = []
        for i in range(len(inputs)):
            self.weights_error.append(self.delta * inputs[i] * self.learning_rate)
        self.bias_error = self.delta * self.learning_rate


class OutputNeuron(Neuron):

    def calc_error(self, inputs, output, expected):
        error = output - expected
        derivative = self.learning_factor(output)
        self.delta = error * derivative
        self.weights_error = []
        for i in range(len(inputs)):
            self.weights_error.append(self.delta * inputs[i] * self.learning_rate)
        self.bias_error = self.delta * self.learning_rate

# Network
n1, n2 = HiddenNeuron(2), HiddenNeuron(2)
n3 = OutputNeuron(2)
# Training data
training_set_in = [[0, 0], [0, 1], [1, 0], [1, 1]]
training_set_out = [0, 1, 1, 0]
# Training cycles
for i in range(10000):
    for i in range(len(training_set_in)):
        # Feed-forward
        n1_out = n1(training_set_in[i])
        n2_out = n2(training_set_in[i])
        n3_in = [n1_out, n2_out]
        n3_out = n3(n3_in)
        # Backpropagation
        n3.calc_error(n3_in, n3_out, training_set_out[i])
        n2.calc_error(training_set_in[i], n2_out, [n3], 2)
        n1.calc_error(training_set_in[i], n1_out, [n3], 1)
        n1.adjust(2)
        n2.adjust(2)
        n3.adjust(2)
# "New" cases (test)
for new in [[0, 0], [0, 1], [1, 0], [1, 1]]:
    print(n3([n1(new), n2(new)]))

如你所见,我使用 sigmoid 函数作为激活函数,但我还没有实现动量(我还需要了解它是如何工作的)。

在大多数情况下,网络都能正常工作。但我发现在某些情况下它会输出一些奇怪的值(例如,参见我在 Neuron 类构造函数中注释的两个随机种子)。如果我增加 Neuron.learning_rate(例如将其设置为 10),这两种情况就解决了,但仍然出现了一些其他异常(找不到这些的种子,对不起......但它们非常频繁,只需运行代码 10 或 20 次,您就会看到一些)。

问题是:为什么会这样?我的网络太“小”/简单吗?我认为 3 个神经元就足够了。还是只是“校准”的问题(不知道这个怎么称呼,我的意思是调整学习率因子和动量的过程,这里没有)?还是我什至犯了任何错误?实在想不通。

编辑:我正在用所有可能的情况训练网络,然后用相同的情况进行尝试,以验证它是否正常工作。

【问题讨论】:

    标签: python python-3.x neural-network perceptron calibration


    【解决方案1】:

    我认为这没关系,因为神经网络的性能取决于其初始状态,即权重和偏差。在您的情况下,权重和偏差开始是随机的,因此取决于种子。甚至还有专门的techniques1 来减少这种影响,比如weight normalisation(也可以google这个,有一些关于这个主题的有趣论文)。


    1. 链接取自http://neuralnetworksanddeeplearning.com/chap5.html

    【讨论】:

    • 感谢您的快速回复:)。我会调查的
    猜你喜欢
    • 2018-10-01
    • 2022-01-08
    • 1970-01-01
    • 1970-01-01
    • 2016-08-18
    • 2011-06-10
    • 2016-08-17
    • 2019-01-23
    • 1970-01-01
    相关资源
    最近更新 更多