当前位置: 首页 > news >正文

【机器学习】逻辑回归的梯度下降以及在一变量数据集、两变量数据集下探索优化的梯度下降算法

引言

在机器学习中,逻辑回归是一种用于二分类问题的方法。它使用逻辑函数(也称为sigmoid函数)来预测属于某个类别的概率。逻辑回归的损失函数通常是交叉熵损失,用于衡量预测值与真实值之间的差异

文章目录

  • 引言
  • 一、逻辑回归的梯度下降
    • 1.1 逻辑回归的梯度下降算法的Python代码示例
    • 1.2 代码解释
    • 1.3 代码注意点
  • 二、逻辑回归的梯度下降
    • 2.1 导入第三方库
    • 2.2 数据集
    • 2.3 逻辑梯度下降
    • 2.4 梯度下降实现
    • 2.5 计算梯度的代码描述
    • 2.6 梯度下降法代码
    • 2.7 另一个数据集
    • 2.8 总结

一、逻辑回归的梯度下降

1.1 逻辑回归的梯度下降算法的Python代码示例

这段代码将展示如何计算损失函数的梯度,并更新模型参数

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2024/8/2 22:31
# @Software: PyCharm
# @Author  : xialiwei
# @Email   : xxxxlw198031@163.comimport numpy as np
# sigmoid函数,用于逻辑回归的预测
def sigmoid(z):return 1 / (1 + np.exp(-z))
# 逻辑回归的损失函数
def log_loss(h, y):return (-y * np.log(h) - (1 - y) * np.log(1 - h)).mean()
# 计算梯度
def compute_gradient(X, y, w, b):m = len(y)z = np.dot(X, w) + bh = sigmoid(z)error = h - ydw = (1/m) * np.dot(X.T, error)db = (1/m) * np.sum(error)return dw, db
# 梯度下降算法
def gradient_descent(X, y, w_init, b_init, learning_rate, num_iterations):w = w_initb = b_initfor i in range(num_iterations):dw, db = compute_gradient(X, y, w, b)w -= learning_rate * dwb -= learning_rate * db# 可选:打印损失值,以便观察收敛情况if i % 100 == 0:z = np.dot(X, w) + bh = sigmoid(z)loss = log_loss(h, y)print(f"Iteration {i}: Loss {loss}")return w, b
# 示例数据(这里需要你自己准备数据集X和标签y)
# X = ... # 特征矩阵,形状为 (num_samples, num_features)
# y = ... # 标签向量,形状为 (num_samples,)
X_train = np.array([[0.5, 1.5], [1,1], [1.5, 0.5], [3, 0.5], [2, 2], [1, 2.5]])
y_train = np.array([0, 0, 0, 1, 1, 1])
# 初始化参数
w_init = np.zeros(X_train.shape[1])
b_init = 0
# 设置学习率和迭代次数
learning_rate = 0.01
num_iterations = 9000
# 执行梯度下降
w_final, b_final = gradient_descent(X_train, y_train, w_init, b_init, learning_rate, num_iterations)

1.2 代码解释

在这个代码中:

  • sigmoid 函数用于计算逻辑回归的预测值
  • log_loss 函数用于计算损失
  • compute_gradient 函数用于计算损失函数关于模型参数的梯度
  • 最后gradient_descent 函数实现了梯度下降算法,通过迭代更新模型参数

1.3 代码注意点

  • 这段代码是一个简化的示例,实际应用中可能需要对数据进行预处理,比如特征缩放,并且可能需要添加正则化项来防止过拟合
  • 学习率、迭代次数和其他超参数可能需要根据具体问题进行调整

二、逻辑回归的梯度下降

2.1 导入第三方库

import copy, math
import numpy as np
%matplotlib widget
import matplotlib.pyplot as plt
from lab_utils_common import  dlc, plot_data, plt_tumor_data, sigmoid, compute_cost_logistic
from plt_quad_logistic import plt_quad_logistic, plt_prob
plt.style.use('./deeplearning.mplstyle')

2.2 数据集

从决策边界实验中使用的同一个双特征数据集开始

X_train = np.array([[0.5, 1.5], [1,1], [1.5, 0.5], [3, 0.5], [2, 2], [1, 2.5]])
y_train = np.array([0, 0, 0, 1, 1, 1])

像之前一样,我们将使用一个辅助函数来绘制这些数据。标签为𝑦=1的数据点用红色十字表示,而标签为𝑦=0的数据点用蓝色圆圈表示。

