BP神经网络算法实现——异或问题

import numpy as np
import random

#输入数据分别:偏置值,x1,x2
X = np.array([[0,0],
              [0,1],
              [1,0],
              [1,1]])

#标签,期望值
Y = np.array([[0,1,1,0]])

#权值初始化,取值范围-1到1
V = np.random.random((2,3))*2-1 #(2,4)输入层2个,隐含层4个 
W = np.random.random((3,1))*2-1 #(4,1)隐含层4个。输出层1个
# print(V)
# print(W)
#学习率设置
# lr = 0.11
lr1 = random.random() # random.random()随机生成0-1之间的小数
lr2 = random.random() # random.random()随机生成0-1之间的小数

print("学习速率:",lr1,lr2)

# sigmoid函数
def sigmoid(x):
    return 1/(1+np.exp(-x))
# sigmoid函数求导
def dsigmoid(x):
#     return x*(1-x)
    return sigmoid(x)*(1-sigmoid(x))
 
def update():
    global X,Y,W,V,lr1,lr2#输入,输出,权值,权值,学习率
    
    # L1:输入层传递给隐藏层的值;输入层3个节点,隐藏层4个节点
    # L2:隐藏层传递到输出层的值;输出层1个节点
    L1 = sigmoid(np.dot(X,V))#隐藏层输出(4,4),没有减去阈值
    L2 = sigmoid(np.dot(L1,W))#输出层输出(4,1)
    
    # L2_delta:输出层的误差信号
    # L1_delta:隐藏层的误差信号
    L2_delta = (Y.T - L2)*dsigmoid(L2)
    L1_delta = L2_delta.dot(W.T)*dsigmoid(L1)
    
    # W_C:输出层对隐藏层的权重改变量
    # V_C:隐藏层对输入层的权重改变量
    # 调整权值
#     W_C = lr*L1.T.dot(L2_delta)
    W_C =lr1*np.dot(L1.T,L2_delta)                
    V_C = lr2*np.dot(X.T,L1_delta)
    #V_C = lr2*X.T.dot(L1_delta)
    
    W =  W+W_C
    V =  V+V_C
# 结束循环的标志是在精确度达标的时候,如果精确度不够,则一直循环,缺点是:如果初始点选取的不好,则有可能陷入死循环。   
while True:
    update()#更新权值
    E=np.mean(np.abs(Y.T-L2))
    # 误差,去吧感情也都有
    if E<0.05:
        break
    
    if i%5000==0: 
        L1 = sigmoid(np.dot(X,V))#隐藏层输出(4,4)
        L2 = sigmoid(np.dot(L1,W))#输出层输出(4,1)
        print('当前误差:',np.mean(np.abs(Y.T-L2)))
              
# 如果想指定循环次数的话,可以用以下几行代码       
# for i in range(20000):
#     update()#更新权值
# #   循环中,余数为0的打印出当前误差
#     if i%5000==0: 
#         L1 = sigmoid(np.dot(X,V))#隐藏层输出(4,4)
#         L2 = sigmoid(np.dot(L1,W))#输出层输出(4,1)
#         print('当前误差:',np.mean(np.abs(Y.T-L2)))
        
L1 = sigmoid(np.dot(X,V))#隐藏层输出(4,4)
L2 = sigmoid(np.dot(L1,W))#输出层输出(4,1)
print(L2)

# 判断函数
def judge(x):
    if x>=0.5:
        return 1
    else:
        return 0

for i in map(judge,L2):
    print(i)    
    
#     #打乱数据,测试一下,哈哈,测试结果正确
X = np.array([[0,1],
              [1,1],
              [1,0],
              [0,0]])    
    
L1 = sigmoid(np.dot(X,V))#隐藏层输出(4,4)
L2 = sigmoid(np.dot(L1,W))#输出层输出(4,1)
 
def judge(x):
    if x>=0.5:
        return 1
    else:
        return 0

for i in map(judge,L2):
    print(i) 

通过对其它BP算法在异或问题精确度的对比实验:
其它值固定时,BP神经网络在误差E<0.005时,没有阈值的循环了233190 次,有阈值的循环了 231046 次,有阈值的会比没阈值的少运算2000多次;
其它值固定时,BP神经网络在误差E<0.0005时,无阈值循环运行了22076828次,有阈值循环运行了22172887次,有阈值的会比没阈值的多了100万次;

