Python实战:3种梯度下降算法对比(附完整代码与可视化分析)

# Python实战:三大梯度下降算法深度对比与可视化调优指南 如果你刚开始接触机器学习,面对一堆复杂的优化算法,可能会感到无从下手。我记得自己第一次跑线性回归时,看着损失函数曲线上下跳动,完全不明白为什么模型就是“学不会”。后来才发现,问题的核心往往不在模型本身,而在于背后那个默默工作的**优化器**——梯度下降。它就像一位导航员,指引着模型参数穿越复杂的高维地形,寻找损失最低的那个山谷。但这位导航员也有不同的“工作风格”:有的稳健但缓慢,有的敏捷却毛躁,还有的试图在两者之间找到平衡。今天,我们就用Python作为显微镜,深入观察**批量梯度下降(BGD)、随机梯度下降(SGD)和小批量梯度下降(MBGD)** 这三位导航员在实际任务中的表现。 本文面向的是已经了解机器学习基础,但希望深入优化过程细节的Python开发者。我们将不满足于简单的公式罗列,而是通过完整的代码实现、动态可视化,并结合真实数据集,直观对比三种算法在**收敛速度、参数更新轨迹和最终精度**上的差异。更重要的是,我们会聚焦于实际调参中的核心痛点:**学习率如何选择?遇到震荡怎么办?批量大小如何影响训练?** 文章附带的Jupyter Notebook模板,你可以直接套用到自己的项目中,快速进行算法对比实验。 ## 1. 优化算法的核心:梯度下降为何是基石 在深入对比之前,我们有必要统一认识:为什么梯度下降如此重要?在机器学习中,我们绝大多数时候都在解决一个优化问题——寻找一组模型参数,使得某个定义好的损失函数的值最小。对于简单的线性模型,或许可以直接求解正规方程。但当模型变成深度神经网络,参数动辄百万甚至上亿,直接求解变得不可能。这时,迭代优化算法就成了唯一可行的路径。 梯度下降提供了这条路径上最直观的方向:沿着函数值下降最快的方向(负梯度方向)前进。用爬山的比喻来说,你不是在山上随机乱走,而是每次都用脚感受一下最陡的下坡方向,然后迈出一步。这个“感受”就是计算梯度,“迈步”的大小就是学习率。 > 注意:梯度下降找到的通常是“局部最优解”。但在许多机器学习问题中,尤其是使用特定损失函数(如凸函数)时,局部最优就是全局最优。对于非凸问题(如神经网络),业界的研究和实践表明,找到“足够好”的局部最优解通常也能获得优异的性能。 三种梯度下降变体的根本区别,在于它们每次“感受”坡度(计算梯度)时所依据的“信息量”不同: * **批量梯度下降(BGD)**:非常严谨。每次更新前,它要看完整个训练集(所有样本),计算一个非常准确的平均梯度。步子稳,但速度慢。 * **随机梯度下降(SGD)**:非常激进。每次随机只看一个样本,用这个样本的梯度来代表整体。更新极快,但方向噪声很大,路线曲折。 * **小批量梯度下降(MBGD)**:折中派。每次只看一个小批量(比如32、64个样本)的数据。它试图在BGD的稳定性和SGD的速度之间取得平衡,是目前深度学习中最主流的选择。 为了在代码中清晰地体现这种区别,我们先来搭建一个统一的实验环境。 ## 2. 实验环境搭建与数据准备 任何有意义的对比都需要在相同的起跑线上进行。我们首先构造一个可控的线性回归问题,并准备好可视化工具。 ```python import numpy as np import matplotlib.pyplot as plt from matplotlib.animation import FuncAnimation from sklearn.datasets import make_regression from sklearn.preprocessing import StandardScaler import warnings warnings.filterwarnings('ignore') # 1. 生成模拟数据 np.random.seed(42) # 确保结果可复现 X, y = make_regression(n_samples=1000, n_features=2, noise=10.0, random_state=42) # 为参数w添加截距项对应的特征列(全为1) X_b = np.c_[np.ones((X.shape[0], 1)), X] # 形状变为 (1000, 3) # 2. 数据标准化(非常重要,能加速梯度下降收敛) scaler = StandardScaler() X_b[:, 1:] = scaler.fit_transform(X_b[:, 1:]) y = scaler.fit_transform(y.reshape(-1, 1)).flatten() # 3. 定义损失函数(均方误差MSE)和其梯度 def compute_mse_loss(X, y, theta): """计算均方误差损失""" m = len(y) predictions = X.dot(theta) loss = (1/(2*m)) * np.sum((predictions - y) ** 2) return loss def compute_gradient(X, y, theta): """计算损失函数关于参数theta的梯度""" m = len(y) gradient = (1/m) * X.T.dot(X.dot(theta) - y) return gradient ``` 我们生成了1000个样本,每个样本有2个特征。`X_b` 是添加了截距项后的特征矩阵。数据标准化是**关键预处理步骤**,它能确保不同特征的尺度相近,让梯度下降的路径更笔直,收敛更快。损失函数采用经典的均方误差(MSE),其梯度有简洁的解析形式。 接下来,我们初始化参数和记录器,为三种算法的运行做准备。 ```python # 4. 初始化参数和记录器 initial_theta = np.random.randn(X_b.shape[1]) # 随机初始化参数,形状(3,) learning_rate = 0.1 # 初始学习率,后续会调整 n_iterations = 200 # 总迭代次数 # 用于记录三种算法训练过程的容器 history = { 'BGD': {'theta': [initial_theta.copy()], 'loss': []}, 'SGD': {'theta': [initial_theta.copy()], 'loss': []}, 'MBGD': {'theta': [initial_theta.copy()], 'loss': []} } ``` ## 3. 算法实现与核心代码剖析 现在,让我们分别实现三位“主角”。你会看到,核心的梯度更新公式 `theta = theta - learning_rate * gradient` 是相同的,但 `gradient` 的计算方式截然不同。 ### 3.1 批量梯度下降(BGD):稳健的全局观察者 BGD在每次迭代中都会使用全部训练数据。这保证了每次更新的方向都是当前参数下,整个数据集平均意义上的最速下降方向。 ```python def batch_gradient_descent(X, y, theta, learning_rate, n_iterations, history_key='BGD'): theta_current = theta.copy() m = len(y) for i in range(n_iterations): # 核心:使用全部数据计算梯度 gradient = compute_gradient(X, y, theta_current) theta_current = theta_current - learning_rate * gradient # 记录历史 history[history_key]['theta'].append(theta_current.copy()) loss = compute_mse_loss(X, y, theta_current) history[history_key]['loss'].append(loss) # 简单打印进度 if i % 40 == 0: print(f"{history_key} - Iteration {i}: Loss = {loss:.6f}") return theta_current # 运行BGD print("开始批量梯度下降(BGD)训练...") theta_bgd = batch_gradient_descent(X_b, y, initial_theta, learning_rate, n_iterations, 'BGD') ``` **BGD的特点分析:** * **优点**:更新方向稳定,收敛路径平滑,对于凸函数能保证收敛到全局最优。 * **缺点**:每次迭代的计算开销与训练集大小成正比。当数据量极大(例如数千万样本)时,一次迭代的计算成本高得无法接受,内存也可能无法承载整个数据集。 * **适用场景**:数据集规模不大(通常内存能装下),且对收敛的稳定性要求极高的场景。 ### 3.2 随机梯度下降(SGD):敏捷的局部探索者 SGD走向另一个极端。每次迭代只随机抽取一个样本计算梯度并更新。这带来了巨大的速度优势和逃离局部极小值的可能,但也引入了显著的噪声。 ```python def stochastic_gradient_descent(X, y, theta, learning_rate, n_iterations, history_key='SGD'): theta_current = theta.copy() m = len(y) for i in range(n_iterations): # 核心:随机选取一个样本的索引 random_index = np.random.randint(m) xi = X[random_index:random_index+1] # 保持二维结构,便于计算 yi = y[random_index:random_index+1] # 计算单个样本的梯度 gradient = xi.T.dot(xi.dot(theta_current) - yi) # 注意这里没有 1/m theta_current = theta_current - learning_rate * gradient # 记录历史(为了公平对比,我们仍然计算在整个训练集上的损失) history[history_key]['theta'].append(theta_current.copy()) loss = compute_mse_loss(X, y, theta_current) history[history_key]['loss'].append(loss) if i % 400 == 0: # SGD迭代快,减少打印频率 print(f"{history_key} - Iteration {i}: Loss = {loss:.6f}") return theta_current # 运行SGD,为了稳定,使用更小的学习率 print("\n开始随机梯度下降(SGD)训练...") theta_sgd = stochastic_gradient_descent(X_b, y, initial_theta, learning_rate=0.01, n_iterations=n_iterations*10, history_key='SGD') # SGD需要更多迭代 ``` **SGD的特点与调参要点:** * **震荡现象**:这是SGD最显著的特征。由于梯度估计噪声大,损失曲线和参数更新路径会剧烈震荡。这不一定全是坏事,震荡可能帮助算法跳出较差的局部最优。 * **学习率衰减**:由于噪声的存在,SGD通常无法像BGD那样精确收敛到最优点,而是在最优点附近徘徊。因此,**采用逐渐减小的学习率(学习率衰减)是标准实践**。例如,可以每若干轮迭代将学习率乘以一个衰减系数(如0.95)。 * **适用场景**:大规模在线学习、数据流式到达,或者当数据集太大无法一次性装入内存时。在深度学习中,其变体(如带动量的SGD)仍是基础优化器。 ### 3.3 小批量梯度下降(MBGD):平衡的实践家 MBGD是前两者的折中,它每次使用一个随机的小批量(Mini-batch)数据来计算梯度。这是深度学习框架(如TensorFlow, PyTorch)中默认的优化模式。 ```python def mini_batch_gradient_descent(X, y, theta, learning_rate, n_iterations, batch_size=32, history_key='MBGD'): theta_current = theta.copy() m = len(y) for i in range(n_iterations): # 核心:随机打乱数据并创建小批量 indices = np.random.permutation(m) X_shuffled = X[indices] y_shuffled = y[indices] for start in range(0, m, batch_size): end = start + batch_size xi = X_shuffled[start:end] yi = y_shuffled[start:end] if len(xi) == 0: continue gradient = compute_gradient(xi, yi, theta_current) theta_current = theta_current - learning_rate * gradient # 记录历史(一个epoch后记录一次) history[history_key]['theta'].append(theta_current.copy()) loss = compute_mse_loss(X, y, theta_current) history[history_key]['loss'].append(loss) if i % 20 == 0: print(f"{history_key} - Epoch {i}: Loss = {loss:.6f}") return theta_current # 运行MBGD print("\n开始小批量梯度下降(MBGD)训练...") theta_mbgd = mini_batch_gradient_descent(X_b, y, initial_theta, learning_rate, n_iterations, batch_size=64, history_key='MBGD') ``` **MBGD的关键参数:批量大小(Batch Size)** 批量大小是MBGD最重要的超参数之一,它直接影响训练的动态: * **小批量(如32, 64)**:更新频繁,收敛速度相对快,梯度估计有一定噪声,可能带来正则化效果,有助于泛化。 * **大批量(如512, 1024)**:梯度估计更准确,方向更稳定,每次迭代的计算更高效(利于GPU并行),但可能收敛到尖锐的极小点,泛化性能有时较差。 * **常见选择**:通常取2的幂次(32, 64, 128, 256),以适应GPU内存的边界。需要根据具体任务和硬件进行调优。 ## 4. 可视化对比与深度分析 代码跑完了,一堆数字可能还不够直观。让我们通过可视化,让三种算法的差异“跃然纸上”。我们将从三个维度进行对比:损失下降曲线、参数空间轨迹和动态训练过程。 ### 4.1 损失曲线对比:收敛速度与稳定性 损失曲线直接反映了模型“学习”的快慢和效果。 ```python # 绘制损失下降曲线对比图 plt.figure(figsize=(12, 5)) # 由于SGD迭代次数是其他的10倍,我们对其x轴进行压缩以对齐比较 iterations_bgd = range(len(history['BGD']['loss'])) iterations_sgd = np.linspace(0, len(history['BGD']['loss'])-1, len(history['SGD']['loss'])) iterations_mbgd = range(len(history['MBGD']['loss'])) plt.subplot(1, 2, 1) plt.plot(iterations_bgd, history['BGD']['loss'], 'b-', linewidth=2, label='BGD (Batch)') plt.plot(iterations_sgd, history['SGD']['loss'], 'r-', alpha=0.6, label='SGD (Stochastic)') plt.plot(iterations_mbgd, history['MBGD']['loss'], 'g-', linewidth=2, label='MBGD (Mini-batch=64)') plt.xlabel('Iteration / Epoch') plt.ylabel('Loss (MSE)') plt.title('Loss Convergence Comparison') plt.legend() plt.grid(True, alpha=0.3) # 绘制对数坐标下的损失曲线,更能看清后期的收敛差异 plt.subplot(1, 2, 2) plt.semilogy(iterations_bgd, history['BGD']['loss'], 'b-', linewidth=2, label='BGD') plt.semilogy(iterations_sgd, history['SGD']['loss'], 'r-', alpha=0.6, label='SGD') plt.semilogy(iterations_mbgd, history['MBGD']['loss'], 'g-', linewidth=2, label='MBGD') plt.xlabel('Iteration / Epoch') plt.ylabel('Loss (Log Scale)') plt.title('Loss Convergence (Log Scale)') plt.legend() plt.grid(True, alpha=0.3) plt.tight_layout() plt.show() ``` 通过损失曲线图,我们可以清晰地看到: 1. **BGD(蓝线)**:下降最平滑、最稳定,几乎没有震荡。但在后期,下降速度变得非常缓慢。 2. **SGD(红线)**:震荡极其剧烈,损失值大起大落。但仔细观察对数坐标图,会发现其**初期下降速度非常快**,在早期就能迅速接近最优区域。这正是SGD的优势所在——快速逼近。 3. **MBGD(绿线)**:轨迹介于两者之间。它比BGD下降得更快(尤其是在初期),又比SGD稳定得多。轻微的震荡可能有助于避免过拟合。 ### 4.2 参数空间轨迹:更新路径的直观展现 损失函数是参数的高维曲面。我们可以通过绘制两个主要参数(`w1`和`w2`,忽略截距)的更新轨迹,来观察算法在“山谷”中是如何行走的。 ```python # 提取参数轨迹 (我们取前两个权重参数 w1, w2) def get_param_trajectory(history_key, max_points=100): thetas = np.array(history[history_key]['theta']) # 为了清晰起见,对轨迹进行下采样 stride = max(1, len(thetas) // max_points) return thetas[::stride, 1], thetas[::stride, 2] # 获取 w1 和 w2 w1_bgd, w2_bgd = get_param_trajectory('BGD') w1_sgd, w2_sgd = get_param_trajectory('SGD') w1_mbgd, w2_mbgd = get_param_trajectory('MBGD') # 绘制等高线图及参数轨迹 # 首先计算损失函数的等高线网格 w1_range = np.linspace(-3, 3, 100) w2_range = np.linspace(-3, 3, 100) W1, W2 = np.meshgrid(w1_range, w2_range) loss_grid = np.zeros(W1.shape) for i in range(W1.shape[0]): for j in range(W2.shape[1]): theta_temp = np.array([0, W1[i, j], W2[i, j]]) # 假设截距为0 loss_grid[i, j] = compute_mse_loss(X_b, y, theta_temp) plt.figure(figsize=(10, 8)) contour = plt.contour(W1, W2, loss_grid, levels=30, cmap='viridis', alpha=0.6) plt.clabel(contour, inline=True, fontsize=8) plt.plot(w1_bgd, w2_bgd, 'bo-', markersize=3, linewidth=1.5, label='BGD Path', alpha=0.7) plt.plot(w1_sgd, w2_sgd, 'r.-', markersize=2, linewidth=0.5, label='SGD Path', alpha=0.5) plt.plot(w1_mbgd, w2_mbgd, 'gx-', markersize=4, linewidth=1, label='MBGD Path', alpha=0.8) plt.scatter([theta_bgd[1]], [theta_bgd[2]], c='blue', s=200, marker='*', edgecolors='black', label='BGD Final') plt.scatter([theta_sgd[1]], [theta_sgd[2]], c='red', s=150, marker='s', edgecolors='black', label='SGD Final') plt.scatter([theta_mbgd[1]], [theta_mbgd[2]], c='green', s=150, marker='^', edgecolors='black', label='MBGD Final') plt.xlabel('Weight w1') plt.ylabel('Weight w2') plt.title('Parameter Update Trajectories on Loss Contour') plt.legend() plt.colorbar(contour, label='Loss Value') plt.grid(True, alpha=0.3) plt.show() ``` 这张轨迹图信息量巨大: * **BGD路径(蓝色圆点线)**:是一条干净、笔直、平滑的路径,从起点几乎沿着最速下降方向径直走向最优点(蓝色五角星)。 * **SGD路径(红色点线)**:是一条混乱、曲折的“布朗运动”式路径。它在大方向上朝着最优点前进,但每一步都充满了随机性。最终停止点(红色方块)可能在最优点附近跳动。 * **MBGD路径(绿色X线)**:路径相对平滑,但有细微的锯齿。它比BGD的路径更“短”(因为每次更新方向更嘈杂,可能不是最优方向),但最终也能到达最优点附近(绿色三角)。 ### 4.3 学习率的影响与选择策略 学习率是梯度下降中**最重要**的超参数。它决定了每一步迈出的距离。让我们通过一个简单的实验来看看学习率如何影响BGD的收敛。 ```python # 测试不同学习率对BGD的影响 learning_rates = [0.001, 0.01, 0.1, 0.5, 1.0] loss_history_lr = {} for lr in learning_rates: theta_temp = initial_theta.copy() losses = [] for i in range(100): # 只迭代100次看初期表现 gradient = compute_gradient(X_b, y, theta_temp) theta_temp = theta_temp - lr * gradient losses.append(compute_mse_loss(X_b, y, theta_temp)) loss_history_lr[lr] = losses # 绘制不同学习率下的损失曲线 plt.figure(figsize=(12, 5)) for lr, losses in loss_history_lr.items(): plt.plot(losses, label=f'LR={lr}') plt.xlabel('Iteration') plt.ylabel('Loss') plt.title('Effect of Learning Rate on BGD Convergence') plt.legend() plt.grid(True, alpha=0.3) plt.yscale('log') # 使用对数坐标更清晰 plt.show() ``` 你会观察到典型的三种情况: 1. **学习率过小(如0.001)**:损失下降极其缓慢,需要非常多的迭代才能收敛,训练时间过长。 2. **学习率合适(如0.01, 0.1)**:损失平稳快速下降,是理想状态。 3. **学习率过大(如0.5, 1.0)**:损失在初期可能不降反升,或者剧烈震荡发散,算法完全失效。 **学习率选择实战技巧:** * **网格搜索/随机搜索**:在开发初期,可以在一个较大的范围(如 `[1e-5, 1]`)进行对数尺度上的搜索。 * **学习率衰减**:随着训练进行,逐渐减小学习率。常见策略有:按步衰减(每N轮减半)、指数衰减、余弦退火等。这能让模型在初期快速靠近最优解,后期精细调整。 * **自适应优化器**:在实践中,我们很少手动调学习率。使用 **Adam、RMSProp** 等自适应优化器是更主流的选择。它们能为每个参数自动调整学习率,对初始学习率的选择也不那么敏感。但理解基础梯度下降是理解这些高级优化器的前提。 ### 4.4 动态可视化:让训练过程“动”起来 最后,我们创建一个动态图,将参数轨迹和损失下降实时地展示出来。这能让你对优化过程有最直观的感受。(以下代码生成动画,在Jupyter中可直接运行) ```python # 动态可视化代码框架 (在Jupyter中运行) fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 6)) # 左图:参数空间轨迹 contour = ax1.contour(W1, W2, loss_grid, levels=20, cmap='viridis', alpha=0.5) ax1.set_xlabel('w1') ax1.set_ylabel('w2') ax1.set_title('Parameter Space Trajectory') ax1.grid(True, alpha=0.3) lines = [] for color, label in zip(['blue', 'red', 'green'], ['BGD', 'SGD', 'MBGD']): line, = ax1.plot([], [], 'o-', markersize=3, linewidth=1, label=label, color=color, alpha=0.7) lines.append(line) ax1.legend() # 右图:损失下降曲线 ax2.set_xlabel('Iteration') ax2.set_ylabel('Loss (Log Scale)') ax2.set_title('Loss Convergence') ax2.set_yscale('log') ax2.grid(True, alpha=0.3) loss_lines = [] for color, label in zip(['blue', 'red', 'green'], ['BGD', 'SGD', 'MBGD']): loss_line, = ax2.plot([], [], '-', linewidth=1.5, label=label, color=color, alpha=0.8) loss_lines.append(loss_line) ax2.legend() def init(): for line in lines: line.set_data([], []) for loss_line in loss_lines: loss_line.set_data([], []) return lines + loss_lines def update(frame): # 此函数会逐帧更新,从history中提取数据绘制 # 为简洁起见,这里省略具体数据索引逻辑,实际代码需根据history长度和帧数计算 # 核心是更新 lines[i].set_data(x_data[:frame], y_data[:frame]) # 以及 loss_lines[i].set_data(iter[:frame], loss[:frame]) return lines + loss_lines # 创建动画 # ani = FuncAnimation(fig, update, frames=total_frames, init_func=init, blit=True, interval=50) # 在Jupyter中显示 # from IPython.display import HTML # HTML(ani.to_jshtml()) ``` 运行这段动画代码,你将看到三个点(代表三种算法的当前参数)在损失函数的等高线图上移动,同时右侧的损失曲线同步绘制。BGD点稳步滑向中心,SGD点则像喝醉了一样东倒西歪但大方向正确,MBGD点则介于两者之间。这种动态展示比静态图更能加深你对算法行为的理解。 经过上述对比实验和可视化分析,一个清晰的图景出现了:没有“最好”的算法,只有“最适合”场景的算法。BGD的稳定、SGD的快速、MBGD的平衡,各有其用武之地。在实际的深度学习项目中,**小批量梯度下降(MBGD)配合自适应优化器(如Adam)** 已经成为默认的黄金标准。但这并不意味着你可以忽略BGD和SGD。理解它们是理解MBGD以及更复杂优化器(如带动量的SGD、AdaGrad、Adam)的基础。当你遇到模型训练震荡不止时,你会想起SGD的噪声;当你发现模型收敛极慢时,你会检查批量大小和学习率;当你需要绝对可重复的稳定结果时,BGD的思路依然有参考价值。把这些代码和实验方法保存下来,它们会成为你工具箱里评估新优化算法、调试模型训练过程的得力助手。

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

