我想实现一个多层感知器(mlp)来解决异或问题。因为我不是一个伟大的科学家,所以很长一段时间以来,我一直在为这个项目绞尽脑汁,我希望能够理解这个项目的每一行。
我将从以下问题开始:
有没有调试神经网络的具体方法?(例如导致预期解决方案的预定义已知权重)
下面的反向传播算法(伪代码)正确吗?
这种算法应该有偏差吗?如果不是,那么偏倚是解决异或问题所必需的吗?如果是的话,偏差应该是每个神经元1个,每层1个还是每个网络1个?
我的python实现正确吗如果不是,是关于反向传播,正向传播,没有偏倚还是其他的?
每一个回应都是非常受欢迎的。这不是“家庭作业”,但如果你很害怕,我会很高兴只有好的提示我仍然没有正确地使用numpy,因为我是一个开发人员,而不是一个科学家,有时会遇到矩阵方程的问题(我目前正在研究)因此,我很难很好地理解我发现的不同实现。
编辑:算法现在运行良好,我将重点介绍伪代码/python实现中存在的不同问题:
理论:
在重量调整时伪代码是错误的(我编辑了代码,用fix标记错误的行)。我在应该使用输入值的地方使用了输出层输出
无偏压、只有一个隐含层的异或问题可以有效地解决。有趣的是,它只对4个或更多的神经元起作用,而对3个神经元不起作用但是,在基准测试之后,添加偏差可以大大加快最佳收敛的时间(5倍或更多)
python实现:
权重是在0和1之间随机初始化的,而不是在-1和1之间,它不能这样工作。
最后,this resource对理解“神经元魔法”有很大帮助。它没有帮助我调试反向传播,但它现在证明,如果没有更多的理论知识,我永远无法使它工作如果,作为我,你更像一个开发人员而不是一个科学家,我强烈建议你去看看。
根据维吉尼·马蒂维特的《开发人员的人工智能》一书,这里是反向传播算法的伪代码(这是一本法国书,对不起,坏的交易):

While stop criteria is not achieved:
    Initialize d(i)

    For each example:
        Compute output value s(i)                          #1

        For each output neuron weight:                     #2
            d(i) = s(i) * (1 - s(i)) * (y(i) - s(i))
        EndFor

        For each hidden neuron weight:
            sum = 0
            For each link towards output neuron k:
                sum += d(k) * w(i->k)
            EndFor
            d(i) = o(i) * (1 - o(i)) * sum
        EndFor

        For each weight of the network:
            If link towards output neuron:
                w(i) += rate * d(i) * o(i)
            Else
                w(i) += rate * d(i) * s(i) # WRONG: s(i) should be input(i)
            EndIf
        EndFor
    EndFor
EndWhile

在上面,d(x)是delta,o(x)是隐藏层输出,s(x)是输出层输出,y(x)是预期输出,w(x)是网络权重。
我知道第1行是正向传播,第2行(包括)之后的行是反向传播因此,正确的算法可以写成:
While stop criteria is not achieved:
    Initialize d(i)

    For each example:
        output = Forward propagation with example inputs                  #1
        Backpropagation of the error between output and expected output   #2
    EndFor
EndWhile

我的问题是,该算法似乎与反向传播算法成圆圈,并且权重发生变化,例如,下面是隐藏层的输出:
[Epoch 0, inputs (1.0, 1.0)]: hidden outputs: None
[Epoch 0, inputs (0.0, 0.0)]: hidden outputs: [ 0.7755638   0.64556638  0.68163599]
[Epoch 0, inputs (1.0, 0.0)]: hidden outputs: [ 0.5  0.5  0.5]
[Epoch 0, inputs (0.0, 1.0)]: hidden outputs: [ 0.60747218  0.58975313  0.55246625]
[Epoch 1, inputs (1.0, 1.0)]: hidden outputs: [ 0.68911554  0.55079694  0.62718831]
[Epoch 1, inputs (1.0, 0.0)]: hidden outputs: [ 0.77449528  0.64107552  0.67770194]
[Epoch 1, inputs (0.0, 0.0)]: hidden outputs: [ 0.60728756  0.58957687  0.55230354]
[Epoch 1, inputs (0.0, 1.0)]: hidden outputs: [ 0.5  0.5  0.5]
[Epoch 2, inputs (0.0, 0.0)]: hidden outputs: [ 0.68877278  0.54872848  0.6254074 ]
[Epoch 2, inputs (1.0, 0.0)]: hidden outputs: [ 0.5  0.5  0.5]
[Epoch 2, inputs (1.0, 1.0)]: hidden outputs: [ 0.60700878  0.58812487  0.5509695 ]
[Epoch 2, inputs (0.0, 1.0)]: hidden outputs: [ 0.77344667  0.63591436  0.67311723]
[Epoch 3, inputs (0.0, 0.0)]: hidden outputs: [ 0.68856723  0.54708942  0.62400827]
[Epoch 3, inputs (1.0, 0.0)]: hidden outputs: [ 0.5  0.5  0.5]

