【算法】梯度下降

news2024/12/23 15:11:47

一、引言

        梯度下降算法(Gradient Descent)是一种一阶迭代优化算法,用于求解最小化目标函数的问题,广泛应用于机器学习和人工智能中的参数优化。

         用于优化问题的迭代算法,尤其在机器学习和深度学习中广泛用于最小化损失函数,以找到模型参数的最佳值。其基本思想是根据当前参数的梯度(即损失函数相对于参数的导数)逐步更新参数,从而使损失函数值逐渐减小。

二、算法原理

        梯度下降算法的核心原理是利用负梯度方向作为搜索方向,因为在多元函数的某一点处,函数值沿着负梯度方向下降最快。算法步骤包括:

        选择初始点:在函数定义域内任选一个初始点。

        计算梯度:在当前点计算目标函数的梯度(导数)。

        参数更新:根据梯度和一个预先设定的学习率来更新参数。

        迭代:重复步骤2和3,直到满足停止条件。

三、数据结构

梯度下降算法中涉及的数据结构主要包括:

  • 参数向量:存储模型参数的向量。
  • 梯度向量:存储目标函数关于参数的导数的向量。

四、算法使用场景

梯度下降算法适用于以下场景:

  • 机器学习:在训练过程中优化模型参数。
  • 深度学习:用于神经网络的权重调整。
  • 经济学:求解资源分配问题。
  • 线性回归:用于拟合线性模型,并通过最小化均方误差(MSE)来找到最佳参数。
  • 逻辑回归:用于分类任务,通过最小化交叉熵损失来优化模型。

  • 神经网络:用于复杂模型的训练,通过反向传播和梯度下降优化网络的权重。

五、算法实现

Python实现的简单梯度下降算法示例:

python

def gradient_descent(gradient_func, start_point, learning_rate, epochs):
    parameters = start_point
    for _ in range(epochs):
        grad = gradient_func(parameters)
        parameters -= learning_rate * grad
    return parameters

# 假设的目标函数和梯度函数
def objective_function(w):
    return w**2 + 10 * w + 20

def gradient(w):
    return 2 * w + 10

# 初始参数,学习率,迭代次数
start_point = 20
learning_rate = 0.1
epochs = 10

# 执行梯度下降
optimal_params = gradient_descent(gradient, start_point, learning_rate, epochs)
print(f"Optimal parameters: {optimal_params}")

六、其他同类算法对比

与梯度下降算法相比,其他优化算法包括:

  • 牛顿法:使用二阶导数(Hessian矩阵)来寻找最优点,收敛速度快但计算复杂。
  • 随机梯度下降(SGD):每次迭代使用一个样本的梯度来更新参数,适合大数据集。由于其更新频繁且噪声较大,可能导致收敛不稳定,但在实践中能加速收敛。

  • 批量梯度下降(Batch Gradient Descent):使用所有训练数据来计算梯度,收敛稳定但可能较慢,特别是在数据集非常大时,因为每次迭代都需要计算整个数据集的梯度。

  • 小批量梯度下降(Mini-batch Gradient Descent):结合了批量梯度下降和随机梯度下降的优点。将数据集分成小批量,每次迭代使用一个小批量来计算梯度。这种方法在稳定性和效率之间取得了平衡。

  • 动量法(Momentum):在梯度下降中引入了过去梯度的加权平均,以加速收敛并减少震荡。公式中引入了动量项,使得更新不仅依赖当前梯度,还依赖于之前的更新方向。

  • 自适应学习率方法(如AdaGrad, RMSprop, Adam)

    • AdaGrad:根据每个参数的历史梯度的平方和调整学习率,适合稀疏数据。
    • RMSprop:对梯度平方的移动平均进行平滑,以调整学习率,能够处理非平稳目标。
    • Adam:结合了动量法和RMSprop的优点,使用动量和学习率的自适应调整,以加速收敛和提高鲁棒性。

七、多语言实现

使用Java、C++和Go语言实现的梯度下降算法的简单示例:

Java

import org.apache.commons.math3.linear.*;

public class GradientDescent {

    public static RealVector gradientDescent(RealMatrix X, RealVector y, RealVector theta, double learningRate, int iterations) {
        int m = y.getDimension();
        RealVector costHistory = new ArrayRealVector(iterations);
        
        for (int i = 0; i < iterations; i++) {
            RealVector predictions = X.operate(theta);
            RealVector errors = predictions.subtract(y);
            RealVector gradients = X.transpose().operate(errors).mapDivide(m);
            theta = theta.subtract(gradients.mapMultiply(learningRate));
            double cost = computeCost(X, y, theta);
            costHistory.setEntry(i, cost);
        }

        return theta;
    }

