- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我试图使用 Python 从头开始实现一个简单的神经网络。这个神经网络只有两个神经元,任务是将输入与输出相匹配。 (即 x = 0 --> 输出 = 0,x = 1 --> 输出 = 1)
我使用了偏导数并尝试使用梯度上升来最大化负损失。 (完整代码如下)即使经过10000多次迭代训练,输出也不够好。 (我认为损失可能停留在局部最大值处。)任何人都可以帮我弄清楚我的实现有什么问题。
import random
import numpy as np
import math
def sigmoid(x):
return 1 / (1 + np.exp(-x))
def error(d,z):
return -0.5 * np.sum(np.power(d-z, 2))
# x = input
##x = np.random.choice((0,1),10000)
x = np.array([0, 1])
# y = desired output
d = np.copy(x)
# weights of two neurons
w = np.random.rand(2)
# now training using backprop
gradient = np.random.rand(2)
iterations = 800
rate = 5
k = 1
for i in xrange(1, iterations + 1):
y = sigmoid(w[0] * x)
z = sigmoid(w[1] * y)
gradient[0] = np.sum(z * w[1] * y * x * (d-z) * (1-y) * (1-z))
gradient[1] = np.sum(y * z * (d-z) * (1-z))
w[0] += gradient[0] * rate
w[1] += gradient[1] * rate
print "Iteration %d, Error %f, Change %f" % (i, error(d,z), ((gradient[0] * rate) ** 2 + (gradient[1] * rate) ** 2)**0.5)
change = ((gradient[0] * rate) ** 2 + (gradient[1] * rate) ** 2)**0.5
if change < 0.00001:
break
## now test
print "1",
x = 1
y = sigmoid(w[0]*x)
z = sigmoid(w[1]*y)
print z
print "0",
x = 0
y = sigmoid(w[0]*x)
z = sigmoid(w[1]*y)
print z
最佳答案
您的简单网络无法学习此功能。
问题是神经元缺乏偏见。如果我们称你的两个权重为 W1 和 W2,你可以看到问题:
如果输入是 0
,那么W1没有区别,第一层的输出是0.5
第二层的输出将是sigmoid( 0.5 * W2 )
.要学习输出 0 值,则网络必须使 W2 变大且为负。
如果输入是 1
, 那么第一层的调用输出为N
, 它必须在 0 和 1 之间。第二层的输出将是 sigmoid( N * W2 )
.如果W2
大而负,那么网络最好的办法就是为 W1
学习一个大的负权重, 制作 N
接近于零。但这仍然充其量只能学会输出一些东西 < 0.5
,因为 sigmoid(0)
是0.5
.
无论您选择什么权重,您都无法为 [0,1] 输入接近 [0,1] 输出。解决方案是在第二层中至少添加一个偏差项,尽管对每个神经元都设置偏差更为正常。
关于python - 具有两个神经元的神经网络,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46561514/
我正在实验性地尝试创建一种具有以下标准的新型神经网络: 每个神经元必须是一个单独的对象。 每个神经元都应该有自己的线程。 网络必须部分连接且随机(在启动时)。 神经元必须异步运行以计算其输出、更新其权
如果我想动态地向我的 tensorflow 层中的一个添加新节点,我该怎么做? 例如,如果我想在模型训练一段时间后将隐藏节点的数量从 10 更改为 11。另外,假设我知道我希望进出该节点/神经元的权重
换句话来说,将神经元求和公式中sigmoid之前的偏置切换为b_j或者附加w_ij*x_i的主要原因是什么?表现? 哪种方法最好,为什么? 注意:j是实际层的神经元,i是下层的神经元。 最佳答案 注意
我是一名优秀的程序员,十分优秀!