机器学习系列----梯度下降算法

梯度下降算法(Gradient Descent)是机器学习和深度学习中最常用的优化算法之一。无论是在训练神经网络、线性回归模型,还是其他类型的机器学习模型时,梯度下降都是不可或缺的一部分。它的核心目标是最小化一个损失函数(Loss Function),从而得到最优的模型参数。

本篇博客将详细介绍梯度下降算法的原理、实现、各种变种以及在实际应用中的注意事项。文章不仅涵盖理论知识,还提供了丰富的Python代码示例,帮助你全面理解梯度下降的内部机制。

1. 梯度下降算法简介

梯度下降算法是一个用于优化的算法,它通过迭代的方式来最小化一个损失函数。在机器学习中,模型的学习过程就是在训练数据上找到一组最佳的参数,这组参数能够使得预测的结果和真实标签之间的误差最小化。梯度下降就是通过反复调整模型参数(例如权重和偏置),沿着损失函数的梯度方向前进,从而找到最优解。

1.1 为什么是“梯度”下降?
“梯度”指的是一个多维函数在某一点的变化率,即函数的导数。在梯度下降算法中,梯度表示损失函数相对于模型参数的变化情况。梯度是一个向量,它指向函数上升最快的方向。为了最小化损失函数,我们要沿着梯度的反方向进行更新。

1.2 梯度下降的核心目标
梯度下降的目标是通过一系列的步骤,找到损失函数的局部最小值或全局最小值,这样我们的模型就能够在训练数据上做出最准确的预测。

2. 梯度下降算法的工作原理

2.1 梯度和导数
梯度下降算法的原理建立在微积分的基础上。对于一个有多个自变量的函数,梯度是该函数在某一点上所有自变量的偏导数的集合。梯度下降的目的是通过计算这些偏导数来更新模型的参数。

3. 梯度下降的类型

梯度下降算法根据每次更新所使用的数据量不同,主要有三种类型:批量梯度下降(Batch Gradient Descent)、随机梯度下降(Stochastic Gradient Descent, SGD)和小批量梯度下降(Mini-Batch Gradient Descent)。

3.1 批量梯度下降(Batch Gradient Descent)
在批量梯度下降中,每次迭代都使用整个训练数据集来计算梯度并更新参数。这种方法的优点是计算稳定,但计算量大,特别是当数据集非常庞大时,计算时间和内存开销都非常高。

代码示例:批量梯度下降

import numpy as np# 生成训练数据
X = np.array([[1, 2], [2, 3], [3, 4], [4, 5]])
y = np.array([5, 7, 9, 11])# 初始化参数
theta = np.zeros(X.shape[1])# 学习率
alpha = 0.01# 批量梯度下降
def batch_gradient_descent(X, y, theta, alpha, iterations):m = len(y)for _ in range(iterations):predictions = X.dot(theta)error = predictions - ygradient = X.T.dot(error) / mtheta -= alpha * gradientreturn theta# 训练模型
theta_optimal = batch_gradient_descent(X, y, theta, alpha, 1000)
print("Optimal Parameters:", theta_optimal)

3.2 随机梯度下降(Stochastic Gradient Descent)
在随机梯度下降中,每次更新仅使用一个训练样本来计算梯度并更新参数。这使得每次更新的计算量非常小,但由于每次迭代的更新方向有较大的波动,SGD收敛速度相对较慢,并且可能会在局部最小值附近震荡。

代码示例:随机梯度下降

def stochastic_gradient_descent(X, y, theta, alpha, iterations):m = len(y)for _ in range(iterations):for i in range(m):xi = X[i:i+1]  # 取一个样本yi = y[i:i+1]prediction = xi.dot(theta)error = prediction - yigradient = xi.T.dot(error)theta -= alpha * gradientreturn theta# 训练模型
theta_optimal_sgd = stochastic_gradient_descent(X, y, theta, alpha, 1000)
print("Optimal Parameters (SGD):", theta_optimal_sgd)

3.3 小批量梯度下降(Mini-Batch Gradient Descent)

小批量梯度下降(Mini-Batch Gradient Descent)是一种常用的优化算法,在深度学习和机器学习中广泛应用。它结合了批量梯度下降(Batch Gradient Descent)和随机梯度下降(Stochastic Gradient Descent,SGD)的优点。具体来说,它通过以下方式对这两种方法进行了改进:

1. 小批量(Mini-Batch)
批量梯度下降使用整个训练集来计算梯度并更新参数,这样做虽然计算准确,但当数据集较大时,计算量非常庞大,且内存消耗大。
随机梯度下降每次从训练集中随机选择一个样本来计算梯度并更新参数,这使得更新速度更快,但由于每次只使用一个样本,梯度估计有较大波动,导致优化过程不稳定。
小批量梯度下降则将训练集划分为多个较小的批次,每个批次包含若干个样本(比如32个、64个等),每次使用一个批次来计算梯度并更新参数。通过这种方式,既能享受批量梯度下降较为稳定的更新效果,又能加速计算,减轻内存负担。
2. 优点
小批量梯度下降相对于批量梯度下降和随机梯度下降有多个优点:

**计算效率高:**每次只使用部分数据进行计算,减少了计算量和内存使用,同时还能够利用现代硬件(如GPU)并行计算的优势。

**更平衡的收敛速度:**由于每个小批量包含多个样本,计算出的梯度相较于随机梯度下降的波动更小,因此优化过程更加稳定且收敛速度比随机梯度下降更快。

**避免局部极小值:**由于每次更新参数时只使用一个小批量,梯度的方向会有所波动,这有助于模型跳出一些局部最优解,避免陷入不好的局部极小值。

**更好的泛化能力:**在训练过程中,较小的批量带来的噪声能够使模型避免过度拟合,增强了模型的泛化能力。

3. 超参数选择
在小批量梯度下降中,批次大小(mini-batch size)是一个重要的超参数,它决定了每次更新时所使用的训练样本数量。常见的批次大小选择有以下几种:

**小批量:**比如 32 或 64(通常是2的幂次),这种设置在实际应用中最为常见,能够兼顾计算效率和收敛性。
**大批量:**比如 128 或 256,虽然可以进一步加快计算速度,但可能导致训练过程的震荡性增加。
**小批量过小:**如果批次过小,比如只有 1 或 2,这样做就几乎回到了随机梯度下降,可能导致梯度估计噪声过大,优化过程不稳定。
批次大小的选择通常依赖于具体的数据集、硬件条件以及目标任务的特点。小批量梯度下降的批次大小需要根据实际情况进行调节,通常是通过实验来找到最佳值。

4. 优化过程
小批量梯度下降的优化过程大致如下:

将训练数据集随机划分为若干小批量。
每次从小批量中取出一个批次,计算该批次的梯度并更新模型参数。
重复以上过程,直到完成所有小批次的训练,或者达到停止条件(如误差小于某个阈值,或者经过足够的迭代次数)。
5. 学习率与批量大小的关系
批量大小与学习率有一定的相互关系。通常情况下,批量越大,更新的方向会越精确,学习率可以相应地调高;而批量越小,则由于每次梯度估计的不稳定,学习率需要适当调低来避免过度震荡。

6. 小批量梯度下降的变种
除了基本的小批量梯度下降外,还有许多改进和变种方法,旨在提高收敛速度和优化过程的稳定性。常见的包括:

**动量(Momentum):**通过引入动量项,利用历史梯度来平滑当前的更新方向,避免参数更新的剧烈波动。
**Adam(Adaptive Moment Estimation):**结合了动量和自适应学习率的优点,能够自动调整每个参数的学习率,适应不同参数的梯度变化。
7. 总结
小批量梯度下降(Mini-Batch Gradient Descent)是一种计算高效且收敛稳定的优化算法,广泛应用于深度学习中。它通过将训练数据划分为小批次来计算梯度,使得算法在批量梯度下降的稳定性和随机梯度下降的计算效率之间达到了平衡。选择合适的批量大小、优化超参数和改进算法(如Adam等)是提高模型训练性能的关键。