fig,ax = plt.subplots(1,1,figsize=(4,4))
plot_data(X_train, y_train, ax)
​
ax.axis([0, 4, 0, 3.5])
ax.set_ylabel('$x_1$', fontsize=12)
ax.set_xlabel('$x_0$', fontsize=12)
plt.show()

输出结果:
在这里插入图片描述

2.3 逻辑梯度下降

回忆一下,梯度下降算法利用梯度计算:
重复直到收敛:
repeat until convergence: { w j = w j − α ∂ J ( w , b ) ∂ w j for j := 0..n-1 b = b − α ∂ J ( w , b ) ∂ b } \begin{align*} &\text{repeat until convergence:} \; \lbrace \\ & \; \; \;w_j = w_j - \alpha \frac{\partial J(\mathbf{w},b)}{\partial w_j} \tag{1} \; & \text{for j := 0..n-1} \\ & \; \; \; \; \;b = b - \alpha \frac{\partial J(\mathbf{w},b)}{\partial b} \\ &\rbrace \end{align*} repeat until convergence:{wj=wjαwjJ(w,b)b=bαbJ(w,b)}for j := 0..n-1(1)

每次迭代都对所有的𝑤𝑗执行同时更新,其中
∂ J ( w , b ) ∂ w j = 1 m ∑ i = 0 m − 1 ( f w , b ( x ( i ) ) − y ( i ) ) x j ( i ) ∂ J ( w , b ) ∂ b = 1 m ∑ i = 0 m − 1 ( f w , b ( x ( i ) ) − y ( i ) ) \begin{align*} \frac{\partial J(\mathbf{w},b)}{\partial w_j} &= \frac{1}{m} \sum\limits_{i = 0}^{m-1} (f_{\mathbf{w},b}(\mathbf{x}^{(i)}) - y^{(i)})x_{j}^{(i)} \tag{2} \\ \frac{\partial J(\mathbf{w},b)}{\partial b} &= \frac{1}{m} \sum\limits_{i = 0}^{m-1} (f_{\mathbf{w},b}(\mathbf{x}^{(i)}) - y^{(i)}) \tag{3} \end{align*} wjJ(w,b)bJ(w,b)=m1i=0m1(fw,b(x(i))y(i))xj(i)=m1i=0m1(fw,b(x(i))y(i))(2)(3)

  • m m m是数据集中的训练示例数量
  • f w , b ( x ( i ) ) f_{\mathbf{w},b}(x^{(i)}) fw,b(x(i))是模型的预测,而 y ( i ) y^{(i)} y(i)是目标值
  • 对于逻辑回归模型
    z = w ⋅ x + b z = \mathbf{w} \cdot \mathbf{x} + b z=wx+b
    f w , b ( x ) = g ( z ) f_{\mathbf{w},b}(x) = g(z) fw,b(x)=g(z)
    – 其中𝑔(𝑧)是sigmoid函数: g ( z ) = 1 1 + e − z g(z) = \frac{1}{1+e^{-z}} g(z)=1+ez1

2.4 梯度下降实现

梯度下降算法实现包含两个部分:

  • 实现上述方程(1)的循环。这是下面的gradient_descent,通常在可选和实践实验中提供给您
  • 计算当前梯度,上述方程(2,3)。这是compute_gradient_logistic。这周您将在实践实验中实现这个

2.5 计算梯度的代码描述

实现上述方程(2,3)对于所有的𝑤𝑗和𝑏。有很多种实现方式。下面是其中一种:
初始化变量以累积dj_dw和dj_db,对于每个示例,计算该示例的错误𝑔(𝐰⋅𝐱(𝑖)+𝑏)−𝐲(𝑖),对于该示例中的每个输入值𝑥(𝑖)𝑗,,将错误乘以输入𝑥(𝑖)𝑗,并加到dj_dw的对应元素上。(方程2)将错误加到dj_db上(方程3)将dj_db和dj_dw除以示例总数(m)

注意,在numpy中𝐱(𝑖)是X[i,:]或X[i],而𝑥(𝑖)𝑗是X[i,j]

