前言:
摘要:本文对机器学习实验五 标准BP算法的代码进行实现,如果不了解的BP算法的话,可以自行上网搜索BP算法的详解.
实验题目: 编程实现误差逆传播算法(BP算法)
实验目的: 掌握误差逆传播算法(BP算法)的工作流程
实验环境(硬件和软件) Anaconda/Jupyter notebook/Pycharm
实验内容:
编码实现标准BP算法,在西瓜数据集3.0上用这个算法训练一个单隐层网络,并进行测试。
要求:
一、已经给定部分代码,补充完整的代码,需要补充代码的地方已经用红色字体标注,在第(2)部分,包括:
#补充前向传播代码
#补充反向传播代码
#补充参数更新代码
#补充Loss可视化代码
二、将补充完整的第(2)部分的代码提交,并提交实验结果;(也可以自己重写这部分的代码提交)
代码 :
PS:标准BP算法
import pandas as pd import numpy as np from sklearn.preprocessing import LabelEncoder from sklearn.preprocessing import StandardScaler import matplotlib.pyplot as plt seed = 2020 import random np.random.seed(seed) # Numpy module. random.seed(seed) # Python random module. plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签 plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号 plt.close('all') # 数据预处理 data = pd.read_csv("PS:这里放入自己数据所在的路径。") def preprocess(data): # 将非数映射数字 for title in data.columns: if data[title].dtype == 'object': encoder = LabelEncoder() data[title] = encoder.fit_transform(data[title]) # 去均值和方差归一化 ss = StandardScaler() X = data.drop('好瓜', axis=1) Y = data['好瓜'] X = ss.fit_transform(X) x, y = np.array(X), np.array(Y).reshape(Y.shape[0], 1) return x, y # 定义Sigmoid def sigmoid(x): return 1 / (1 + np.exp(-x)) # 求导 def d_sigmoid(x): return x * (1 - x) # 标准BP算法 def standard_BP(x, y, dim=10, eta=0.8, max_iter=500): n_samples = 1 w1 = np.random.random((x.shape[1], dim)) w2 = np.random.random((dim, 1)) b1 = np.random.random((n_samples, dim)) b2 = np.random.random((n_samples, 1)) losslist = [] for ite in range(max_iter): loss_per_ite = [] for m in range(x.shape[0]): xi, yi = x[m, :], y[m, :] xi, yi = xi.reshape(1, xi.shape[0]), yi.reshape(1, yi.shape[0]) ##补充前向传播代码 u1 = np.dot(xi, w1) + b1 out1 = sigmoid(u1) u2 = np.dot(out1, w2) + b2 out2 = sigmoid(u2) loss = np.square(yi - out2) / 2 loss_per_ite.append(loss) print('iter:%d loss:%.4f' % (ite, loss)) ##反向传播 ##补充反向传播代码 ##补充参数更新代码 g = (yi - out2) * d_sigmoid(out2) d_w2 = np.dot(np.transpose(out1), g) d_b2 = -g d_out1 = np.dot(g, np.transpose(w2)) e = d_out1 * sigmoid(out1) d_w1 = np.dot(np.transpose(xi), e) d_b1 = -e w1 = w1 + eta * d_w1 w2 = w2 + eta * d_w2 b1 = b1 + eta * d_b1 b2 = b2 + eta * d_b2 losslist.append(np.mean(loss_per_ite)) ##Loss可视化 ##补充Loss可视化代码 plt.figure() plt.plot([i + 1 for i in range(max_iter)], losslist) plt.legend(['standard BP']) plt.xlabel('iteration') plt.ylabel('loss') plt.show() return w1, w2, b1, b2 # 测试 def main(): data = pd.read_table('watermelon30.txt', delimiter=',') data.drop('编号', axis=1, inplace=True) x, y = preprocess(data) dim = 10 # _,_,_,_ = standard_BP(x,y,dim) w1, w2, b1, b2 = standard_BP(x, y, dim) u1 = np.dot(x, w1) + b1 out1 = sigmoid(u1) u2 = np.dot(out1, w2) + b2 out2 = sigmoid(u2) y_pred = np.round(out2) result = pd.DataFrame(np.hstack((y, y_pred)), columns=['真值', '预测']) result.to_excel('result.xlsx', index=False) # 补充测试代码,根据当前的x,预测其类别; if __name__ == '__main__': main()
总结:
标准BP的算法实现的核心在于对的向前,向后,参数的更新算法的理解。
PS:BP算法中有标准BP算法与累积BP算法的区别,这里给出的是标准的BP算法的一个小示例,如果读者对BP算法有兴趣的话,建议您在网上查阅资料或者查阅书籍。