【问题标题】:How to fix "invalid value", "divide by zero" and other calculation errors如何修复“无效值”、“除以零”等计算错误
【发布时间】:2020-12-15 14:55:09
【问题描述】:

我正在使用 numpy 来计算神经网络权重和节点,但几乎每次我遇到如下错误:

  • “RuntimeWarning:在日志中遇到除以零”
  • “乘法中遇到无效值”
  • “RuntimeWarning:exp 中遇到溢出”
  • ...

这在大多数情况下会导致值变为“nan”。

因为权重是随机启动的,所以我并不总是得到相同的错误。

当我构建小型神经网络(例如 2 个输入、4 个隐藏节点和 1 个输出)时,我根本没有遇到这些错误,但是如果我增加隐藏节点的数量,它会中断,导致 'nan' 成为值一切。

我已经搜索了解决方案,但没有帮助。我检查了值不是会导致“nan”的值,但我什么也没找到。

import numpy as np
import sys
import matplotlib.pyplot as plt

np.set_printoptions(threshold=sys.maxsize)


class NeuralNetwork:
    def __init__(self, inputs, outputs, epochs, lr):
        self.inputs = inputs
        self.outputs = outputs
        self.m = self.inputs.shape[0]
        self.n = self.inputs.shape[1]
        self.epochs = epochs
        self.lr = lr
        self.hidden1Size = 64
        self.hidden2Size = 64
        self.w1 = np.random.randn(self.n, self.hidden1Size)
        self.w2 = np.random.randn(self.hidden1Size, self.hidden2Size)
        self.w3 = np.random.randn(self.hidden2Size, self.outputs.shape[1])

    def sigmoid(self, n):
        return 1 / (1 - np.exp(-n))

    def sigmoidDerivative(self, n):
        return self.sigmoid(n) * (1 - self.sigmoid(n))

    def ReLU(self, n):
        return n * (n > 0)

    def ReLUDerivatie(self, n):
        return n > 0

    def crossEntropyLoss(self, y, h):
        return - (y * np.log(h) + (y - 1) * np.log(1 - h))

    def train(self):
        for i in range(self.epochs):
            X, a2, a3, h = self.feedForward()
            self.backProp(X, a2, a3, h)
            if i % 100 == 0:
                print('Cost at ', i, 'epochs: ', print(self.crossEntropyLoss(self.inputs, h)))

    def feedForward(self):
        X = self.inputs
        z2 = X.dot(self.w1)
        a2 = self.ReLU(z2)
        z3 = a2.dot(self.w2)
        a3 = self.ReLU(z3)
        z4 = a3.dot(self.w3)
        h = self.sigmoid(z4)

        return X, a2, a3, h

    def backProp(self, X, a2, a3, h):

        outputErrors = self.crossEntropyLoss(self.outputs, h)
        outputDeltas = outputErrors * self.sigmoidDerivative(h)

        hidden2Errors = outputDeltas.dot(self.w3.T)
        hidden2Deltas = hidden2Errors * self.ReLUDerivatie(a3)

        hidden1Errors = hidden2Deltas.dot(self.w2.T)
        hidden1Deltas = hidden1Errors * self.ReLUDerivatie(a2)

        self.w3 += self.lr * a3.T.dot(outputDeltas)
        self.w2 += self.lr * a2.T.dot(hidden2Deltas)
        self.w1 += self.lr * X.T.dot(hidden1Deltas)


NN = NeuralNetwork(np.array([[0, 0], [0, 1], [1, 0], [1, 1]]), np.array([[0], [0], [0], [1]]), 10000, 0.01)
NN.train()

这些值仅用于测试。我计划提供图像数据来区分数字,但据我所知,它不应该与这些数据中断。

【问题讨论】:

    标签: python numpy neural-network runtime-error nan


    【解决方案1】:

    因此,以下可能会呈现 nans/errors:

    # if n == 0, you'll have division by 0
    def sigmoid(self, n):
        return 1 / (1 - np.exp(-n))
    

    这里:

    # log function is not defined for negatives, thus for h < 0 or 1 - h < 0
    def crossEntropyLoss(self, y, h):
            return - (y * np.log(h) + (y - 1) * np.log(1 - h))
    

    正在进行很多转换,很难追踪值的来源,但这是我的第一个猜测。如果向量是平行的,dot 将呈现 0 - 也许这也可能对您有所帮助。

    所以,如果出现上述情况,我建议在这两个函数中打印回溯:https://docs.python.org/3/library/traceback.html#traceback.print_tb

    通过这种方式,您将能够找出调用的迭代/函数导致了这种无效条件。

    【讨论】:

      猜你喜欢
      • 2015-03-16
      • 2011-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-13
      相关资源
      最近更新 更多