Python内容推荐

Logistic算法(随机梯度下降法)的Python代码和数据样本

Logistic算法(随机梯度下降法)的Python代码和数据样本

资源中包含随机梯度下降逻辑回归算法的Python代码和测试数据,python的版本为3.6,您运行代码前,将测试文件路径修改为您本地的存储路径,使用pycharm平台运行即可。

python梯度下降算法的实现

python梯度下降算法的实现

本文实例为大家分享了python实现梯度下降算法的具体代码,供大家参考,具体内容如下 简介 本文使用python实现了梯度下降算法,支持y = Wx+b的线性回归 目前支持批量梯度算法和随机梯度下降算法(bs=1) 也支持输入特征向量的x维度小于3的图像可视化 代码要求python版本>3.4 代码 ''' 梯度下降算法 Batch Gradient Descent Stochastic Gradient Descent SGD ''' __author__ = 'epleone' import numpy as np import matplotlib.pyplot as pl

python实现梯度下降算法

python实现梯度下降算法

梯度下降(Gradient Descent)算法是机器学习中使用非常广泛的优化算法。当前流行的机器学习库或者深度学习库都会包括梯度下降算法的不同变种实现。 本文主要以线性回归算法损失函数求极小值来说明如何使用梯度下降算法并给出python实现。若有不正确的地方,希望读者能指出。  梯度下降 梯度下降原理:将函数比作一座山,我们站在某个山坡上,往四周看,从哪个方向向下走一小步,能够下降的最快。 在线性回归算法中,损失函数为 在求极小值时,在数据量很小的时候,可以使用矩阵求逆的方式求最优的θ值。但当数据量和特征值非常大,例如几万甚至上亿时,使用矩阵求逆根本就不现实。而梯度下降法就是很好的一个选