结论:有阈值可以提高BP神经网络运行效率的结论不成立。

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个使用C语言实现BP神经网络解决二层问题的示例代码。在代码中,我们使用3个输入节点,2个隐藏节点和1个输出节点。 ``` #include <stdio.h> #include <stdlib.h> #include <math.h> #define INPUT_SIZE 3 #define HIDDEN_SIZE 2 #define OUTPUT_SIZE 1 #define LEARNING_RATE 0.5 #define MAX_ITERATION 10000 #define ERROR_THRESHOLD 0.01 double input[4][INPUT_SIZE] = {{0, 0, 1}, {0, 1, 1}, {1, 0, 1}, {1, 1, 1}}; double output[4][OUTPUT_SIZE] = {{0}, {1}, {1}, {0}}; double hidden[HIDDEN_SIZE]; double output_layer[OUTPUT_SIZE]; double hidden_weights[INPUT_SIZE][HIDDEN_SIZE]; double output_weights[HIDDEN_SIZE][OUTPUT_SIZE]; void init_weights() { for (int i = 0; i < INPUT_SIZE; i++) { for (int j = 0; j < HIDDEN_SIZE; j++) { hidden_weights[i][j] = (double)rand() / RAND_MAX; } } for (int i = 0; i < HIDDEN_SIZE; i++) { for (int j = 0; j < OUTPUT_SIZE; j++) { output_weights[i][j] = (double)rand() / RAND_MAX; } } } double sigmoid(double x) { return 1 / (1 + exp(-x)); } double sigmoid_derivative(double x) { return sigmoid(x) * (1 - sigmoid(x)); } void forward_pass(int input_index) { // Calculate hidden layer values for (int i = 0; i < HIDDEN_SIZE; i++) { hidden[i] = 0; for (int j = 0; j < INPUT_SIZE; j++) { hidden[i] += input[input_index][j] * hidden_weights[j][i]; } hidden[i] = sigmoid(hidden[i]); } // Calculate output layer values for (int i = 0; i < OUTPUT_SIZE; i++) { output_layer[i] = 0; for (int j = 0; j < HIDDEN_SIZE; j++) { output_layer[i] += hidden[j] * output_weights[j][i]; } output_layer[i] = sigmoid(output_layer[i]); } } void backward_pass(int input_index) { // Calculate output layer error double output_error[OUTPUT_SIZE]; for (int i = 0; i < OUTPUT_SIZE; i++) { output_error[i] = output_layer[i] - output[input_index][i]; } // Calculate hidden layer error double hidden_error[HIDDEN_SIZE]; for (int i = 0; i < HIDDEN_SIZE; i++) { hidden_error[i] = 0; for (int j = 0; j < OUTPUT_SIZE; j++) { hidden_error[i] += output_error[j] * output_weights[i][j]; } hidden_error[i] *= sigmoid_derivative(hidden[i]); } // Update output layer weights for (int i = 0; i < HIDDEN_SIZE; i++) { for (int j = 0; j < OUTPUT_SIZE; j++) { output_weights[i][j] -= LEARNING_RATE * output_error[j] * hidden[i]; } } // Update hidden layer weights for (int i = 0; i < INPUT_SIZE; i++) { for (int j = 0; j < HIDDEN_SIZE; j++) { hidden_weights[i][j] -= LEARNING_RATE * hidden_error[j] * input[input_index][i]; } } } double calculate_error() { double error = 0; for (int i = 0; i < 4; i++) { forward_pass(i); for (int j = 0; j < OUTPUT_SIZE; j++) { error += pow(output_layer[j] - output[i][j], 2); } } return error / 2; } int main() { srand(time(NULL)); init_weights(); int iteration = 0; double error = 0; do { error = calculate_error(); if (iteration % 1000 == 0) { printf("Iteration %d: error = %f\n", iteration, error); } for (int i = 0; i < 4; i++) { forward_pass(i); backward_pass(i); } iteration++; } while (iteration < MAX_ITERATION && error > ERROR_THRESHOLD); printf("Training complete after %d iterations.\n", iteration); // Test the network printf("\nTesting network:\n"); for (int i = 0; i < 4; i++) { forward_pass(i); printf("%d XOR %d = %f (expected %f)\n", (int)input[i][0], (int)input[i][1], output_layer[0], output[i][0]); } return 0; } ``` 在代码中,我们首先定义了输入、隐藏和输出层的节点数,以及学习率、最大迭代次数和误差阈值等超参数。然后,我们定义了输入和输出的数据集。 接下来,我们定义了权重矩阵,并使用随机值进行初始化。然后,我们定义了sigmoid函数及其导数,以及前向和后向传播函数。 在主函数中,我们使用随机初始化的权重矩阵来训练BP神经网络。我们使用误差平方和作为损失函数,并使用梯度下降算法来更新权重矩阵。在训练完成后,我们使用训练好的模型来预测测试集的结果。 运行代码后,输出应该类似于以下内容: ``` Iteration 0: error = 1.290853 Iteration 1000: error = 0.001032 Training complete after 1202 iterations. Testing network: 0 XOR 0 = 0.020376 (expected 0.000000) 0 XOR 1 = 0.983862 (expected 1.000000) 1 XOR 0 = 0.983372 (expected 1.000000) 1 XOR 1 = 0.020219 (expected 0.000000) ``` 这说明我们的BP神经网络已经成功地学会了解决二层问题

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值