import numpy as np
import matplotlib.pyplot as plt# 生成模拟数据
np.random.seed(0)
X = 2 * np.random.rand(100, 1)  # 100个数据点,特征维度为1
y = 4 + 3 * X + np.random.randn(100, 1)  # 目标值 y = 4 + 3X + 噪声# 标准化数据(常见做法,提高模型训练效率)
X = (X - X.mean()) / X.std()# 将X扩展为包含常数项的特征矩阵
X_b = np.c_[np.ones((X.shape[0], 1)), X]# 小批量梯度下降实现
def mini_batch_gradient_descent(X, y, learning_rate=0.1, n_iterations=1000, batch_size=32):m = len(X)theta = np.random.randn(X.shape[1], 1)  # 随机初始化参数for iteration in range(n_iterations):# 随机打乱数据indices = np.random.permutation(m)X_shuffled = X[indices]y_shuffled = y[indices]# 分小批量for i in range(0, m, batch_size):X_batch = X_shuffled[i:i+batch_size]y_batch = y_shuffled[i:i+batch_size]# 计算梯度gradients = 2 / batch_size * X_batch.T.dot(X_batch.dot(theta) - y_batch)# 更新参数theta -= learning_rate * gradientsreturn theta# 使用小批量梯度下降训练模型
theta_final = mini_batch_gradient_descent(X_b, y, learning_rate=0.1, n_iterations=1000, batch_size=32)# 输出最终的theta值
print(f"Final model parameters: {theta_final.ravel()}")# 画出训练过程中的拟合直线
plt.scatter(X, y, color='blue', label='Data points')
plt.plot(X, X_b.dot(theta_final), color='red', label='Regression line')
plt.xlabel('X')
plt.ylabel('y')
plt.legend()
plt.title('Linear Regression using Mini-Batch Gradient Descent')
plt.show()

解释代码:
数据生成:

X:生成100个随机样本,表示特征(这里假设是1维特征)。
y:根据线性关系 ( y = 4 + 3X + \text{噪声} ) 生成目标值。
标准化:

对特征 X 进行标准化(均值为0,标准差为1),帮助提高模型训练效率。
小批量梯度下降函数:

mini_batch_gradient_descent:接收特征 X、目标 y、学习率、迭代次数和批次大小作为输入。
在每次迭代中,首先对数据进行随机打乱,然后分成小批次,每个小批次使用梯度下降更新模型参数。
梯度计算公式: ( \nabla_\theta J(\theta) = \frac{2}{m} X^T (X\theta - y) ),其中 ( J(\theta) ) 是均方误差损失函数。
训练过程:

在1000次迭代中,不断通过小批量梯度下降更新模型参数,最后得到训练后的参数 theta_final。
结果可视化:

绘制了训练数据点(蓝色散点)和拟合的回归直线(红色直线)。
小批量梯度下降的优势:
通过分小批次计算,避免了内存溢出,同时保持了较好的收敛性。
由于每个小批次包含多个样本,梯度更新比纯随机梯度下降更稳定。
调优:
你可以通过调整以下超参数来优化模型:

learning_rate:控制每次参数更新的步长。
n_iterations:迭代次数,越多通常能得到更好的拟合。
batch_size:小批量大小,常见选择是32、64、128等。可以根据训练数据的大小和硬件资源进行调整。
这段代码实现了一个基础的小批量梯度下降,用于线性回归问题,可以根据自己的需求进行修改和扩展。

4.梯度下降的变种

4.1 动量法(Momentum)

动量法(Momentum)借鉴了物理中的“动量”概念,它通过引入一个动量项,使得优化算法在梯度下降过程中不仅仅依赖当前的梯度,还结合了之前梯度的历史信息,帮助加速收敛,并减少震荡

def momentum_gradient_descent(X, y, learning_rate=0.1, n_iterations=1000, beta=0.9):m = len(X)theta = np.random.randn(X.shape[1], 1)v = np.zeros_like(theta)  # 初始化动量for iteration in range(n_iterations):gradients = 2 / m * X.T.dot(X.dot(theta) - y)v = beta * v + (1 - beta) * gradients  # 更新动量theta -= learning_rate * v  # 更新参数return theta

4.2 Adagrad

Adagrad(Adaptive Gradient Algorithm)是一种自适应梯度下降算法,通过为每个参数引入独立的学习率,使得学习率随着参数的更新而调整。对于更新较大的参数,学习率会逐渐减小;而对于更新较小的参数,学习率会相对较大,从而加速收敛。