    public static double computeCost(RealMatrix X, RealVector y, RealVector theta) {
        RealVector predictions = X.operate(theta);
        RealVector errors = predictions.subtract(y);
        double cost = errors.dotProduct(errors) / (2 * y.getDimension());
        return cost;
    }

    public static void main(String[] args) {
        // Sample data
        double[][] data = {{1, 1}, {1, 2}, {1, 3}};
        double[] labels = {1, 2, 3};
        RealMatrix X = MatrixUtils.createRealMatrix(data);
        RealVector y = new ArrayRealVector(labels);
        RealVector theta = new ArrayRealVector(new double[]{0.1, 0.2});
        double learningRate = 0.01;
        int iterations = 1000;

        RealVector optimizedTheta = gradientDescent(X, y, theta, learningRate, iterations);
        System.out.println("Optimized Theta: " + optimizedTheta);
    }
}

C++

#include <iostream>
#include <Eigen/Dense>

using namespace Eigen;

double computeCost(const MatrixXd& X, const VectorXd& y, const VectorXd& theta) {
    int m = y.size();
    VectorXd predictions = X * theta;
    VectorXd error = predictions - y;
    double cost = (1.0 / (2 * m)) * error.dot(error);
    return cost;
}

VectorXd gradientDescent(const MatrixXd& X, const VectorXd& y, VectorXd theta, double learningRate, int iterations) {
    int m = y.size();
    VectorXd costHistory(iterations);

    for (int i = 0; i < iterations; ++i) {
        VectorXd predictions = X * theta;
        VectorXd error = predictions - y;
        VectorXd gradients = (1.0 / m) * X.transpose() * error;
        theta -= learningRate * gradients;
        costHistory(i) = computeCost(X, y, theta);
    }

    return theta;
}

int main() {
    // Sample data
    MatrixXd X(3, 2);
    X << 1, 1, 1, 2, 1, 3;
    VectorXd y(3);
    y << 1, 2, 3;
    VectorXd theta(2);
    theta << 0.1, 0.2;
    double learningRate = 0.01;
    int iterations = 1000;

    VectorXd optimizedTheta = gradientDescent(X, y, theta, learningRate, iterations);
    std::cout << "Optimized Theta:\n" << optimizedTheta << std::endl;

    return 0;
}

Go

package main

import (
	"fmt"
	"gonum.org/v1/gonum/mat"
)

// Compute Cost Function
func computeCost(X, y *mat.Dense, theta *mat.VecDense) float64 {
	m, _ := X.Dims()
	predictions := mat.NewVecDense(m, nil)
	predictions.MulVec(X, theta)
	error := mat.NewVecDense(m, nil)
	error.SubVec(predictions, y)
	cost := mat.Dot(error, error) / (2 * float64(m))
	return cost
}

// Gradient Descent
func gradientDescent(X, y *mat.Dense, theta *mat.VecDense, learningRate float64, iterations int) (*mat.VecDense, []float64) {
	m, _ := X.Dims()
	costHistory := make([]float64, iterations)

	for i := 0; i < iterations; i++ {
		predictions := mat.NewVecDense(m, nil)
		predictions.MulVec(X, theta)
		error := mat.NewVecDense(m, nil)
		error.SubVec(predictions, y)
		gradients := mat.NewVecDense(X.Caps().Cols, nil)
		gradients.MulVec(X.T(), error)
		gradients.Scale(1/float64(m), gradients)
		theta.SubVec(theta, gradients.Scale(learningRate, gradients))
		costHistory[i] = computeCost(X, y, theta)
	}

	return theta, costHistory
}

func main() {
	// Sample data
	X := mat.NewDense(3, 2, []float64{1, 1, 1, 2, 1, 3})
	y := mat.NewVecDense(3, []float64{1, 2, 3})
	theta := mat.NewVecDense(2, []float64{0.1, 0.2})
	learningRate := 0.01
	iterations := 1000

	optimizedTheta, costHistory := gradientDescent(X, y, theta, learningRate, iterations)
	fmt.Println("Optimized Theta:\n", optimizedTheta)
	fmt.Println("Final Cost:", costHistory[iterations-1])
}

 八、实际的服务应用场景代码框架

        示例代码框架,演示如何使用实现的线性回归模型在 Flask(Python)中构建一个简单的服务。
Python Flask 应用

from flask import Flask, request, jsonify
import numpy as np

app = Flask(__name__)

class LinearRegression:
def __init__(self, learning_rate=0.01, n_iterations=1000):
self.learning_rate = learning_rate
self.n_iterations = n_iterations
self.weights = None
self.bias = None

def fit(self, X, y):
n_samples, n_features = X.shape
self.weights = np.zeros(n_features)
self.bias = 0

