python - 从头开始构建的简单神经网络不是学习

标签 python machine-learning neural-network deep-learning

我实现了一个始终只有一个隐藏层的神经网络类,不使用任何库——甚至不使用 numpy。一切都按照我理解的方式去做了,但是根本不是在学习,损失实际上是不断增加的,我在网上看了很多例子也找不到哪里错了。

这是我的 MLP 类及其尝试学习 XOR 函数的演示:

import random
from math import exp


class MLP:

    def __init__(self, numInputs, numHidden, numOutputs):
        # MLP architecture sizes
        self.numInputs = numInputs
        self.numHidden = numHidden
        self.numOutputs = numOutputs

        # MLP weights
        self.IH_weights = [[random.random() for i in range(numHidden)] for j in range(numInputs)]
        self.HO_weights = [[random.random() for i in range(numOutputs)] for j in range(numHidden)]

        # Gradients corresponding to weight matrices computed during backprop
        self.IH_gradients = [[0 for i in range(numHidden)] for j in range(numInputs)]
        self.HO_gradients = [[0 for i in range(numOutputs)] for j in range(numHidden)]

        # Input, hidden and output neuron values
        self.I = None
        self.H = [0 for i in range(numHidden)]
        self.O = [0 for i in range(numOutputs)]

        self.H_deltas = [0 for i in range(numHidden)]
        self.O_deltas = [0 for i in range(numOutputs)]

    # Sigmoid
    def activation(self, x):
        return 1 / (1 + exp(-x))

    # Derivative of Sigmoid
    def activationDerivative(self, x):
        return x * (1 - x)

    # Squared Error
    def calculateError(self, prediction, label):
        return (prediction - label) ** 2

    def forward(self, input):
        self.I = input
        for i in range(self.numHidden):
            for j in range(self.numInputs):
                self.H[i] += self.I[j] * self.IH_weights[j][i]
            self.H[i] = self.activation(self.H[i])

        for i in range(self.numOutputs):
            for j in range(self.numHidden):
                self.O[i] += self.activation(self.H[j] * self.HO_weights[j][i])
            self.O[i] = self.activation(self.O[i])

        return self.O

    def backwards(self, label):
        if label != list:
            label = [label]

        error = 0
        for i in range(self.numOutputs):
            neuronError = self.calculateError(self.O[i], label[i])
            error += neuronError
            self.O_deltas[i] = neuronError * self.activationDerivative(self.O[i])
            for j in range(self.numHidden):
                self.HO_gradients[j][i] += self.O_deltas[i] * self.H[j]

        for i in range(self.numHidden):
            neuronError = 0
            for j in range(self.numOutputs):
                neuronError += self.HO_weights[i][j] * self.O_deltas[j]
            self.H_deltas[i] = neuronError * self.activationDerivative(self.H[i])
            for j in range(self.numInputs):
                self.IH_gradients[j][i] += self.H_deltas[i] * self.I[j]

        return error

    def updateWeights(self, learningRate):
        for i in range(self.numInputs):
            for j in range(self.numHidden):
                self.IH_weights[i][j] += learningRate * self.IH_gradients[i][j]

        for i in range(self.numHidden):
            for j in range(self.numOutputs):
                self.HO_weights[i][j] += learningRate * self.HO_gradients[i][j]

        self.IH_gradients = [[0 for i in range(self.numHidden)] for j in range(self.numInputs)]
        self.HO_gradients = [[0 for i in range(self.numOutputs)] for j in range(self.numHidden)]


data = [
    [[0, 0], 0],
    [[0, 1], 1],
    [[1, 0], 1],
    [[1, 1], 0]
]

mlp = MLP(2, 5, 1)

for epoch in range(100):
    epochError = 0
    for i in range(len(data)):
        mlp.forward(data[i][0])
        epochError += mlp.backwards(data[i][1])
    print(epochError / len(data))
    mlp.updateWeights(0.001)

最佳答案

如果我正确理解了你的实现,那么我认为你的问题在于向后函数中权重更新的计算,更新应该是误差(不是误差平方)乘以 sigmoid 导数,所以我会采取查看/重做计算。

关于python - 从头开始构建的简单神经网络不是学习,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49741328/

相关文章:

python - 使用 XlsxWriter 在 pandas 中导出到 'xlsx' 时应用样式

python - 如何在Python中迭代列表列表时标记编码

machine-learning - 为范围内存在的输入值选择机器学习算法

matlab - 如何在 MATLAB 中高效实现 Maxpooling?

python - 神经网络没有经过训练,交叉熵保持不变

python - 如何使用元类添加方法

python - 找到我自己实现的 kNN 算法中的训练和测试错误

python - 为什么 Python 的 itertools.permutations 包含重复项? (当原始列表有重复时)

python - key 错误 : 'SPARK_HOME' in pyspark

python - PyTorch:创建非完全连接层/连接隐藏层的输出