我正在使用numpy来计算神经网络的权重和节点,但是几乎每次我遇到类似这样的错误时:
大多数情况下导致值变为“ 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()
这些值仅供测试。我打算提供图像数据以区分数字,但据我所知,不应该破坏这些数字。
答案 0 :(得分:0)
因此,以下操作可能会导致nan /错误:
# 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
这样,您将能够找出导致这种无效情况的调用的迭代/函数。