我有两个输入和一个输出的简单神经网络,没有隐藏层。即[input1] [weight1 weight2] = z [input2]
输出= Sigmoid(z)
权重似乎没有达到最佳值。据我所知,我已经检查了梯度,并且可以看到权重根据成本函数的导数而上升或下降,但是网络并没有朝着最优值发展。
这里是代码:
import numpy as np
import random as r
import sys
def sigmoid(ip, derivate=False):
if derivate:
return ip*(1-ip)
return 1.0/(1+np.exp(-1*ip))
class NeuralNet:
global sigmoid
def __init__(self):
self.inputLayers = 2
self.outputLayer = 1
def setup(self):
self.i = np.array([r.random(), r.random()], dtype=float).reshape(2,)
self.w = np.array([r.random(), r.random()], dtype=float).reshape(2,)
def forward_propogate(self):
self.z = self.w*self.i
self.o = sigmoid(sum(self.z))
def optimize_cost(self, desired):
i=0
current_cost = pow(desired - self.o, 2)
for weight in self.w:
dpdw = -1 * (desired-self.o) * (sigmoid(self.o, derivate=True)) * self.i[i]
print(dpdw)
self.w[i] = self.w[i] + 500*dpdw
i+=1
self.forward_propogate()
def train(self, ip, op):
self.i = np.array(ip).reshape(2,)
self.forward_propogate()
print("before:{}".format(self.o))
self.optimize_cost(op[0])
# print(self.i,self.w)
n = NeuralNet()
n.setup()
# while sys.stdin.read(1):
while True:
a = r.random()
b = r.random()
if a>0.5 and b>0.5:
c = 0.9
else:
c = 0.1
print(c)
n.train([a,b],[c])
print(n.i, n.w)
print("after: {}".format(n.o))
我已经阅读了此https://towardsdatascience.com/emulating-logical-gates-with-a-neural-network-75c229ec4cc9,并且还说需要更深的(具有(多个)隐藏层的)网络才能获得良好的训练结果,提到的原因是:]]
有关。平面(或非深层/无隐藏层)神经网络无法执行简单的乘法cf https://stats.stackexchange.com/questions/217703/can-deep-neural-network-approximate-multiplication-function-without-normalizatio培训与学习
现在我们已经表明该神经网络是可能的,现在剩下的问题是,有可能训练。我们可以期望如果在定义之后,我们简单地输入从上图绘制的数据正确的层,神经元数量和激活功能,网络将以这种方式训练吗?
不,不总是,甚至不经常。问题,就像许多神经网络是优化之一。在训练这个网络时,它将即使是近乎完美的解决方案,也常常陷入局部最小值存在。这是您的优化算法可能发挥很大作用的地方角色,这是Tensorflow Playground所不允许的您进行更改,并且可能是将来发布的主题。
[...]
通过手动输入权重建立此网络后,为什么不尝试从头开始训练此网络的权重而不是手动构建它。我已经做到了经过多次试验,但我相信它对播种非常敏感并且通常以局部最小值结束。如果您找到可靠的方法使用这些功能和网络结构训练该网络请在评论中提出。
[尝试仅使用此数量的神经元和层。在本文中,我表明可以做到这一点只有这么多的神经元。如果您引入更多节点,那么您将当然有一些多余的神经元。 尽管,还有更多神经元/神经元,我在训练好模型方面运气更好一致。
可能是问题与神经网络的乘法问题
UPDATE(comment)
老实说,我不确定MSE错误函数(据我所知,实现也不准确,np.mean()
缺少np.mean(pow(y-y_pred,2)
),因为它在分类问题上不好,请参见https://towardsdatascience.com/why-using-mean-squared-error-mse-cost-function-for-binary-classification-is-a-bad-idea-933089e90df7和https://medium.com/autonomous-agents/how-to-teach-logic-to-your-neuralnetworks-116215c71a49
均方误差损失
均方误差或MSE损失是用于回归[非分类]问题的默认损失。
训练两个标签或类(True
,False
)是一个分类问题,而不是回归问题。
但是我认为主要系统性问题
(除了实现中的错误)是网络不够深。如文章https://towardsdatascience.com/emulating-logical-gates-with-a-neural-network-75c229ec4cc9所述,您可以播种初始权重的组合以避免局部最小值,但这也不能解决基本问题(网络不够深入,错误的错误函数(MSE),实现中的错误)。在https://towardsdatascience.com/lets-code-a-neural-network-in-plain-numpy-ae7e74410795中是用于分类的神经网络的一个小数实现,其中包括二进制交叉熵
误差函数的实现,也许将此与您的代码进行比较。回答我自己的问题。我所需要的只是一个BIAS。如果没有BIAS,则S形不能偏离0。
这里是一个Sigmoid,偏差为2。现在Sigmoid(0)=接近0.1