我实现了以下神经网络来解决Python中的异或问题。我的神经网络由2个神经元的输入层、1个2个神经元的隐藏层和1个神经元的输出层组成。我使用Sigmoid函数作为隐藏层的激活函数,使用线性(恒等式)函数作为输出层的激活函数:
import numpy as np
def sigmoid(z):
return 1/(1+np.exp(-z))
def s_prime(z):
return np.multiply(sigmoid(z), sigmoid(1.0-z))
def init_weights(layers, epsilon):
weights = []
for i in range(len(layers)-1):
w = np.random.rand(layers[i+1], layers[i]+1)
w = w * 2*epsilon - epsilon
weights.append(np.mat(w))
return weights
def fit(X, Y, w, predict=False, x=None):
w_grad = ([np.mat(np.zeros(np.shape(w[i])))
for i in range(len(w))])
for i in range(len(X)):
x = x if predict else X[0]
y = Y[0,i]
# forward propagate
a = x
a_s = []
for j in range(len(w)):
a = np.mat(np.append(1, a)).T
a_s.append(a)
z = w[j] * a
a = sigmoid(z)
if predict: return a
# backpropagate
delta = a - y.T
w_grad[-1] += delta * a_s[-1].T
for j in reversed(range(1, len(w))):
delta = np.multiply(w[j].T*delta, s_prime(a_s[j]))
w_grad[j-1] += (delta[1:] * a_s[j-1].T)
return [w_grad[i]/len(X) for i in range(len(w))]
def predict(x):
return fit(X, Y, w, True, x)
####
X = np.mat([[0,0],
[0,1],
[1,0],
[1,1]])
Y = np.mat([0,1,1,0])
layers = [2,2,1]
epochs = 10000
alpha = 0.5
w = init_weights(layers, 1)
for i in range(epochs):
w_grad = fit(X, Y, w)
print w_grad
for j in range(len(w)):
w[j] -= alpha * w_grad[j]
for i in range(len(X)):
x = X[i]
guess = predict(x)
print x, ":", guess
反向传播似乎都是正确的;我想到的唯一问题是我在实现偏差单位时遇到的一些问题。无论哪种方式,每次运行代码时,每个输入的所有谓词都会收敛到大约0.5。我仔细检查了代码,似乎找不到问题所在。有人能指出我的实现有什么问题吗?非常感谢您的反馈。
如果出于任何原因,这可能会有所帮助,下面是我得到的输出:
[[0 0]] : [[ 0.5]]
[[0 1]] : [[ 0.49483673]]
[[1 0]] : [[ 0.52006739]]
[[1 1]] : [[ 0.51610963]]
您对正向和反向传播的实现或多或少是正确的。但是,您出错的地方很简单。第一个小错误是查看您的fit
函数内部-特别是for
循环中的第一条语句:
x = x if predict else X[0]
您是说如果您不进行预测(即执行训练),则在随机梯度下降的每次迭代期间选择的输入示例必须始终是第一个示例,即[0 0]
(即X[0]
)。这就是为什么您的所有预测都获得0.5的原因,因为您只使用第一个输入进行训练。您需要更改此项,以便它读取正确的示例,即examplei
:
x = x if predict else X[i]
最后需要进行的更改是您的s\U prime函数。sigmoid函数的导数实际上就是这里的导数:
def s_prime(z):
return np.multiply(sigmoid(z), sigmoid(1.0-z))
当您计算前向传播时,您已经计算了a_s
中每个神经元的输出激活,因此当您计算这些神经元的局部导数时,您将输出激活直接提供给s_prime
,因此您无需再次计算这些的sigmoid。
因此:
def s_prime(z):
return np.multiply(z, 1.0-z)
一旦我做了这两个更改,我们现在就可以得到以下输出:
[[0 0]] : [[ 0.00239857]]
[[0 1]] : [[ 0.99816778]]
[[1 0]] : [[ 0.99816596]]
[[1 1]] : [[ 0.0021052]]
您可以看到,这或多或少与异或门的预期输出一致。最后一件我可以推荐的事情是,考虑到您当前的代码结构,10000次迭代在计算上太长了。我注意到,通过上述更正,我们能够在更少的迭代中达到预期的输出。我已经将迭代次数减少到1000次,并且将学习率提高到了0.75。改变我们现在得到的两件事:
[[0 0]] : [[ 0.03029435]]
[[0 1]] : [[ 0.95397528]]
[[1 0]] : [[ 0.95371525]]
[[1 1]] : [[ 0.04796917]]
在过去的两周里,我读了很多关于NN的文章,我想我在网上看到了几乎所有的“XOR”方法教程。但是,我无法使工作成为我自己的工作。我从一个简单的“OR”神经元方法开始。给出良好的结果。我认为我的问题是反向传播的实现。我做了一个对象方法,所以这里是主线。 三类: 神经元 前馈层(包含神经元) 前馈网络(包含前馈层) 所以我通过给网络赋予异或表xor表的历元来训练网络 网络将在千历元后输出约0.5…有趣的
我一直在看一些关于深度学习/卷积神经网络的视频,比如这里和这里,我试图用C语言实现我自己的。在我第一次尝试时,我试图保持输入数据相当简单,所以我的想法是区分十字和圆,我有一个大约25个的小数据集(64*64个图像),它们如下所示: 网络本身有五层: 我的问题是我的网络没有收敛到任何东西上。权重似乎都没有改变。如果我运行它,预测基本保持不变,除了偶尔出现的异常值,它会在下一次迭代返回之前跳起来。 卷
我已经实现了下面的神经网络来解决Python中的异或问题。我的神经网络由3个神经元的输入层、1个2个神经元的隐层和1个神经元的输出层组成。我使用Sigmoid函数作为隐藏层和输出层的激活函数: backpropogation似乎是正确的,但我一直得到这个错误,所有的值都变成了“nan”,输出: 你能帮我解决这个问题吗?谢谢你。
我试图在DL4j中做一个简单的预测(稍后将用于具有n个特性的大型数据集),但无论我做什么,我的网络都不想学习,行为非常奇怪。当然,我学习了所有的教程,并执行了dl4j repo中显示的相同步骤,但不知何故,它对我不起作用。 对于虚拟特性,我使用以下数据: *双[val][x]特征;其中val=linspace(-10,10)...;和x=math.sqrt(math.abs(val))*val;
我创建了一个神经网络,其结构如下: Input1-Input2-输入层。 N0-N1-隐藏层。每个节点3个权重(一个用于偏移)。 N2——输出层。3个砝码(一个用于偏置)。 我正在尝试使用以下测试数据对其进行XOR函数训练: 0 1-期望结果:1 1 0-期望结果:1 0 0-所需结果:0 1 1-所需结果:0 训练后,测试的均方误差(当寻找1结果时){0,1}=0,我认为这很好。但是测试的均方误
我试图用两个感知器网络做一个异或门,但由于某种原因,网络没有学习,当我在图中绘制误差的变化时,误差达到一个静态水平,并在该区域振荡。 目前我没有给网络添加任何偏见。 这是错误随着学习轮数的变化而变化。这是正确的吗?红色线是我所期望的错误将如何改变的线。