按随机顺序排列示例不会改变任何内容。此外,我尝试了所有的学习率(0.05到0.95),结果都是一样的,所以我认为这并不是因为收敛性差以下是我的python实现:
def sigmoid(x):
    return 1 / (1 + np.exp(-x))

def dsigmoid(y):
    return y * (1.0 - y)

class NeuralNetwork:

    def __init__(self, nb_inputs, nb_hidden, nb_outputs, learning_rate):
        self.nb_inputs = nb_inputs
        self.nb_hidden = nb_hidden
        self.nb_outputs = nb_outputs
        self.learning_rate = learning_rate

        self.output_deltas = None
        self.output_weights = np.random.random((nb_outputs, nb_hidden)) # WRONG: should be between -1 and 1, not 0 and 1
        self.outputs = None
        self.hidden_deltas = None
        self.hidden_weights = np.random.random((nb_hidden, nb_inputs)) # WRONG: should be between -1 and 1, not 0 and 1
        self.hidden_outputs = None

    def forward_propagation(self, inputs):
        self.hidden_outputs = np.zeros((self.nb_hidden,))
        self.outputs = np.zeros((self.nb_outputs,))

        # get outputs for hidden layer
        for i in range(self.nb_hidden):
            aggregated = sum([inputs[j] * self.hidden_weights[i][j] for j in range(self.nb_inputs)])
            self.hidden_outputs[i] = sigmoid(aggregated)

        # get inputs for output layer
        for i in range(self.nb_outputs):
            aggregated = sum([self.hidden_outputs[j] * self.output_weights[i][j] for j in range(self.nb_hidden)])
            self.outputs[i] = sigmoid(aggregated)

    def backpropagation(self, expected_outputs):

        # find deltas for output layer
        for i in range(self.nb_outputs):
            for j in range(self.nb_hidden):
                self.output_deltas[i][j] = dsigmoid(self.outputs[i]) * (expected_outputs[i] - self.outputs[i])

        # find deltas for hidden layer
        for i in range(self.nb_hidden):
            for j in range(self.nb_inputs):
                total = 0.0
                for k in range(self.nb_outputs):
                    total += self.output_deltas[k][i] * self.output_weights[k][i]
                self.hidden_deltas[i][j] = dsigmoid(self.hidden_outputs[i]) * total

        # change weights for output layer
        for i in range(self.nb_outputs):
            for j in range(self.nb_hidden):
                self.output_weights[i][j] += self.learning_rate * self.output_deltas[i][j] * self.outputs[i] # WRONG: should be self.hidden_outputs[j]

        # change weights for inputs layer
        for i in range(self.nb_hidden):
            for j in range(self.nb_inputs):
                self.hidden_weights[i][j] += self.learning_rate * self.hidden_deltas[i][j] * self.hidden_outputs[i] # WRONG: should be inputs[j]

    def train(self, data, nb_iterations):
        for i in range(nb_iterations):
            # Init deltas
            self.output_deltas = np.zeros((self.nb_outputs, self.nb_hidden), dtype=np.float64)
            self.hidden_deltas = np.zeros((self.nb_hidden, self.nb_inputs), dtype=np.float64)

            # Train on examples with different orders
            for inputs, expected_output in sorted(data.items(), key=lambda x: random.random()):
                expected_outputs = np.array([expected_output])

                self.forward_propagation(inputs)
                self.backpropagation(expected_outputs) # WRONG: need inputs: backpropagation(inputs, expected_outputs)

    def predict(self, inputs):
        self.forward_propagation(inputs)
        return self.outputs

最佳答案

很长一段时间以来,我一直在为它伤脑筋,因为我不是一个伟大的人
科学家,我想知道
程序。
你得到我的答案了。继续这样下去,你会发疯的!
免责声明:部分回答我可能会随着时间的推移而改进。
有没有调试神经网络的具体方法?(例如
导致预期解决方案的预定义已知权重)
一般情况下是不可能的。由于权重的数量,在大多数实际情况下几乎是不可能的。您仍然可以尝试监视神经元活动(代码中的aggregated变量),例如连续两次发送类似的网络输入,看它是否学习,即它越来越接近正确的值。
下面的反向传播算法(伪代码)正确吗?
会去查的。是你的吗?
这种算法应该有偏差吗?如果没有,是否有必要
解决异或问题如果是,偏差应该是
神经元,每层一个还是每个网络一个?
通常每个神经元有一个biais。如果你忽略了它就没问题了。
我的python实现正确吗如果不是,是关于
反向传播、正向传播、无偏压或
其他事?
会检查的没有偏见是可以的。
作为一个脚注,我推荐这本在线“书”:http://neuralnetworksanddeeplearning.com/chap1.html有相当多的数学,不要把时间花在数学上,试着得到概念。我觉得这很有教益。
希望有帮助
pltrdy

关于python - 反向传播算法卡在了多层感知器中,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42394761/

10-10 18:21