for _ in range(self.n_iterations):
y_predicted = np.dot(X, self.weights) + self.bias
dw = (1 / n_samples) * np.dot(X.T, (y_predicted - y))
db = (1 / n_samples) * np.sum(y_predicted - y)

self.weights -= self.learning_rate * dw
self.bias -= self.learning_rate * db

def predict(self, X):
return np.dot(X, self.weights) + self.bias


# 创建模型实例
model = LinearRegression()

@app.route('/train', methods=['POST'])
def train():
data = request.json
X = np.array(data['X'])
y = np.array(data['y'])
model.fit(X, y)
return jsonify({'message': 'Model trained successfully'}), 200

@app.route('/predict', methods=['POST'])
def predict():
data = request.json
X = np.array(data['X'])
predictions = model.predict(X).tolist()
return jsonify({'predictions': predictions}), 200

if __name__ == '__main__':
app.run(debug=True)


        安装 Flask:pip install Flask
        运行 Flask 应用:python app.py
        发送训练请求:curl -X POST http://127.0.0.1:5000/train -H "Content-Type: application/json" -d '{"X": [[1], [2], [3]], "y": [2, 3, 4]}'
        发送预测请求:curl -X POST http://127.0.0.1:5000/predict -H "Content-Type: application/json" -d '{"X": [[4], [5]]}'
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2036572.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

EMQX Platform Snowflake:构建可再生分布式能源的智慧未来

引言 可再生能源如风力和太阳能发电&#xff0c;具有低成本和环保的特性&#xff0c;是未来能源供应的主要方向。然而&#xff0c;这类发电方式存在供应分散、设备数量多、地区分布广等特点。再加上不同地区的季节和天气变化&#xff0c;不确定性极大。 随着社会用电需求的持…

11 Radiobutton组件

11 Radiobutton组件 Tkinter 是 Python 的标准图形用户界面库&#xff0c;它提供了一个 Radiobutton 控件&#xff0c;用于在一组选项中让用户选择一个选项。Radiobutton 通常用于提供一组互斥的选项&#xff0c;用户只能选择其中一个。 Radiobutton 组件基础 Radiobutton 控…

CMake详解-捡重要的讲

CMake 通常我们使用cmake构建C++项目,其实就是编写CMakeLists.txt文件,过程如下 首先在创建项目名称,我这里是CMake文件夹,在路径下创建CMakeLists.txt文件,也就是在工作空间的目录下创建,具体有几个要素要设置 CMake最低版本要求项目名称-自定义即可编译方法:Debug或…

html+css+js网页制作 自定义电商10个页面

htmlcssjs网页制作 自定义电商10个页面 网页作品代码简单&#xff0c;可使用任意HTML编辑软件&#xff08;如&#xff1a;Dreamweaver、HBuilder、Vscode 、Sublime 、Webstorm、Text 、Notepad 等任意html编辑软件进行运行及修改编辑等操作&#xff09;。 获取源码 1&#…

前端面试题整理-Javascript

JS组成&#xff1a; JS是运行在浏览器的一门编程语言 函数类型&#xff1a; 1. 说说 js 都有哪些数据类型&#xff0c;他们在内存存储上有什么不同 基本数据类型&#xff1a;number、boolean、string、null&#xff08;null就是特殊的object&#xff09;、undefined、Symbo…

循环神经网络三

一.介绍 在普通的神经网络中&#xff0c;信息的传递是单向的&#xff0c;这种限制虽然使得网络变得更容易学习&#xff0c;单在一定程度上也减弱了神经网络模型的能力。特别是在现实生活中&#xff0c;网络的输出不仅和当前时刻的输入相关&#xff0c;也过去一段时间的输出相关…

keepalived搭建与基础配置

目录 1 keepalived部署与环境准备 1.1 Keepalived 实验环境准备 1.2 Keepalived 相关文件 1.3 Keepalived 安装 1.4 KeepAlived 配置说明 1.5 配置语法说明 2 企业应用示例与配置 2.1 主从架构 2.1.1 启用keepalived日志功能 2.1.2 vrrp_iptables 参数 2.1.3 实现独立子配置文件…

python实现模型训练期间定时查询解析GPU资源详细信息,根据实际显存占用量动态启动新模型训练任务

经常要做模型开发训练的人一定对于GPU的查询不会陌生&#xff0c;实例如下&#xff1a; 详情数据如下&#xff1a; Tue Aug 13 16:42:31 2024 ----------------------------------------------------------------------------- | NVIDIA-SMI 450.80.02 Driver Versi…

oracle普通导出导入

原始的普通导出导入工具&#xff0c;是一个客户端工具。使用导出工具&#xff08;export utility简称exp&#xff09;是将数据从oracle数据库以二进制形式写入操作系统文件&#xff0c;这个文件存储在数据库之外&#xff0c;并且可以被另一个数据库使用导入工具&#xff08;imp…

