- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
出于学习目的,我一直在尝试实现自己的玩具神经网络库。我已经尝试在各种逻辑门操作(如 Or、And 和 XOR)上测试它。虽然它适用于 OR 操作,但它无法用于 AND 和 XOR 操作。它很少为 AND 和 XOR 运算提供正确的输出。
我尝试了范围学习率。我还尝试了各种学习曲线来找到具有时期数的成本模式。
import numpy as np
class myNeuralNet:
def __init__(self, layers = [2, 2, 1], learningRate = 0.09):
self.layers = layers
self.learningRate = learningRate
self.biasses = [np.random.randn(l, 1) for l in self.layers[1:]]
self.weights = [np.random.randn(i, o) for o, i in zip(self.layers[:-1], self.layers[1:])]
self.cost = []
def sigmoid(self, z):
return (1.0 / (1.0 + np.exp(-z)))
def sigmoidPrime(self, z):
return (self.sigmoid(z) * (1 - self.sigmoid(z)))
def feedForward(self, z, predict = False):
activations = [z]
for w, b in zip(self.weights, self.biasses): activations.append(self.sigmoid(np.dot(w, activations[-1]) + b))
# for activation in activations: print(activation)
if predict: return np.round(activations[-1])
return np.array(activations)
def drawLearningRate(self):
import matplotlib.pyplot as plt
plt.xlim(0, len(self.cost))
plt.ylim(0, 5)
plt.plot(np.array(self.cost).reshape(-1, 1))
plt.show()
def backPropogate(self, x, y):
bigDW = [np.zeros(w.shape) for w in self.weights]
bigDB = [np.zeros(b.shape) for b in self.biasses]
activations = self.feedForward(x)
delta = activations[-1] - y
# print(activations[-1])
# quit()
self.cost.append(np.sum([- y * np.log(activations[-1]) - (1 - y) * np.log(1 - activations[-1])]))
for l in range(2, len(self.layers) + 1):
bigDW[-l + 1] = (1 / len(x)) * np.dot(delta, activations[-l].T)
bigDB[-l + 1] = (1 / len(x)) * np.sum(delta, axis = 1)
delta = np.dot(self.weights[-l + 1].T, delta) * self.sigmoidPrime(activations[-l])
for w, dw in zip(self.weights, bigDW): w -= self.learningRate * dw
for b, db in zip(self.biasses, bigDB): b -= self.learningRate *db.reshape(-1, 1)
return np.sum(- y * np.log(activations[-1]) - (1 - y) * np.log(1 - activations[-1])) / 2
if __name__ == '__main__':
nn = myNeuralNet(layers = [2, 2, 1], learningRate = 0.35)
datasetX = np.array([[1, 1], [0, 1], [1, 0], [0, 0]]).transpose()
datasetY = np.array([[x ^ y] for x, y in datasetX.T]).reshape(1, -1)
print(datasetY)
# print(nn.feedForward(datasetX, predict = True))
for _ in range(60000): nn.backPropogate(datasetX, datasetY)
# print(nn.cost)
print(nn.feedForward(datasetX, predict = True))
nn.drawLearningRate()
有时也会报“RuntimeWarning: overflow encountered in exp”,有时会导致收敛失败。
最佳答案
对于交叉熵错误,您需要在网络上有一个概率输出层才能正确工作。 Sigmoid 通常不起作用,也不应该真正使用。
您的公式似乎有点不对劲。对于您定义的当前网络布局:3 层(2、2、1),您有 w0(2x2) 和 w1(1x2)。记得找到 dw1 你有以下内容:
d1 = (guess - target) * sigmoid_prime(net_inputs[1]) <- when you differentiated da2/dz1 you ended up f'(z1) and not f'(a2)!
dw1 = d1 * activations[1]
db1 = np.sum(d1, axis=1)
d0 = d1 * w1 * sigmoid_prime(net_inputs[0])
dw0 = d0 * activations[0]
db0 = np.sum(d0, axis=1)
要记住的是每一层都有 net_inputs 作为
z := w @ x + b
和激活
a := f(z)
.在反向传播过程中,当您计算 da[i]/dz[i-1] 时,您需要将激活函数的导数应用于 z[i-1] 而不是 a[i]。
z = w @ x + b
a = f(z)
da/dz = f'(z) !!!
这是针对所有图层的。一些小的注意事项:
将误差计算切换为:np.mean(.5 * (activations[-1] - y) ** 2) 如果您没有对输出层使用软/硬最大激活函数(对于单输出神经元你为什么会这样)。
在delta计算期间在激活函数的导数中使用z-s
不要使用 Sigmoid(它在梯度消失方面有问题),尝试 ReLu:np.where(x <= 0, 0, x)/np.where(x<=0, 0, 1) 或它的一些变体。
对于 XOR 的学习率,在 [.0001, .1] 之间选择应该足以使用任何类型的优化。
如果您将权重矩阵初始化为:[number_of_input_units x number_of_output_units] 而不是 [number_of_output_units x number_of_input_units],您可以将 z = w @ x + b 更改为 z = x @ w + b 和您不需要调换输入和输出。
下面是上面的示例实现:
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(0)
def cost(guess, target):
return np.mean(np.sum(.5 * (guess - target)**2, axis=1), axis=0)
datasetX = np.array([[0., 0.], [0., 1.], [1., 0.], [1., 1.]])
datasetY = np.array([[0.], [1.], [1.], [0.]])
w0 = np.random.normal(0., 1., size=(2, 4))
w1 = np.random.normal(0., 1., size=(4, 1))
b0 = np.zeros(4)
b1 = np.zeros(1)
f1 = lambda x: np.where(x <= 0, 0, x)
df1 = lambda d: np.where(d <= 0, 0, 1)
f2 = lambda x: np.where(x <= 0, .1*x, x)
df2 = lambda d: np.where(d <= 0, .1, 1)
costs = []
for i in range(250):
a0 = datasetX
z0 = a0 @ w0 + b0
a1 = f1(z0)
z1 = a1 @ w1 + b1
a2 = f2(z1)
costs.append(cost(a2, datasetY))
d1 = (a2 - datasetY) * df2(z1)
d0 = d1 @ w1.T * df1(z0)
dw1 = a1.T @ d1
db1 = np.sum(d1, axis=0)
dw0 = a0.T @ d0
db0 = np.sum(d0, axis=0)
w0 = w0 - .1 * dw0
b0 = b0 - .1 * db0
w1 = w1 - .1 * dw1
b1 = b1 - .1 * db1
print(f2(f1(datasetX @ w0 + b0) @ w1 + b1))
plt.plot(costs)
plt.show()
它给出的结果:
[[0.00342399]
[0.99856158]
[0.99983358]
[0.00156524]]
关于python - 如何正确实现反向传播,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56240097/
我能否获得一个具有两个参数的递归Prolog谓词,称为反向,它返回列表的反向: 示例查询和预期结果: α-反向([a,b,c],L)。 L = [c,b,a]。 由两个称为palindrome的参数组
在使用 get_dummies() 将分类数据转换为数字数据后,我的数据框看起来像这样 score1 score2 country_CN country _AU category_leader ca
我有一张 table ,上面有一个国家/地区列表。说这些国家之一是“马其顿” 如果搜索“马其顿共和国”,什么 SQL 查询会返回“马其顿”记录? 我相信在 linq 中它会是这样的 var count
我们有一个角色继承结构,它假设每个人都默认获得最低级别的角色,而不是最高级别的过滤,如下图所示: role.Everyone //lowest level; everyone gets this ro
我正在使用 $.each() 解析数组,但在其中,我使用 .splice() 方法,因此我需要向后迭代。这可能吗? var store = [...]; //... var rules = [...]
我有一个 SPLObjectStorage 对象,其中 Player 对象作为键,分数作为与之关联的信息。玩家对象按照从最高分到最低分的顺序添加到存储中,但我现在需要以相反的顺序遍历它们。 我还需要能
我无法理解这一点:如果我给 Prolog reverse([], A). 它工作得很好,如果我给它 reverse(A, [] ). 并根据第一个建议回答 ; 它挂起!为什么? (GNU Prolog
我有一个 SPLObjectStorage 对象,其中 Player 对象作为键,分数作为与之关联的信息。玩家对象按照从最高分到最低分的顺序添加到存储中,但我现在需要以相反的顺序遍历它们。 我还需要能
我有一个HashMap看起来像: HashMap playerHashMap = new HashMap<>(); 玩家是包含姓名、号码、年龄等的对象。 现在我已经对它进行了排序,它看起来像这样: k
我有这个: file://localhost/Volumes/Untitled%20RAID%20Set%201/Callum/iTunes/Music/Steppenwolf/Steppenwolf
我正在使用 std::regex 并希望找到与某个用户定义的正则表达式字符串匹配的字符串中的最后一个位置。 例如,给定正则表达式 :.* 和字符串“test:55:last”,我想找到“:last”,
有一个表 ServErog(服务),它被重新引导到 4 个表 ServA、ServB、ServC、ServD(它们是不同的非统一服务),其中包含 servtype(服务类型)和 type_id(来自其
这个问题在这里已经有了答案: What is the best way to convert date from JavaScript string in format YYYYMMDD to Ja
我知道如何获得包含几个词的所有结果: SELECT * FROM `table` WHERE MATCH (`row`) AGAINST ('+word1 +word2' IN BOOLEAN MOD
你好,我有这个 html 代码: .container{ width: 450; height: 400; border:1px solid
我想知道是否有任何方法可以使用相同的 CSS 过渡实例来将其向前移动然后向后/向后移动。例如,假设我有这种转变: @-webkit-keyframes fade-transition { fr
假设我有这些字符串: char ref[30] = "1234567891234567891"; char oth[30] = "1234567891234567891"; 我想在 C++ 中使用 S
所以我有这段代码,它使 xcode 崩溃 void strrev(const std::string& str) { for(size_t i=str.length();i>=0;i--)
我正在使用下面的代码使每张图片 1 对 1 淡入淡出。我怎样才能反向执行此操作以使图片以相反的顺序加载? img {display:none;} $('img').each(function(
我正在尝试弄清楚如何改变 FrameLayout 堆叠其子项的方式。 目前它是最新的(先进先出)。我想更改它,使最新的 child 位于底部(FILO)。我试着查看 FrameLayout 的源代码,
我是一名优秀的程序员,十分优秀!