def adagrad_gradient_descent(X, y, learning_rate=0.1, n_iterations=1000, epsilon=1e-8):m = len(X)theta = np.random.randn(X.shape[1], 1)G = np.zeros_like(theta)  # 初始化梯度平方和for iteration in range(n_iterations):gradients = 2 / m * X.T.dot(X.dot(theta) - y)G += gradients ** 2  # 累积梯度的平方theta -= learning_rate / (np.sqrt(G) + epsilon) * gradients  # 更新参数return theta

4.3 RMSprop

RMSprop(Root Mean Square Propagation)是对Adagrad的改进版本,目的是解决Adagrad学习率过早衰减的问题。RMSprop通过对梯度平方的指数加权平均来控制梯度更新,从而避免了学习率过快下降的问题。

def rmsprop_gradient_descent(X, y, learning_rate=0.01, n_iterations=1000, beta=0.9, epsilon=1e-8):m = len(X)theta = np.random.randn(X.shape[1], 1)Eg2 = np.zeros_like(theta)  # 初始化梯度平方的加权平均for iteration in range(n_iterations):gradients = 2 / m * X.T.dot(X.dot(theta) - y)Eg2 = beta * Eg2 + (1 - beta) * gradients ** 2  # 更新梯度平方的加权平均theta -= learning_rate / (np.sqrt(Eg2) + epsilon) * gradients  # 更新参数return theta

4.4 Adam

Adam(Adaptive Moment Estimation)结合了动量法和RMSprop的优点,同时考虑了梯度的均值和方差。它通过估计梯度的一阶矩(均值)和二阶矩(方差)的加权平均来调整每个参数的学习率。Adam是目前应用最广泛的优化算法之一,适用于大多数深度学习任务。

def adam_gradient_descent(X, y, learning_rate=0.001, n_iterations=1000, beta1=0.9, beta2=0.999, epsilon=1e-8):m = len(X)theta = np.random.randn(X.shape[1], 1)m_t = np.zeros_like(theta)  # 初始化一阶矩v_t = np.zeros_like(theta)  # 初始化二阶矩t = 0for iteration in range(n_iterations):t += 1gradients = 2 / m * X.T.dot(X.dot(theta) - y)# 更新一阶矩和二阶矩m_t = beta1 * m_t + (1 - beta1) * gradientsv_t = beta2 * v_t + (1 - beta2) * gradients ** 2# 偏差修正m_t_hat = m_t / (1 - beta1 ** t)v_t_hat = v_t / (1 - beta2 ** t)# 更新参数theta -= learning_rate * m_t_hat / (np.sqrt(v_t_hat) + epsilon)return theta

5.1 线性回归中的梯度下降
线性回归是一个常见的回归问题,目标是通过一条直线拟合数据点,最小化预测值与真实值之间的误差。我们可以通过梯度下降来优化线性回归模型的参数,使得模型能够尽可能准确地拟合训练数据。

线性回归模型:

import numpy as npdef gradient_descent(X, y, learning_rate=0.01, n_iterations=1000):m = len(y)theta = np.random.randn(X.shape[1], 1)  # 随机初始化参数for iteration in range(n_iterations):gradients = 2/m * X.T.dot(X.dot(theta) - y)  # 计算梯度theta -= learning_rate * gradients  # 更新参数return theta

输入: 训练数据 (X), 目标变量 (y), 学习率 (\alpha), 迭代次数
输出: 训练得到的参数 (\theta)
通过梯度下降迭代更新,模型会逐步接近最优的参数值,从而最小化预测误差。

5.2 神经网络中的梯度下降
神经网络是深度学习中的核心模型,它通过多个层级(输入层、隐藏层、输出层)进行非线性变换,用于处理复杂的任务,如分类、回归等。在神经网络中,梯度下降用于优化权重和偏置,以最小化损失函数,通常是交叉熵或均方误差。

神经网络的结构:
一个简单的神经网络通常包含:

输入层:接收输入特征
隐藏层:应用激活函数(如ReLU、sigmoid等)
输出层:输出预测结果
假设一个有一层隐藏层的神经网络,其中:

( X ) 是输入数据,( y ) 是目标输出。
权重矩阵分别为 ( W_1 ) 和 ( W_2 ),偏置分别为 ( b_1 ) 和 ( b_2 )。
激活函数为 ( \sigma )(如ReLU或sigmoid)。