大数据系列之:Flink Doris Connector,实时同步数据到Doris数据库

大数据系列之&#xff1a;Flink Doris Connector&#xff0c;实时同步数据到Doris数据库 一、版本兼容性二、使用三、Flink SQL四、DataStream五、Lookup Join六、配置通用配置项接收器配置项查找Join配置项 七、Doris 和 Flink 列类型映射八、使用Flink CDC访问Doris的示例九、…

Unity协程WaitForSeconds在编辑器和WebGL表现不同问题的解决方法参考

最近做的一个效果让下面为了让下面这种图片生成一个翻页效果&#xff08;使用ShaderGraph中的FlipBook节点&#xff09;&#xff0c;我通过携程来实现连续翻页。 先是定义一个Coroutine coroutine null&#xff1b; 然后在一定情况下执行coroutine StartCoroutine(KeepPrevie…

Spring入门讲解

这里写目录标题 Spring基础概念关键重点主要特性主要优势Spring与Java EE的对比Spring生态系统概述总结 Spring 基础概念 Spring是一个开源的轻量级Java开发框架&#xff0c;它提供了全面的基础设施支持&#xff0c;简化了企业级应用的开发和部署。Spring的核心理念是依赖注入…

基于华为atlas下的yolov5+BoT-SORT/ByteTrack煤矿箕斗状态识别大探索

写在前面&#xff1a; 本项目的代码原型基于yolov5yolov8。其中检测模型使用的yolov5&#xff0c;跟踪模型使用的yolov8。 这里说明以下&#xff0c;为什么不整体都选择yolov8呢&#xff0c;v8无疑是比v5优秀的&#xff0c;但是atlas这块经过不断尝试没有过去&#xff0c;所以…

前端进行分页Vue3+Setup写法

当后端不方便提供数据分页查询接口时&#xff0c;就需要前端来自己分割进行分页操作 在有可能的情况下还是建议用分页查询接口&#xff0c;减少网络数据传输 首先el-table绑定数组 分页组件&#xff0c;变量自己定义防止报错 <el-paginationlayout"->, total, siz…

Springboot实现doc,docx,xls,xlsx,ppt,pptx,pdf,txt,zip,rar,图片,视频,音频在线预览功能,你学“废”了吗?

最近工作中&#xff0c;客户需要生成包含动态内容的word/pdf报告&#xff0c;并且需要在线预览。 刚开始使用后台直接生成word文档&#xff0c;返回文件流给前端&#xff0c;浏览器预览会发生格式错乱问题&#xff0c;特别是文档中的图片有些还不显示。 想到最简单的办法就是…

在原生未启用kdump的BCLinux 8系列服务器上启用kdump及报错处理

本文记录了在原生未启用kdump的BCLinux 8系列操作系统的服务器上手动启用kdump服务及报错处理的过程。 一、问题描述 BCLinux 8系列操作系统&#xff0c;系统初始化安装时未启用kdump服务&#xff0c;手动启动时报以下“No memory reserved for crash kernel”或“ConditionK…

数学建模——评价决策类算法(层次分析法、Topsis)

一、层次分析法 概念原理 通过相互比较确定各准则对于目标的权重, 及各方案对于每一准则的权重&#xff0c;这些权重在人的思维过程中通常是定性的, 而在层次分析法中则要给出得到权重的定量方法. 将方案层对准则层的权重及准则层对目标层的权重进行综合, 最终确定方案层对目标…

解读RPA自动化流程机器人

RPA全称Robotic Process Automation&#xff0c;即机器人流程自动化&#xff0c;基于人工智能和自动化技术&#xff0c;能够将大量重复、规则明确的日常事务操作实现自动化处理&#xff0c;通常被形象地称为“数字员工”。本文金智维将深入探讨RPA的主要价值和应用领域&#xf…

除悟空CRM外,主流的6大CRM私有部署的厂商

支持私有化部署的CRM有&#xff1a;1.纷享销客&#xff1b; 2.悟空CRM&#xff1b; 3.销售易&#xff1b; 4.有赞CRM&#xff1b; 5.知客CRM&#xff1b; 6.八骏CRM&#xff1b; 7.白码CRM。 面对日益复杂的网络环境和严峻的数据保护法规&#xff0c;私有化部署的CRM系统成为了…

论文阅读笔记:Semi-DETR: Semi-Supervised Object Detection with Detection Transformers

论文阅读笔记&#xff1a;Semi-DETR: Semi-Supervised Object Detection with Detection Transformers 1 背景1.1 动机1.2 问题 2 创新点3 方法4 模块4.1 分阶段混合匹配4.2 跨视图查询一致性4.3 基于代价的伪标签挖掘4.4 总损失 效果5.1 和SOTA方法对比5.2 消融实验 论文&…