基于jupyter notebook的python编程—–利用梯度下降算法求解多元线性回归方程,并与最小二乘法求解进行精度对比

基于jupyter notebook的python编程—–利用梯度下降算法求解多元线性回归方程,并与最小二乘法求解进行精度对比

基于jupyter notebook的python编程—–利用梯度下降算法求解多元线性回归方程,并与最小二乘法求解进行精度对比目录一、梯度下降算法的基本原理1、梯度下降算法的基本原理二、题目、表格数据、以及python环境搭建1、多元线性回归分析求解题目2、准备的多元线性回归方程的变量的表格数据3、搭建python环境三、梯度下降算法求解多元线性回归的方程的python代码实现1、导入基本库、数据,并为变量赋值2、定义系数初始值以及学习率和迭代次数3、定义最小二乘法函数-损失函数(代价函数)4、定义梯度下降算法求解线性回归方程系数python函数5、代用函数,进行系数求解,并打印6、画出回归方

python实现梯度下降算法的实例详解

python实现梯度下降算法的实例详解

在本篇文章里小编给大家整理的是一篇关于python实现梯度下降算法的实例详解内容,需要的朋友们可以参考下。

python应用Axes3D绘图(批量梯度下降算法)

python应用Axes3D绘图(批量梯度下降算法)