def sigmoid(x):return 1 / (1 + np.exp(-x))def neural_network(X, y, learning_rate=0.01, n_iterations=1000):m = X.shape[0]n_features = X.shape[1]# 初始化权重和偏置W1 = np.random.randn(n_features, 4)b1 = np.zeros((1, 4))W2 = np.random.randn(4, 1)b2 = np.zeros((1, 1))for i in range(n_iterations):# 前向传播Z1 = np.dot(X, W1) + b1A1 = sigmoid(Z1)Z2 = np.dot(A1, W2)

 5.总结

  梯度下降法(Gradient Descent)是一种迭代优化算法,广泛应用于机器学习和深度学习中,用于最小化损失函数,从而优化模型参数。其基本原理是通过计算损失函数相对于参数的梯度,指示损失函数变化最快的方向,并沿着这个方向调整参数值。每次更新的步长由学习率决定,确保参数朝着最小值的方向前进。梯度下降法的核心优点是实现简单、计算高效,尤其适用于大规模数据集和复杂的模型。根据不同的计算方式,梯度下降法有几种常见变体,包括批量梯度下降、随机梯度下降(SGD)和小批量梯度下降(Mini-batch SGD),它们各有优缺点。虽然梯度下降法能有效地优化许多问题,但它也可能陷入局部最小值或鞍点,尤其是在非凸优化问题中;此外,学习率的选择对算法的收敛速度和稳定性至关重要,因此在实践中需要合理调节学习率,或者使用一些自适应学习率的优化算法(如Adam、Adagrad等)来改进收敛效率。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何在 Android 上增加 SELinux 权限

SELinux(Security-Enhanced Linux)是一种强制访问控制(MAC)机制,它为 Android 系统提供了额外的安全层。通过 SELinux,系统管理员可以定义细粒度的安全策略,限制进程对文件、网络和其他资源的访…

数字化转型实践:金蝶云星空与钉钉集成提升企业运营效率

数字化转型实践:金蝶云星空与钉钉集成提升企业运营效率 本文介绍了深圳一家电子设备制造企业在数字化转型过程中,如何通过金蝶云星空与钉钉的高效集成应对挑战、实施解决方案,并取得显著成果。集成项目在提高沟通效率、自动化审批流程和监控异…

『事善能』MySQL基础 — 2.MySQL 5.7安装(一)

1、通过msi安装软件进行MySQL安装 (1)点击运行MySQL安装文件 (2)选择安装类型 我们选择自定义安装,点击Next。 说明 Develop Default:默认开发类型,安装MySQL服务器以及开发MySQL应用所需要的工…

DICOM图像知识:DICOM图像排序与坐标系解析

