代码先放在这啦,理论知识以后再来补充
import numpy as np
import pandas as pd
import time
import matplotlib.pyplot as plt
start = time.time()
class Bp:
def __init__(self,num_input, num_hidden, num_out, num_sample):
# 三个参数分别为输入,隐藏,输出层的节点个数
self.num_input = num_input
self.num_hidden = num_hidden
self.num_out = num_out
# 初始化权重矩阵
"""
为什么使用rand函数结果全为1
"""
# 以正态分布初始化各层权重
self.weight_in = np.random.normal(0.0, num_input ** - 0.5, (num_input, num_hidden)) #第一层的权重
self.weight_out = np.random.normal(0.0, num_hidden ** - 0.5,(num_hidden, num_out)) #第二层的权重
# self.weight_in = np.random.rand(num_input, num_hidden) # 第一层的权重
# self.weight_out = np.random.rand(num_hidden, num_out) # 第二层的权重
# self.weight_in = np.ones((num_input, num_hidden)) #第一层的权重
# self.weight_out = np.ones((num_hidden, num_out)) #第二层的权重
# print(self.weight_in.shape)
#初始化偏置项
# self.b_in = np.random.rand(num_hidden, 1)
# self.b_out = np.random.rand(num_out, 1)
self.b_in = np.zeros((num_hidden, 1))
self.b_out = np.zeros((num_out, 1))
#初试化各层的激活值
self.input_activate = np.zeros((num_input, 1))
self.hidden_activate = np.zeros((num_hidden, 1))
self.out_activate = np.zeros((num_out, 1))
#初始化激活后的参数
self.num_sample = num_sample
def updata(self, data_input):
self.input_activate = data_input
#第一层更新
# print(self.b_in.shape)
z_hidden = self.input_activate @ self.weight_in + self.b_in.T
# print(self.input_activate.shape, self.weight_in.shape)
# print(z_hidden.shape,self.b_in.shape)
self.hidden_activate = sigmoid(z_hidden)
# print(self.u_activate.shape)
#第二层更新
z_out = self.hidden_activate @ self.weight_out + self.b_out.T
self.out_activate = sigmoid(z_out)
# return sigmoid(z_out)
def derivate_sigmiod(self,x):
return (1 - x) * x
#返回第一次正向传播的误差,即预测值和实际值的差值
def total_loss(self, target):
error = target - self.out_activate
return np.sum(np.power(error, 2)) / self.num_sample
#反向传播更新参数
def backPropagate(self, data, target, alpha):
#求输出层的delta
out_error = self.out_activate - target
out_delta = out_error * self.derivate_sigmiod(self.out_activate)
# print(out_delta)
#计算隐藏层的delta
hidden_error = out_delta @ self.weight_out.T
hidden_delta = hidden_error * self.derivate_sigmiod(self.hidden_activate)
#更新权重
self.weight_in -= alpha * data.T @ hidden_delta / self.num_sample #用平均值
self.weight_out -= alpha * self.hidden_activate.T @ out_delta / self.num_sample #用平均值
# print(np.sum(hidden_delta,axis=0).reshape(self.num_hidden,1))
# print(self.weight_in)
self.b_in -= alpha * np.mean(hidden_delta,axis=0).reshape(self.num_hidden, 1)
self.b_out -= alpha * np.mean(out_delta,axis=0).reshape(self.num_out, 1)
# print(self.b_in)
def train(self, data_input, target, alpha, iterations):
total_loss = []
for iter in range(iterations):
self.updata(data_input)
self.backPropagate(data_input,target, alpha)
loss = self.total_loss(target)
total_loss.append(loss)
return total_loss
def sigmoid(x):
return 1 / (1 + np.exp(-x))
from sklearn.datasets import load_boston
from sklearn.preprocessing import MinMaxScaler
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
# 设置缩放器
scaler = MinMaxScaler(feature_range=(0, 1))
def boston():
print("这是波士顿房价预测:")
# ****************波士顿的房价预测****************************
boston = load_boston()
df = pd.DataFrame(boston['data'], columns=boston['feature_names'])
df['target'] = boston['target']
df = scaler.fit_transform(df)
df, df_test = train_test_split(df,test_size=0.1)
input = df[:, 0:-1]
target = df[:, -1].reshape(-1, 1)
# print(input.shape, target)
n = 1
# 对数据进行预测
model = Bp(13, 69, 1, 5)
loss = model.train(input,target,0.02,2000 * n)
model.updata(df_test[:,0:-1])
plt.plot(np.arange(2000 * n), loss, label="boston")
plt.legend()
plt.show()
print("实际值:\n", df_test[0:5,-1].reshape(-1,1))
print("预测值:\n", model.out_activate[0:5,:])
def cancer():
print("这是乳腺癌预测:")
# *******************乳腺癌的预测*******************************
cancer_data = load_breast_cancer()
df1 = pd.DataFrame(cancer_data['data'], columns=cancer_data['feature_names'])
df1['tagert'] = cancer_data['target']
df1 = scaler.fit_transform(df1)
# 划分数据集
df1, df1_test = train_test_split(df1,test_size=0.1)
input1 = df1[:, 0:-1]
# print(input1.shape)
target1 = df1[:, -1].reshape(-1, 1)
# print(target1)
n1 = 1 # 在这调迭代次数呀
model = Bp(30, 90, 1, 5)
loss = model.train(input1,target1,0.01,2000 * n1)
model.updata(df1_test[:,0:-1])
plt.plot(np.arange(2000 * n1), loss, label="cancer")
plt.legend()
plt.show()
print("实际值:\n", df1_test[0:5,-1].reshape(-1,1))
print("预测值:\n", model.out_activate[0:5,:])
# ******************************************************
boston()
cancer()
end = time.time()
print("用时:{0}秒".format(end - start))
# 绘制不同学习率下的机器学习曲线
# alpha_list = [0.01, 0.05, 0.08, 0.1,0.3,0.5,0.8,1]
# fig, ax = plt.subplots()
# for alpha in alpha_list:
# model = Bp(13, 69, 1, 506)
# total_loss = model.train(df_scaler, target_scaler, alpha, 2000)
# ax.plot(np.arange(2000), total_loss, label=alpha)
# ax.legend()
# plt.show()
# df_scaler = np.array([[1,2,5],[1,3,4],[1, 6, 2],[1, 5, 1],[1, 8, 4]])
# target_scaler = np.array([[0],[1],[1],[0],[1]])
# df_scaler = np.array([[0,0,0],[0,0,1],[0,1,0],[0,1,1],[1,0,0]])
# target_scaler = np.array([[0],[0.2],[0.4],[0.6],[0.8]])