主要为大家详细介绍了python应用Axes3D绘图,批量梯度下降算法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

基于随机梯度下降的矩阵分解推荐算法(python)

基于随机梯度下降的矩阵分解推荐算法(python)

主要为大家详细介绍了基于随机梯度下降的矩阵分解推荐算法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

纯python3.5代码实现逻辑回归的二分类(附数据)

纯python3.5代码实现逻辑回归的二分类(附数据)

纯python代码实现逻辑回归,不调机器学习第三方库,仅调用numpy实现矩阵向量计算和matplotlib实现画图

Python实现多元线性回归方程梯度下降法与求函数极值

Python实现多元线性回归方程梯度下降法与求函数极值

梯度下降法 梯度下降法的基本思想可以类比为一个下山的过程。 假设这样一个场景:一个人被困在山上,需要从山上下来(找到山的最低点,也就是山谷)。但此时山上的浓雾很大,导致可视度很低;因此,下山的路径就无法确定,必须利用自己周围的信息一步一步地找到下山的路。这个时候,便可利用梯度下降算法来帮助自己下山。怎么做呢,首先以他当前的所处的位置为基准,寻找这个位置最陡峭的地方,然后朝着下降方向走一步,然后又继续以当前位置为基准,再找最陡峭的地方,再走直到最后到达最低处;同理上山也是如此,只是这时候就变成梯度上升算法了 梯度下降 梯度下降的基本过程就和下山的场景很类似。 首先,我们有一个可微分的函数。这个

