# 导入必要的运行包# 三大件import numpy as np
import pandas as pd
import numpy.random
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
import time
# 定义损失函数--目标函数-->输出损失值defcost(self, X, y, theta):
left = np.multiply(-y, np.log(self.model(X, theta)))
right = np.multiply(1- y, np.log(1- self.model(X, theta)))return np.sum(left - right)/(len(X))
4.定义梯度计算函数
# 定义梯度的计算公式defgradient(self, X, y, theta):
grad = np.zeros(theta.shape)# 对应theta的形状
error =(self.model(X, theta)- y).ravel()for j inrange(len(theta.ravel())):# for each parmeter
term = np.multiply(error, X[:, j])# 分三次对不同的theta进行梯度计算
grad[0, j]= np.sum(term)/len(X)# 累计和取均值return grad # 返回的是一个更新的方向
# 对输出的softmax概率进行二分类处理defpredict(self, X, theta):
X = self.data_matrix(X)# print(self.model(X, theta)) # 为什么全他妈大于0.5return[1if x >=0.5else0for x in self.model(X, theta)]
7.进行梯度计算进行训练以及损失值可视化调用的函数
defdescent(self, data, theta, batchSize, stopType, thresh, alpha):# 梯度下降求解
init_time = time.time()
i =0# 迭代次数
k =0# batch
X, y = self.shuffleData(data)
grad = np.zeros(theta.shape)# 计算的梯度
costs =[self.cost(X, y, theta)]# 损失值whileTrue:
grad = self.gradient(X[k:k + batchSize], y[k:k + batchSize], theta)# 给的数据越多梯度进行计算时考虑的样本也就越多
k += batchSize # 取batch数量个数据if k >=len(data):# 如果取得数据范围大于了原有数据的长度,就重新从第一个开始,每次都打乱顺序,综合考虑数据
k =0
X, y = self.shuffleData(data)# 重新洗牌
theta = theta - alpha * grad # 参数更新, alpha是学习率,grad代表的是更新方向
costs.append(self.cost(X, y, theta))# 计算新的损失,将损失放入列表中,便于后期进行变化大小判别
i +=1# 迭代次数加一if stopType ==0:
value = i
elif stopType ==1:
value = costs
elif stopType ==2:
value = grad
if self.stopCriterion(stopType, value, thresh):breakreturn theta, i -1, costs, grad, time.time()- init_time
defrunExpe(self, data, theta, batchSize, stopType, thresh, alpha):# 核心代码
theta,iter, costs, grad, dur = self.descent(data, theta, batchSize, stopType, thresh, alpha)# 进行显示代码
name ="Original"if(data[:,1]>2).sum()>1else"Scaled"
name +=" data - learning rate: {} - ".format(alpha)if batchSize ==len(data):
strDescType ="Gradient"elif batchSize ==1:
strDescType ="Stochastic"else:
strDescType ="Mini-batch ({})".format(batchSize)
name += strDescType +" descent - Stop: "if stopType ==0:
strStop ="{} iterations".format(thresh)elif stopType ==1:
strStop ="costs change < {}".format(thresh)else:
strStop ="gradient norm < {}".format(thresh)
name += strStop
print("***{}\nTheta: {} - Iter: {} - Last cost: {:03.2f} - Duration: {:03.2f}s".format(
name, theta,iter, costs[-1], dur))
fig, ax = plt.subplots(figsize=(12,4))
ax.plot(np.arange(len(costs)), costs,'r')
ax.set_xlabel('Iterations')
ax.set_ylabel('Cost')
ax.set_title(name.upper()+' - Error vs. Iteration')
plt.show()return theta