【问题标题】:Xor gate with Backpropagation反向传播的异或门
【发布时间】:2025-12-14 14:50:02
【问题描述】:

我正在尝试了解反向传播的工作原理。所以我写了一个直截了当的脚本来尝试理解它,然后再写一个通用的算法。

脚本试图做的是训练一个 XOR 门。 我的神经网络非常简单。 2 个输入、2 个隐藏神经元和 1 个输出。 (注意,为简单起见省略了偏差)

(欲了解更多信息,请参阅最后附上的图片)

问题是在训练感知器后它不起作用,我不知道问题出在哪里。它可以在我的方程式中或在我的实现中。

代码:

    def xor(self):
        print('xor')
        X = np.array([[1,1],[1,0],[0,1],[0,0]]) #X.shape = (4,2)
        y = np.array([0,1,1,0])
        w0 = np.array([[.9,.1],[.3,.5]]) #random weights layer0
        w1 = np.array([.8,.7]) #random wights layer1

        #forward pass
        youtput=[]
        for i in range(X.shape[0]):#X.shape = (4,2)
            #print('x0', X[i][0])
            #print('x1', X[i][1])
            h0 = self.sig(w0[0,0]*X[i][0] + w0[1,0]*X[i][1])
            h1 = self.sig(w0[0,1]*X[i][0] + w0[1,1]* X[i][1])
            y0 = self.sig(w1[0]* h0 + w1[1] * h1) # shape = (4,)
            youtput.append(y0)
            print('y0',y0)

            #backpropagation
            dey0 = -(y[i]-y0) # y[i] -> desired output | y0 -> output
            deW0_00 = dey0 * y0 * (1 - y0) * w1[0] * h0 * (1 - h0) * X[i][0]
            deW0_01 = dey0 * y0 * (1 - y0) * w1[1] * h1 * (1 - h1) * X[i][0]
            deW0_10 = dey0 * y0 * (1 - y0) * w1[0] * h0 * (1 - h0) * X[i][1]
            deW0_11 = dey0 * y0 * (1 - y0) * w1[1] * h1 * (1 - h1) * X[i][1]
            deW1_00 = dey0 * h0
            deW1_10 = dey0 * h1

            w0[0,0] = self.gradient(w0[0,0], deW0_00)
            w0[0,1] = self.gradient(w0[0,1], deW0_01)
            w0[1,0] = self.gradient(w0[1,0], deW0_10)
            w0[1,1] = self.gradient(w0[1,1], deW0_11)
            w1[0] = self.gradient(w1[0], deW1_00)
            w1[1] = self.gradient(w1[1], deW1_10)

            #print('print W0, ', w0)
            #print('print W1, ', w1)
        print('error -> ', self.error(y,youtput ))  
        #forward pass
        youtput2= []
        for i in range(X.shape[0]):#X.shape = (4,2)
            print('x0 =', X[i][0], ', x1 =', X[i][1])
            h0 = self.sig(w0[0,0]*X[i][0] + w0[1,0]*X[i][1])
            h1 = self.sig(w0[0,1]*X[i][0] + w0[1,1]* X[i][1])
            y0 = self.sig(w1[0]* h0 + w1[1] * h1)
            youtput2.append(y0)
            print('y0----->',y0)
        print('error -> ', self.error(y,youtput2 ))

    def gradient(self, w, w_derivative):
        alpha = .001
        for i in range(1000000):
            w = w - alpha * w_derivative
        return w

    def error(self, y, yhat):
        e = 0
        for i in range (y.shape[0]):
            e = e + .5 * (y[i]- yhat[i])**2
        return e 

    def sig(self,x):
         return 1 / (1 + math.exp(-x)) 

结果

PS C:\gitProjects\perceptron> python .\perceptron.py
xor
y0 0.7439839341840395
y0 0.49999936933995615
y0 0.4999996364775347
y0 7.228146514841657e-229
error ->  0.5267565442535
x0 = 1 , x1 = 1
y0-----> 0.49999999999999856
x0 = 1 , x1 = 0
y0-----> 0.4999993695274945
x0 = 0 , x1 = 1
y0-----> 0.49999963653435153
x0 = 0 , x1 = 0
y0-----> 7.228146514841657e-229
error ->  0.3750004969693411

方程。