梯度下降python实现

梯度下降python实现

梯度下降法是机器学习任务中最常用的优化方法,这里是其python实现

逻辑回归的Python实现,附源代码,数据集,结果图片

逻辑回归的Python实现,附源代码,数据集,结果图片

逻辑回归 python的简单实现,附加数据集,源代码,迭代结果图片 适合机器学习初学者,标注清晰,明确

Python编程实现线性回归和批量梯度下降法代码实例

Python编程实现线性回归和批量梯度下降法代码实例

主要介绍了Python编程实现线性回归和批量梯度下降法代码实例,具有一定借鉴价值,需要的朋友可以参考下

NNDL:使用python的梯度下降算法

NNDL:使用python的梯度下降算法

NNDL:使用python的梯度下降算法

机器学习的优化程序库,用Python实现了梯度下降、LBFGS、rmsprop、adadelta 等算法。

机器学习的优化程序库,用Python实现了梯度下降、LBFGS、rmsprop、adadelta 等算法。

机器学习的优化程序库,用Python实现了梯度下降、LBFGS、rmsprop、adadelta 等算法。

人工智能梯度下降算法python代码

人工智能梯度下降算法python代码

人工智能梯度下降算法python代码

各种梯度下降算法的代码(python)

各种梯度下降算法的代码(python)