目录 引言 1. 概述 2. DICOM图像排序规则 2.1 Patient的Study按Study Date排序 2.2 Study的Series按Series Number排序 2.3 Series的SOP按Instance Number或Slice Location排序 2.3.1 Instance Number排序 2.3.2 Slice Location排序 2.3.3 使用Image Position (Patien…

uniapp—android原生插件开发(2原生插件开发)

本篇文章从实战角度出发,将UniApp集成新大陆PDA设备RFID的全过程分为四部曲,涵盖环境搭建、插件开发、AAR打包、项目引入和功能调试。通过这份教程,轻松应对安卓原生插件开发与打包需求! ***环境问题移步至:uniapp—an…

清华大学提出Mini-Omni2:开源多模态模型,功能与GPT-4o媲美!

🌐 在人工智能领域,多模态模型的发展正如火如荼。今天,我们要介绍的是由清华大学提出的Mini-Omni2,这是一个开源的多模态语言模型,它在功能上与GPT-4o相媲美,能够理解和生成视觉、听觉和文本内容&#xff0…

Golang进阶

1.面向对象 1.1.golang语言面向对象编程说明 Golang 也支持面向对象编程(OOP),但是和传统的面向对象编程有区别,并不是纯粹的面向对象语言。所以我们说 Golang 支持面向对象编程特性是比较准确的。Golang 没有类(class),Go 语言的结构体(st…

ElasticSearch 添加IK分词器

ElasticSearch 添加IK分词器 前言一、IK分词器的算法二、Ik分词器的下载安装(Winows 版本)三、Ik分词器的下载安装(Linux 版本)四、验证测试(postman工具)测试 ik_smart 分词算法测试 ik_max_word 分词算法…

双指针算法的妙用:提高代码效率的秘密(2)

双指针算法的妙用:提高代码效率的秘密(2) 前言: 小编在前几日讲述了有关双指针算法两道题目的讲解,今天小编继续进行有关双指针算法习题的讲解,老规矩,今天还是两道题目的讲解,希望…

浮动路由:实现出口线路的负载均衡冗余备份。

浮动路由 Tip:浮动路由指在多条默认路由基础上加入优先级参数,实现出口线路冗余备份。 ip routing-table //查看路由表命令 路由优先级参数:越小越优 本次实验测试两条默认路由,其中一条默认路由添加优先级参数,设置…

利用VMware workstation pro 17安装 Centos7虚拟机以及修改网卡名称

通过百度网盘分享的文件:安装虚拟机必备软件 链接:https://pan.baidu.com/s/1rbYhDh8x1hTzlSNihm49EA?pwdomxy 提取码:omxy 123网盘 https://www.123865.com/s/eXPrVv-UsKch 提取码:eNcy 先自行安装好VMware workstation pro 17 设置虚拟机…

如何在Linux中使用Cron定时执行SQL任务

文章目录 前言一、方案分析二、使用步骤1.准备脚本2.crontab脚本执行 踩坑 前言 演示数据需要每天更新监控数据,不想手动执行,想到以下解决方案 navicat 创建定时任务java服务定时执行linux crontab 定时执行sql脚本 一、方案分析 我选择了第三个方案…

SpringBoot技术在企业资产管理中的应用

4系统概要设计 4.1概述 系统设计原则 以技术先进、系统实用、结构合理、产品主流、低成本、低维护量作为基本建设原则,规划系统的整体构架. 先进性: 在产品设计上,整个系统软硬件设备的设计符合高新技术的潮流,媒体数字化、压缩、…

linux基础-完结(详讲补充)

linux基础-完结 一、Linux目录介绍 二、基础命令详细讲解 1. ls(列出目录内容) 2. cd(更改目录) 3. clear(清除终端屏幕) 4. pwd(显示你当前所在的目录) 5. vim(文本编辑器) 6. touch(创…

ArcGIS软件之“计算面积几何”地图制作

目录 一、消防站的泰森多边形ex12二、人口调查的泰森多边形三、人口调查的泰森多边形属性设置四、计算面积几何,用于求密度五、求密度六、给“现有中学”属性 R1赋值七、“现有中学”设置多环缓存区 并为它赋值八、“土地使用”为不同的功能区赋值九、三个图层相交十、计算面积…

一、有限状态机

一、状态基类 在创建一个FSM的有限状态机的缩写脚本 例:比如枚举这个状态,现在不确定是给敌人还是玩家,那么就写一个枚举的基类 在这里先创建了三个抽象方法,进行状态的切换; 并且这是一个状态基类,不需要…

C++20 概念与约束(2)—— 初识概念与约束

1、概念 C20 中引入新的编译期关键字 concept 用于创建概念。个人认为将其翻译为“构思”更为贴切。直接使用时,它更像一个只能用于模板的布尔类型关键字。 而如果用于模板中,他会将模板类型先带入自身,当自身条件为 true 才会实例化模板&…

程序员会被AI取代吗?

时间:2024年 11月 10日 作者:小蒋聊技术 邮箱:wei_wei10163.com 微信:wei_wei10 音频:喜马拉雅 近年来,随着人工智能(AI)技术的发展,技术圈内关于“程序员会被AI取代…

2024 第五次周赛

A: 直接遍历即可 #include<bits/stdc.h> using namespace std;typedef long long ll; typedef pair<ll, ll>PII; const int N 2e6 10; const int MOD 998244353; const int INF 0X3F3F3F3F;int n, m; int main() {cin >> n;int cnt 0;for(int i 0; i …

十五、Linux线程(二)

4.线程的分离属性 通过属性设置线程的分离 1.线程属性类型&#xff1a; pthread_attr_t attr; 2.线程属性操作函数&#xff1a; &#xff08;1&#xff09;对线程属性变量的初始化 int pthread_attr_init(pthread_attr_t* attr); &#xff08;2&#xff09;设置线程分离属…