### XOR神经网络反向传播

我正在尝试用Python实现一个带有一个隐藏层的基本XOR神经网络。我特别不理解反向传播算法,所以我卡在了计算delta2和更新权重上…能帮帮我吗?


import numpy as np

def sigmoid(x):
    return 1.0 / (1.0 + np.exp(-x))

vec_sigmoid = np.vectorize(sigmoid)

theta1 = np.matrix(np.random.rand(3,3))
theta2 = np.matrix(np.random.rand(3,1))

def fit(x, y, theta1, theta2, learn_rate=.001):
    # 前向传播
    layer1 = np.matrix(x, dtype='f')
    layer1 = np.c_[np.ones(1), layer1]
    layer2 = vec_sigmoid(layer1*theta1)
    layer3 = sigmoid(layer2*theta2)
    
    # 反向传播
    delta3 = y - layer3
    delta2 = (theta2*delta3) * np.multiply(layer2, 1 - layer2) #??
    
    # 更新权重
    theta2 += learn_rate * delta3 #??
    theta1 += learn_rate * delta2 #??

def train(X, Y):
    for _ in range(10000):
        for i in range(4):
            x = X[i]
            y = Y[i]
            fit(x, y, theta1, theta2)

X = [(0,0), (1,0), (0,1), (1,1)]
Y = [0, 1, 1, 0]
train(X, Y)

回答:

好的,首先,这里是修改后的代码,让你的代码能够工作。


#! /usr/bin/python

import numpy as np

def sigmoid(x):
    return 1.0 / (1.0 + np.exp(-x))

vec_sigmoid = np.vectorize(sigmoid)

# Binesh - 只是清理一下代码,这样你可以轻松更改隐藏层的数量。
# 同时,使用Yoshua Bengio的启发式初始化。
# 在很多地方,你混用了矩阵乘法和逐元素乘法... 你不能这样做..(所以我明确地将所有内容改为点积和乘法,以便更清晰。)
input_sz = 2;hidden_sz = 3;output_sz = 1;
theta1 = np.matrix(0.5 * np.sqrt(6.0 / (input_sz+hidden_sz)) * (np.random.rand(1+input_sz,hidden_sz)-0.5))
theta2 = np.matrix(0.5 * np.sqrt(6.0 / (hidden_sz+output_sz)) * (np.random.rand(1+hidden_sz,output_sz)-0.5))

def fit(x, y, theta1, theta2, learn_rate=.1):
    # 前向传播
    layer1 = np.matrix(x, dtype='f')
    layer1 = np.c_[np.ones(1), layer1]
    # Binesh - 对于layer2,我们需要添加一个偏置项。
    layer2 = np.c_[np.ones(1), vec_sigmoid(layer1.dot(theta1))]
    layer3 = sigmoid(layer2.dot(theta2))
    
    # 反向传播
    delta3 = y - layer3
    # Binesh - 实际上,这是交叉熵函数对最终sigmoid函数输入的_负_导数。
    delta2 = np.multiply(delta3.dot(theta2.T), np.multiply(layer2, (1-layer2)))
    # Binesh - 我们实际上不使用偏置项的delta。(这有什么意义呢?
    # 它没有输入。因此下面这行代码。
    delta2 = delta2[:,1:]
    # 但,delta只是sigmoid输入的导数。
    # 我们不会直接将这些加到theta上。我们必须将这些乘以
    # 前一层以获得theta2d和theta1d
    theta2d = np.dot(layer2.T, delta3)
    theta1d = np.dot(layer1.T, delta2)
    
    # 更新权重
    # Binesh - 这里你使用了delta3和delta2... 这些不是
    # theta的导数,它们是sigmoid输入的导数..(如上所述)
    theta2 += learn_rate * theta2d #??
    theta1 += learn_rate * theta1d #??

def train(X, Y):
    for _ in range(10000):
        for i in range(4):
            x = X[i]
            y = Y[i]
            fit(x, y, theta1, theta2)

# Binesh - 这里是一个小测试函数,用来查看它是否真的工作
def test(X):
    for i in range(4):
        layer1 = np.matrix(X[i],dtype='f')
        layer1 = np.c_[np.ones(1), layer1]
        layer2 = np.c_[np.ones(1), vec_sigmoid(layer1.dot(theta1))]
        layer3 = sigmoid(layer2.dot(theta2))
        print "%d xor %d = %.7f" % (layer1[0,1], layer1[0,2], layer3[0,0])

X = [(0,0), (1,0), (0,1), (1,1)]
Y = [0, 1, 1, 0]
train(X, Y)
# Binesh - 好吧,让我们看看!
test(X)

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注