各种梯度下降算法的代码

Python数据分析与机器学习实战课程

Python数据分析与机器学习实战课程

Python数据分析与机器学习实战课程,全套14.17G,仅有免密视频,课程目录: 01 人工智能入门指南 02 科学计算库-numpy 03 数据分析处理库-Pandas 04 可视化库-Matplotlib 05 机器学习入门算法实战-K近邻 06 线性回归算法 07 梯度下降与逻辑回归算法 08 项目实战:信用卡欺诈检测 09 决策树算法 10 随机森林与集成算法 11 项目实战-基于随机森林的气温预测 12 贝叶斯算法 13 项目实战-基于贝叶斯的新闻分类任务 14 无监督聚类-Kmeans算法 15 无监督聚类-DBSCAN算法 16 降维算法-PCA主成分分析 17 降维算法-线性判别分析 18 支持向量机SVM 19 Xgboost提升算法 20 项目实战-Xgboost调参实战 21 探索性数据分析-赛事数据集 22 时间序列ARIMA模型 23 时间序列实战

Python数据分析与机器学习-Python实现逻辑回归与梯度下降策略

Python数据分析与机器学习-Python实现逻辑回归与梯度下降策略

Python数据分析与机器学习-Python实现逻辑回归与梯度下降策略

机器学习案例实战:Python实现逻辑回归与梯度下降策略.zip

机器学习案例实战:Python实现逻辑回归与梯度下降策略.zip

机器学习

机器学习——梯度下降python实现

机器学习——梯度下降python实现

机器学习中经典的优化算法,让loss快速达到更小,本代码在minist数据集测试分类算法,取得很好的结果。

最新推荐最新推荐

recommend-type

python快速编写单行注释多行注释的方法

在python代码编写过程中,养成注释的习惯非常有用,可以让自己或别人后续在阅读代码时,轻松理解代码的含义。 如果只是简单的单行注释,可直接用“#”号开头,放于代码前面。 单行注释也可以跟代码同行,放在代码后面,以“#”号开头。 如果是多行注释,可在每行注释前面加“#”号。 多行注释,也可用3个双引号括起来。 多行注释,还可以用3个单引号括起来。 如需将现有的代码注释掉,可先选中需要注释的代码。 再按Ctrl + / ,这样选中的代码行前均会加上“#”号,表示该代码已经被注释掉了,不会再运行。 以上就是本次介绍的关于python如何快速编写单行注释多行注释的具体操作,感谢大家对软
recommend-type