def compute_gradient_logistic(X, y, w, b): """Computes the gradient for linear regression Args:X (ndarray (m,n): Data, m examples with n featuresy (ndarray (m,)): target valuesw (ndarray (n,)): model parameters  b (scalar)      : model parameterReturnsdj_dw (ndarray (n,)): The gradient of the cost w.r.t. the parameters w. dj_db (scalar)      : The gradient of the cost w.r.t. the parameter b. """m,n = X.shapedj_dw = np.zeros((n,))                           #(n,)dj_db = 0.for i in range(m):f_wb_i = sigmoid(np.dot(X[i],w) + b)          #(n,)(n,)=scalarerr_i  = f_wb_i  - y[i]                       #scalarfor j in range(n):dj_dw[j] = dj_dw[j] + err_i * X[i,j]      #scalardj_db = dj_db + err_idj_dw = dj_dw/m                                   #(n,)dj_db = dj_db/m                                   #scalarreturn dj_db, dj_dw  

检查以下代码中梯度函数的实现

X_tmp = np.array([[0.5, 1.5], [1,1], [1.5, 0.5], [3, 0.5], [2, 2], [1, 2.5]])
y_tmp = np.array([0, 0, 0, 1, 1, 1])
w_tmp = np.array([2.,3.])
b_tmp = 1.
dj_db_tmp, dj_dw_tmp = compute_gradient_logistic(X_tmp, y_tmp, w_tmp, b_tmp)
print(f"dj_db: {dj_db_tmp}" )
print(f"dj_dw: {dj_dw_tmp.tolist()}" )

输出结果:
在这里插入图片描述
预期结果:
dj_db: 0.49861806546328574
dj_dw: [0.498333393278696, 0.49883942983996693]

结论:输出结果与预期结果一致

2.6 梯度下降法代码

下面是实现上述方程(1)的代码。
将程序中的函数与上面的方程进行比较。

def gradient_descent(X, y, w_in, b_in, alpha, num_iters): """Performs batch gradient descentArgs:X (ndarray (m,n)   : Data, m examples with n featuresy (ndarray (m,))   : target valuesw_in (ndarray (n,)): Initial values of model parameters  b_in (scalar)      : Initial values of model parameteralpha (float)      : Learning ratenum_iters (scalar) : number of iterations to run gradient descentReturns:w (ndarray (n,))   : Updated values of parametersb (scalar)         : Updated value of parameter """# An array to store cost J and w's at each iteration primarily for graphing laterJ_history = []w = copy.deepcopy(w_in)  #avoid modifying global w within functionb = b_infor i in range(num_iters):# Calculate the gradient and update the parametersdj_db, dj_dw = compute_gradient_logistic(X, y, w, b)   # Update Parameters using w, b, alpha and gradientw = w - alpha * dj_dw               b = b - alpha * dj_db               # Save cost J at each iterationif i<100000:      # prevent resource exhaustion J_history.append( compute_cost_logistic(X, y, w, b) )# Print cost every at intervals 10 times or as many iterations if < 10if i% math.ceil(num_iters / 10) == 0:print(f"Iteration {i:4d}: Cost {J_history[-1]}   ")return w, b, J_history         #return final w,b and J history for graphing

在我们的数据集上跑梯度下降的代码

w_tmp  = np.zeros_like(X_train[0])
b_tmp  = 0.
alph = 0.1
iters = 10000w_out, b_out, _ = gradient_descent(X_train, y_train, w_tmp, b_tmp, alph, iters) 
print(f"\nupdated parameters: w:{w_out}, b:{b_out}")

输出结果:
在这里插入图片描述

绘制梯度下降结果的代码:

fig,ax = plt.subplots(1,1,figsize=(5,4))
# plot the probability 
plt_prob(ax, w_out, b_out)# Plot the original data
ax.set_ylabel(r'$x_1$')
ax.set_xlabel(r'$x_0$')   
ax.axis([0, 4, 0, 3.5])
plot_data(X_train,y_train,ax)# Plot the decision boundary
x0 = -b_out/w_out[1]
x1 = -b_out/w_out[0]
ax.plot([0,x0],[x1,0], c=dlc["dlblue"], lw=1)
plt.show()

绘制结果:
在这里插入图片描述
在上面的图中:

  • 着色反映了概率y=1(在决策边界之前的结果)
  • 决策边界是概率等于0.5的线

2.7 另一个数据集

让我们回到一个一变量数据集。只有两个参数,𝑤和𝑏,我们可以在等高线图中绘制成本函数,以更好地了解梯度下降在做什么。

x_train = np.array([0., 1, 2, 3, 4, 5])
y_train = np.array([0,  0, 0, 1, 1, 1])

我们将使用一个辅助函数来绘制这些数据。标签为𝑦=1的数据点用红色十字表示,而标签为𝑦=0的数据点用蓝色圆圈表示