【问题讨论】:

  • 也许这会有所帮助? towardsdatascience.com/…
  • 我也想看看你是怎么训练网络的
  • 我对神经网络一无所知,但我确实注意到您的代码不完整。它缺少导入、class 语句和 main。
  • @t_e_o 网络使用梯度下降进行训练。在我的代码中,我有一个名为渐变的函数。这个函数对我们想要更新的权重进行导数,然后我们使用梯度下降算法来更新权重。为了查看方程式,请在我写完“为了计算梯度”后检查我的笔记

标签: python backpropagation


【解决方案1】:

只是改变了你“循环”的方式,现在似乎工作正常(以下修改代码)。

我可能错过了一些东西,但你的反向传播看起来不错

import numpy as np
import math

class perceptronmonocouche(object):
    def xor(self):
        print('xor')
        X = np.array([[1,1],[1,0],[0,1],[0,0]]) #X.shape = (4,2)
        y = np.array([0,1,1,0])
        w0 = np.array([[.9,.1],[.3,.5]]) #random weights layer0
        w1 = np.array([.8,.7]) #random wights layer1
        max_epochs = 10000
        epochs = 0
        agreed_convergence_error = 0.001
        error = 1
        decision_threshold = 0.5

        while epochs <= max_epochs and error > agreed_convergence_error:
            #forward pass
            epochs += 1
            youtput=[]
            for i in range(X.shape[0]):#X.shape = (4,2)
                #print('x0', X[i][0])
                #print('x1', X[i][1])
                h0 = self.sig(w0[0,0]*X[i][0] + w0[1,0]*X[i][1])
                h1 = self.sig(w0[0,1]*X[i][0] + w0[1,1]* X[i][1])
                y0 = self.sig(w1[0]* h0 + w1[1] * h1) # shape = (4,)
                youtput.append(y0)
                if epochs%1000 ==0:
                    print('y0',y0)
                    if y0 > decision_threshold:
                        prediction = 1
                    else:
                        prediction = 0
                    print('real value', y[i])
                    print('predicted value', prediction)

                #backpropagation
                dey0 = -(y[i]-y0) # y[i] -> desired output | y0 -> output            
                dew0_00 = dey0 * y0 * (1 - y0) * w1[0] * h0 * (1 - h0) * X[i][0]
                dew0_01 = dey0 * y0 * (1 - y0) * w1[1] * h1 * (1 - h1) * X[i][0]
                dew0_10 = dey0 * y0 * (1 - y0) * w1[0] * h0 * (1 - h0) * X[i][1]
                dew0_11 = dey0 * y0 * (1 - y0) * w1[1] * h1 * (1 - h1) * X[i][1]
                dew1_0 = dey0 * h0
                dew1_1 = dey0 * h1

                w0[0,0] = self.gradient(w0[0,0], dew0_00)
                w0[0,1] = self.gradient(w0[0,1], dew0_01)
                w0[1,0] = self.gradient(w0[1,0], dew0_10)
                w0[1,1] = self.gradient(w0[1,1], dew0_11)
                w1[0] = self.gradient(w1[0], dew1_0)
                w1[1] = self.gradient(w1[1], dew1_1)

                #print('print W0, ', w0)
                #print('print W1, ', w1)
            error = self.error(y,youtput )
            if epochs%1000 ==0:
                print('error -> ', error)

    def gradient(self, w, w_derivative):
        alpha = .2
        w = w - alpha * w_derivative
        return w

    def error(self, y, yhat):
        e = 0
        for i in range (y.shape[0]):
            e = e + .5 * (y[i]- yhat[i])**2
        return e 

    def sig(self,x):
         return 1 / (1 + math.exp(-x))

p = perceptronmonocouche()
p.xor()

结果

y0 0.05892656406522486
real value 0
predicted value 0
y0 0.9593864604895951
real value 1
predicted value 1
y0 0.9593585562506973
real value 1
predicted value 1
y0 0.03119936553811551
real value 0
predicted value 0
error ->  0.003873463452052477

注意:在这里它可以在没有偏见的情况下正常工作,但是我建议您随时可以让偏见传播。

【讨论】:

  • 谢谢,我对梯度的计算方式有误。我只进行了一次前向传递并在梯度中循环,该梯度正在对不起作用的权重做一些事情,但是相反,我每次都需要进行一次前向传递以再次计算梯度。我还用你们中的一些评论修改了我的问题。
  • @mavi 是的,我删除了我的评论,因为它们不再相关,并且每次只推荐使用偏见。祝你的脚本泛化好运!
最近更新 更多