Python中注释(多行注释和单行注释)的用法实例

前言 学会向程序中添加必要的注释,也是很重要的。注释不仅可以用来解释程序某些部分的作用和功能(用自然语言描述代码的功能),在必要时,还可以将代码临时移除,是调试程序的好帮手。 当然,添加注释的最大作用还是提高程序的可读性!很多时候,笔者宁愿自己写一个应用,也不愿意去改进别人的代码,没有合理的注释是一个重要原因。虽然良好的代码可自成文挡,但我们永远也不清楚今后读这段代码的人是谁,他是否和你有相同的思路。或者一段时间以后,你自己也不清楚当时写这段代码的目的了。 总的来说,一旦程序中注释掉某部分内容,则该内容将会被 Python 解释器忽略,换句话说,此部分内容将不会被执行。 通常而言,合理的代码
recommend-type

Pyhton中单行和多行注释的使用方法及规范

大家都知道python中的注释有多种,有单行注释,多行注释,批量注释,中文注释也是常用的。python注释也有自己的规范,这篇文章文章中会给大家详细介绍Pyhton中单行和多行注释的使用方法及规范,有需要朋友们可以参考借鉴。
recommend-type

Python中的单行、多行、中文注释方法

今天小编就为大家分享一篇Python中的单行、多行、中文注释方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
recommend-type

Perl中的单行注释和多行注释语法

主要介绍了Perl中的单行注释和多行注释语法,本文还同时讲解了其它常见编程语言的单行注释和多行注释语法,需要的朋友可以参考下
recommend-type

学生成绩管理系统C++课程设计与实践

资源摘要信息:"学生成绩信息管理系统-C++(1).doc" 1. 系统需求分析与设计 在进行学生成绩信息管理系统开发前,首先需要进行系统需求分析,这是确定系统开发目标与范围的过程。需求分析应包括数据需求和功能需求两个方面。 - 数据需求分析: - 学生成绩信息:需要收集学生的姓名、学号、课程成绩等数据。 - 数据类型和长度:明确每个数据项的数据类型(如字符串、整型等)和长度,例如学号可能是字符串类型且长度为一定值。 - 描述:详细描述每个数据项的意义,以确保系统能够准确处理。 - 功能需求分析: - 列出功能列表:用户界面应提供清晰的操作指引,列出所有可用功能。 - 查询学生成绩:系统应能通过学号或姓名查询学生的成绩信息。 - 增加学生成绩信息:允许用户添加未保存的学生成绩信息。 - 删除学生成绩信息:能够通过学号或姓名删除已经保存的成绩信息。 - 修改学生成绩信息:通过学号或姓名修改已有的成绩记录。 - 退出程序:提供安全退出程序的选项,并确保所有修改都已保存。 2. 系统设计 系统设计阶段主要完成内存数据结构设计、数据文件设计、代码设计、输入输出设计、用户界面设计和处理过程设计。 - 内存数据结构设计: - 使用链表结构组织内存中的数据,便于动态增删查改操作。 - 数据文件设计: - 选择文本文件存储数据,便于查看和编辑。 - 代码设计: - 根据功能需求,编写相应的函数和模块。 - 输入输出设计: - 设计简洁明了的输入输出提示信息和操作流程。 - 用户界面设计: - 用户界面应为字符界面,方便在命令行环境下使用。 - 处理过程设计: - 设计数据处理流程,确保每个操作都有明确的处理逻辑。 3. 系统实现与测试 实现阶段需要根据设计阶段的成果编写程序代码,并进行系统测试。 - 程序编写: - 完成系统设计中所有功能的程序代码编写。 - 系统测试: - 设计测试用例,通过测试用例上机测试系统。 - 记录测试方法和测试结果,确保系统稳定可靠。 4. 设计报告撰写 最后,根据系统开发的各个阶段,撰写详细的设计报告。 - 系统描述:包括问题说明、数据需求和功能需求。 - 系统设计:详细记录内存数据结构设计、数据文件设计、代码设计、输入/输出设计、用户界面设计、处理过程设计。 - 系统测试:包括测试用例描述、测试方法和测试结果。 - 设计特点、不足、收获和体会:反思整个开发过程,总结经验和教训。 时间安排: - 第19周(7月12日至7月16日)完成项目。 - 7月9日8:00到计算机学院实验中心(三楼)提交程序和课程设计报告。 指导教师和系主任(或责任教师)需要在文档上签名确认。 系统需求分析: - 使用表格记录系统需求分析的结果,包括数据项、数据类型、数据长度和描述。 - 分析数据项如学生成绩信息、状态器、链表节点等,确定其属性和行为。 以上就是文档中提到的学生成绩信息管理系统开发的关键知识点。开发此类系统需要熟练掌握C++编程基础,了解面向对象的程序设计思想,以及熟悉文件操作和链表等数据结构的应用。此外,良好的软件开发流程意识、测试意识和文档撰写能力也是必不可少的。
recommend-type

别再手动拖拽了!用Lumerical脚本批量创建FDTD仿真结构(附完整代码)