fig,ax = plt.subplots(1,1,figsize=(4,3))
plt_tumor_data(x_train, y_train, ax)
plt.show()

绘制结果:
在这里插入图片描述

在下面的图中,尝试:

  • 通过点击上右角的等高线图来更改𝑤和𝑏
    – 更改可能需要一秒钟或两秒钟
    – 注意上左图中的成本值的变化
    – 注意成本是通过每个示例的损失累积的(垂直虚线)
  • 通过点击橙色按钮运行梯度下降
    – 注意成本稳步下降(等高线和成本图以对数成本显示)
    – 在等高线图中点击将重置模型以进行新的运行
    – 要重置图表,重新运行此单元格
w_range = np.array([-1, 7])
b_range = np.array([1, -14])
quad = plt_quad_logistic( x_train, y_train, w_range, b_range )

绘制结果:

  • 运行梯度下降前:
    在这里插入图片描述
  • 运行梯度下降后:
    在这里插入图片描述

2.8 总结

  • 检查了逻辑回归的梯度计算公式和实现,在这些例行程序中进行了探索一变量数据集、两变量数据集
  • 更新逻辑回归的梯度下降算法
  • 在一个熟悉的数据集上探索梯度下降

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 26.9 Django书籍管理练习
  • vue实现简易的全局加载动画效果
  • 2.回文数
  • Python使用内置logging模块打印日志
  • 主动学习实现领域自适应语义分割
  • 某次活动优惠券故障复盘及优化建议
  • JVM生态创新
  • Redis 数据结构深度解析:跳跃表(Skiplist)
  • vscode安装与配置本地c/c++编译调试环境
  • 详解Xilinx FPGA高速串行收发器GTX/GTP(2)--什么是GTX?
  • 【传知代码】LAD-GNN标签注意蒸馏(论文复现)
  • 研究表明产品越强调AI越招人们反感:降低情感信任 减少购买意愿
  • sftp做成一个池子
  • 区块链如何助力数字版权保护和内容创作者的权益?
  • linux nicstat
  • 【vuex入门系列02】mutation接收单个参数和多个参数
  • 3.7、@ResponseBody 和 @RestController
  • - C#编程大幅提高OUTLOOK的邮件搜索能力!
  • CEF与代理
  • Computed property XXX was assigned to but it has no setter
  • extjs4学习之配置
  • HashMap剖析之内部结构
  • Hibernate【inverse和cascade属性】知识要点
  • JavaScript 是如何工作的:WebRTC 和对等网络的机制!
  • JavaScript标准库系列——Math对象和Date对象(二)
  • Kibana配置logstash,报表一体化
  • RxJS 实现摩斯密码(Morse) 【内附脑图】
  • 包装类对象
  • 初探 Vue 生命周期和钩子函数
  • 从0实现一个tiny react(三)生命周期
  • 老板让我十分钟上手nx-admin
  • 前端_面试
  • 人脸识别最新开发经验demo
  • 用Python写一份独特的元宵节祝福
  • Oracle Portal 11g Diagnostics using Remote Diagnostic Agent (RDA) [ID 1059805.
  • 不要一棍子打翻所有黑盒模型,其实可以让它们发挥作用 ...
  • ​LeetCode解法汇总2808. 使循环数组所有元素相等的最少秒数
  • ​软考-高级-信息系统项目管理师教程 第四版【第23章-组织通用管理-思维导图】​
  • "无招胜有招"nbsp;史上最全的互…
  • # .NET Framework中使用命名管道进行进程间通信
  • # 数论-逆元
  • #162 (Div. 2)
  • #Js篇:单线程模式同步任务异步任务任务队列事件循环setTimeout() setInterval()
  • #window11设置系统变量#
  • $GOPATH/go.mod exists but should not goland
  • (Forward) Music Player: From UI Proposal to Code
  • (第二周)效能测试
  • (附源码)springboot高校宿舍交电费系统 毕业设计031552
  • (回溯) LeetCode 40. 组合总和II
  • (回溯) LeetCode 78. 子集
  • (三)elasticsearch 源码之启动流程分析
  • (十一)c52学习之旅-动态数码管
  • (图文详解)小程序AppID申请以及在Hbuilderx中运行
  • (一)、软硬件全开源智能手表,与手机互联,标配多表盘,功能丰富(ZSWatch-Zephyr)
  • (一)python发送HTTP 请求的两种方式(get和post )