# 告别低效建模:Lumerical脚本自动化实战指南 在光子学仿真领域,时间就是科研生命线。当同行还在GUI界面里反复点击菜单时,你已经用脚本批量生成了20组参数化结构——这不是未来场景,而是每位FDTD用户都应该掌握的基础生产力革命。本文将彻底改变你与Lumerical的交互方式,从手动拖拽的农耕时代,跃迁到自动化建模的工业文明。 ## 1. 为何脚本建模是必然选择 2019年Nature Photonics的一项研究显示,科研工作者在仿真工具上平均浪费37%的时间在重复性操作上。对于需要参数扫描的纳米光学结构设计,这个数字可能更高。手动创建10个不同尺寸的纳米柱阵列意味着: -
recommend-type

Java邮件解析任务中,如何安全高效地提取HTML邮件内容并避免硬编码、资源泄漏和类型转换异常?

<think>我们被要求优化一段Java代码,该代码用于处理邮件(特别是来自特定发件人的构建通知邮件)。代码的主要问题包括: 1. 重复获取邮件内容:在检查MIME类型后,多次调用`msg[i].getContent()`,这可能导致性能问题或流关闭异常。 2. 类型转换问题:直接将邮件内容转换为`Multipart`而不进行类型检查,可能引发`ClassCastException`。 3. 代码结构问题:逻辑嵌套过深,可读性差,且存在重复代码(如插入邮件详情的操作在两个地方都有)。 4. 硬编码和魔法值:例如在解析HTML表格时使用了硬编码的索引(如list3.get(10)),这容易因邮件
recommend-type

RH公司应收账款管理优化策略研究

资源摘要信息:"本文针对RH公司的应收账款管理问题进行了深入研究,并提出了改进策略。文章首先分析了应收账款在企业管理中的重要性,指出其对于提高企业竞争力、扩大销售和充分利用生产能力的作用。然后,以RH公司为例,探讨了公司应收账款管理的现状,并识别出合同管理、客户信用调查等方面的不足。在此基础上,文章提出了一系列改善措施,包括完善信用政策、改进业务流程、加强信用调查和提高账款回收力度。特别强调了建立专门的应收账款回收部门和流程的重要性,并建议在实际应用过程中进行持续优化。同时,文章也意识到企业面临复杂多变的内外部环境,因此提出的策略需要根据具体情况调整和优化。 针对财务管理领域的专业学生和从业者,本文提供了一个关于应收账款管理问题的案例研究,具有实际指导意义。文章还探讨了信用管理和征信体系在应收账款管理中的作用,强调了它们对于提升企业信用风险控制和市场竞争能力的重要性。通过对比国内外企业在应收账款管理上的差异,文章总结了适合中国企业实际环境的应收账款管理方法和策略。" 根据提供的文件内容,以下是详细的知识点: 1. 应收账款管理的重要性:应收账款作为企业的一项重要资产,其有效管理关系到企业的现金流、财务健康以及市场竞争力。不良的应收账款管理会导致资金链断裂、坏账损失增加等问题,严重影响企业的正常运营和长远发展。 2. 应收账款的信用风险:在信用交易日益频繁的商业环境中,企业必须对客户信用进行评估,以便采取合理的信用政策,降低信用风险。 3. 合同管理的薄弱环节:合同是应收账款管理的法律基础,严格的合同管理能够保障企业权益,减少因合同问题导致的应收账款风险。 4. 客户信用调查:了解客户的信用状况对于预测和控制应收账款风险至关重要。企业需要建立有效的客户信用调查机制,识别和筛选信用良好的客户。 5. 应收账款回收策略:企业应建立有效的账款回收机制,包括定期的账款跟进、逾期账款的催收等。同时,建立专门的应收账款回收部门可以提升回收效率。 6. 应收账款管理流程优化:通过改进企业内部管理流程,如简化审批流程、提高工作效率等措施,能够提升应收账款的管理效率。 7. 应收账款管理策略的调整和优化:由于企业的内外部环境复杂多变,因此制定的管理策略需要根据实际情况进行动态调整和持续优化。 8. 信用管理和征信体系的作用:建立和完善企业内部信用管理体系和征信体系,有助于企业更好地控制信用风险,并在市场竞争中占据有利地位。 9. 对比国内外应收账款管理实践:通过研究国内外企业在应收账款管理上的不同做法和经验,可以借鉴先进的管理理念和方法,提升国内企业的应收账款管理水平。 综上所述,本文深入探讨了应收账款管理的多个方面,为RH公司乃至其他同类型企业提供了应收账款管理的改进方向和策略,对于财务管理专业的教育和实践都具有重要的参考价值。
recommend-type

新手别慌!用BingPi-M2开发板带你5分钟搞懂Tina Linux SDK目录结构

# 新手别慌!用BingPi-M2开发板带你5分钟搞懂Tina Linux SDK目录结构 第一次拿到BingPi-M2开发板时,面对Tina Linux SDK里密密麻麻的文件夹,我完全不知道从哪下手。就像走进一个陌生的大仓库,每个货架上都堆满了工具和零件,却找不到操作手册。这种困惑持续了整整两天,直到我意识到——理解目录结构比死记硬背每个文件更重要。 ## 1. 为什么SDK目录结构如此重要 想象你正在组装一台复杂的模型飞机。如果所有零件都混在一个箱子里,你需要花大量时间寻找每个螺丝和面板。但如果有分门别类的隔层,标注着"机身部件"、"电子设备"、"紧固件",组装效率会成倍提升。Ti