深度学习 - 梯度下降优化方法

梯度下降的基本概念

梯度下降(Gradient Descent)是一种用于优化机器学习模型参数的算法,其目的是最小化损失函数,从而提高模型的预测精度。梯度下降的核心思想是通过迭代地调整参数,沿着损失函数下降的方向前进,最终找到最优解。

生活中的背景例子:寻找山谷的最低点

想象你站在一个山谷中,眼睛被蒙住,只能用脚感受地面的坡度来找到山谷的最低点(即损失函数的最小值)。你每一步都想朝着坡度下降最快的方向走,直到你感觉不到坡度,也就是你到了最低点。这就好比在优化一个模型时,通过不断调整参数,使得模型的预测误差(损失函数)越来越小,最终找到最佳参数组合。

梯度下降的具体方法及其优化

1. 批量梯度下降(Batch Gradient Descent)

生活中的例子
你决定每次移动之前,都要先测量整个山谷的坡度,然后再决定移动的方向和步幅。虽然每一步的方向和步幅都很准确,但每次都要花很多时间来测量整个山谷的坡度。

公式
θ : = θ − η ⋅ ∇ θ J ( θ ) \theta := \theta - \eta \cdot \nabla_{\theta} J(\theta) θ:=θηθJ(θ)
其中:

  • θ \theta θ是模型参数
  • η \eta η是学习率
  • ∇ θ J ( θ ) \nabla_{\theta} J(\theta) θJ(θ)是损失函数 J ( θ ) J(\theta) J(θ)关于 θ \theta θ的梯度

API
TensorFlow

optimizer = tf.keras.optimizers.SGD(learning_rate=0.01)

PyTorch

optimizer = torch.optim.SGD(model.parameters(), lr=0.01)

批量梯度下降过程图像python代码

import numpy as np
import matplotlib.pyplot as plt

# 损失函数: y = x^2
def loss(x):
    return x ** 2

# 损失函数的梯度: dy/dx = 2x
def gradient(x):
    return 2 * x

# 批量梯度下降
def batch_gradient_descent(start, learning_rate, iterations):
    x = start
    path = [x]
    for i in range(iterations):
        grad = gradient(x)
        x = x - learning_rate * grad
        path.append(x)
    return path

# 参数
start = 10
learning_rate = 0.1
iterations = 20

# 运行梯度下降
path = batch_gradient_descent(start, learning_rate, iterations)

# 绘制图像
x = np.linspace(-10, 10, 100)
y = loss(x)
plt.plot(x, y, label='Loss Function')
plt.scatter(path, [loss(p) for p in path], color='red', label='Batch Gradient Descent Path')
plt.xlabel('x')
plt.ylabel('Loss')
plt.legend()
plt.title('Batch Gradient Descent')
plt.show()

在这里插入图片描述

  • 从图像可知,批量梯度下降每次使用整个训练集计算梯度并更新参数,适用于小规模数据集,收敛稳定,但计算开销大。
2. 随机梯度下降(Stochastic Gradient Descent, SGD)

生活中的例子
你决定每一步都只根据当前所在位置的坡度来移动。虽然这样可以快速决定下一步怎么走,但由于只考虑当前点,可能会导致路径不稳定,有时候会走过头。

公式
θ : = θ − η ⋅ ∇ θ J ( θ ; x ( i ) , y ( i ) ) \theta := \theta - \eta \cdot \nabla_{\theta} J(\theta; x^{(i)}, y^{(i)}) θ:=θηθJ(θ;x(i),y(i))
其中 ( x ( i ) , y ( i ) ) (x^{(i)}, y^{(i)}) (x(i),y(i))是当前样本的数据

API
TensorFlowPyTorch 中的API与批量梯度下降相同,具体行为取决于数据的加载方式。例如在训练时可以一批数据包含一个样本。

随机梯度下降过程图像python代码

import numpy as np
import matplotlib.pyplot as plt

# 损失函数: y = x^2
def loss(x):
    return x ** 2

# 损失函数的梯度: dy/dx = 2x
def gradient(x):
    return 2 * x

# 随机梯度下降
def stochastic_gradient_descent(start, learning_rate, iterations):
    x = start
    path = [x]
    for i in range(iterations):
        grad = gradient(x)
        x = x - learning_rate * grad * np.random.uniform(0.5, 1.5)  # 模拟随机样本的影响
        path.append(x)
    return path

# 参数
start = 10
learning_rate = 0.1
iterations = 20

# 运行梯度下降
path = stochastic_gradient_descent(start, learning_rate, iterations)

# 绘制图像
x = np.linspace(-10, 10, 100)
y = loss(x)
plt.plot(x, y, label='Loss Function')
plt.scatter(path, [loss(p) for p in path], color='red', label='SGD Path')
plt.xlabel('x')
plt.ylabel('Loss')
plt.legend()
plt.title('Stochastic Gradient Descent')
plt.show()

  • 随机梯度下降每次使用一个样本计算梯度并更新参数,计算效率高,适用于大规模数据集,但收敛不稳定,容易出现抖动。
3. 小批量梯度下降(Mini-Batch Gradient Descent)

生活中的例子
你决定每次移动之前,只测量周围一小部分区域的坡度,然后根据这小部分区域的平均坡度来决定方向和步幅。这样既不需要花太多时间测量整个山谷,也不会因为只看一个点而导致路径不稳定。

公式
θ : = θ − η ⋅ ∇ θ J ( θ ; B ) \theta := \theta - \eta \cdot \nabla_{\theta} J(\theta; \mathcal{B}) θ:=θηθJ(θ;B)
其中 B \mathcal{B} B是当前小批量的数据

API
TensorFlowPyTorch 中的API与批量梯度下降相同,但在数据加载时使用小批量。

小批量梯度下降过程图像python代码

import numpy as np
import matplotlib.pyplot as plt

# 损失函数: y = x^2
def loss(x):
    return x ** 2

# 损失函数的梯度: dy/dx = 2x
def gradient(x):
    return 2 * x

# 小批量梯度下降
def mini_batch_gradient_descent(start, learning_rate, iterations, batch_size=5):
    x = start
    path = [x]
    for i in range(iterations):
        grad = gradient(x)
        x = x - learning_rate * grad * np.random.uniform(0.8, 1.2)  # 模拟小批量样本的影响
        path.append(x)
    return path

# 参数
start = 10
learning_rate = 0.1
iterations = 20

# 运行梯度下降
path = mini_batch_gradient_descent(start, learning_rate, iterations)

# 绘制图像
x = np.linspace(-10, 10, 100)
y = loss(x)
plt.plot(x, y, label='Loss Function')
plt.scatter(path, [loss(p) for p in path], color='red', label='Mini-Batch Gradient Descent Path')
plt.xlabel('x')
plt.ylabel('Loss')
plt.legend()
plt.title('Mini-Batch Gradient Descent')
plt.show()

在这里插入图片描述

  • 小批量梯度下降每次使用一个小批量样本计算梯度并更新参数,平衡了计算效率和稳定性。
4. 动量法(Momentum)

生活中的例子
你在移动时,不仅考虑当前的坡度,还考虑之前几步的移动方向,就像带着惯性一样。如果前几步一直往一个方向走,那么你会倾向于继续往这个方向走,减少来回震荡。

公式
v : = β v + ( 1 − β ) ∇ θ J ( θ ) v := \beta v + (1 - \beta) \nabla_{\theta} J(\theta) v:=βv+(1β)θJ(θ)
θ : = θ − η v \theta := \theta - \eta v θ:=θηv
其中:

  • v v v是动量项
  • β \beta β是动量系数(通常接近1,如0.9)

API
TensorFlow

optimizer = tf.keras.optimizers.SGD(learning_rate=0.01, momentum=0.9)

PyTorch

optimizer = torch.optim.SGD(model.parameters(), lr=0.01, momentum=0.9)

动量法图像python代码

import numpy as np
import matplotlib.pyplot as plt

# 损失函数: y = x^2
def loss(x):
    return x ** 2

# 损失函数的梯度: dy/dx = 2x
def gradient(x):
    return 2 * x

# 动量法
def momentum_gradient_descent(start, learning_rate, iterations, beta=0.9):
    x = start
    v = 0
    path = [x]
    for i in range(iterations):
        grad = gradient(x)
        v = beta * v + (1 - beta) * grad
        x = x - learning_rate * v
        path.append(x)
    return path

# 参数
start = 10
learning_rate = 0.1
iterations = 20

# 运行梯度下降
path = momentum_gradient_descent(start, learning_rate, iterations)

# 绘制图像
x = np.linspace(-10, 10, 100)
y = loss(x)
plt.plot(x, y, label='Loss Function')
plt.scatter(path, [loss(p) for p in path], color='red', label='Momentum Path')
plt.xlabel('x')
plt.ylabel('Loss')
plt.legend()
plt.title('Momentum Gradient Descent')
plt.show()

在这里插入图片描述

  • 动量法通过引入动量项加速收敛并减少震荡,适用于深度神经网络训练。
5. RMSProp

生活中的例子
你在移动时,会根据最近一段时间内每一步的坡度情况,动态调整步幅。比如,当坡度变化剧烈时,你会迈小步,当坡度变化平缓时,你会迈大步。

公式
s : = β s + ( 1 − β ) ( ∇ θ J ( θ ) ) 2 s := \beta s + (1 - \beta) (\nabla_{\theta} J(\theta))^2 s:=βs+(1β)(θJ(θ))2
θ : = θ − η s + ϵ ∇ θ J ( θ ) \theta := \theta - \frac{\eta}{\sqrt{s + \epsilon}} \nabla_{\theta} J(\theta) θ:=θs+ϵ ηθJ(θ)
其中:

  • s s s是梯度平方的加权平均值
  • ϵ \epsilon ϵ是一个小常数,防止除零错误

API
TensorFlow

optimizer = tf.keras.optimizers.RMSprop(learning_rate=0.001)

PyTorch

optimizer = torch.optim.RMSprop(model.parameters(), lr=0.001)

RMSProp图像python代码

import numpy as np
import matplotlib.pyplot as plt

# 损失函数: y = x^2
def loss(x):
    return x ** 2

# 损失函数的梯度: dy/dx = 2x
def gradient(x):
    return 2 * x

# RMSProp
def rmsprop_gradient_descent(start, learning_rate, iterations, beta=0.9, epsilon=1e-8):
    x = start
    s = 0
    path = [x]
    for i in range(iterations):
        grad = gradient(x)
        s = beta * s + (1 - beta) * grad**2
        x = x - learning_rate * grad / (np.sqrt(s) + epsilon)
        path.append(x)
    return path

# 参数
start = 10
learning_rate = 0.1
iterations = 20

# 运行梯度下降
path = rmsprop_gradient_descent(start, learning_rate, iterations)

# 绘制图像
x = np.linspace(-10, 10, 100)
y = loss(x)
plt.plot(x, y, label='Loss Function')
plt.scatter(path, [loss(p) for p in path], color='red', label='RMSProp Path')
plt.xlabel('x')
plt.ylabel('Loss')
plt.legend()
plt.title('RMSProp Gradient Descent')
plt.show()

在这里插入图片描述

  • RMSProp动态调整学习率,通过对梯度平方的加权平均值进行调整,适用于处理非平稳目标。
6. Adam(Adaptive Moment Estimation)

生活中的例子
你在移动时,结合动量法和RMSProp的优点,不仅考虑之前的移动方向(动量),还根据最近一段时间内的坡度变化情况(调整步幅),从而使移动更加平稳和高效。

公式
m : = β 1 m + ( 1 − β 1 ) ∇ θ J ( θ ) m := \beta_1 m + (1 - \beta_1) \nabla_{\theta} J(\theta) m:=β1m+(1β1)θJ(θ)
v : = β 2 v + ( 1 − β 2 ) ( ∇ θ J ( θ ) ) 2 v := \beta_2 v + (1 - \beta_2) (\nabla_{\theta} J(\theta))^2 v:=β2v+(1β2)(θJ(θ))2
m ^ : = m 1 − β 1 t \hat{m} := \frac{m}{1 - \beta_1^t} m^:=1β1tm
v ^ : = v 1 − β 2 t \hat{v} := \frac{v}{1 - \beta_2^t} v^:=1β2tv
θ : = θ − η m ^ v ^ + ϵ \theta := \theta - \eta \frac{\hat{m}}{\sqrt{\hat{v}} + \epsilon} θ:=θηv^ +ϵm^
其中:

  • m m m v v v分别是梯度的一阶和二阶动量
  • β 1 \beta_1 β1 β 2 \beta_2 β2是动量系数(通常分别取0.9和0.999)
  • m ^ \hat{m} m^ v ^ \hat{v} v^是偏差校正后的动量项
  • t t t是时间步

API
TensorFlow

optimizer = tf.keras.optimizers.Adam(learning_rate=0.001)

PyTorch

optimizer = torch.optim.Adam(model.parameters(), lr=0.001)

Adam图像python代码

import numpy as np
import matplotlib.pyplot as plt

# 损失函数: y = x^2
def loss(x):
    return x ** 2

# 损失函数的梯度: dy/dx = 2x
def gradient(x):
    return 2 * x

# Adam
def adam_gradient_descent(start, learning_rate, iterations, beta1=0.9, beta2=0.999, epsilon=1e-8):
    x = start
    m = 0
    v = 0
    path = [x]
    for t in range(1, iterations + 1):
        grad = gradient(x)
        m = beta1 * m + (1 - beta1) * grad
        v = beta2 * v + (1 - beta2) * grad**2
        m_hat = m / (1 - beta1**t)
        v_hat = v / (1 - beta2**t)
        x = x - learning_rate * m_hat / (np.sqrt(v_hat) + epsilon)
        path.append(x)
    return path

# 参数
start = 10
learning_rate = 0.1
iterations = 20

# 运行梯度下降
path = adam_gradient_descent(start, learning_rate, iterations)

# 绘制图像
x = np.linspace(-10, 10, 100)
y = loss(x)
plt.plot(x, y, label='Loss Function')
plt.scatter(path, [loss(p) for p in path], color='red', label='Adam Path')
plt.xlabel('x')
plt.ylabel('Loss')
plt.legend()
plt.title('Adam Gradient Descent')
plt.show()

在这里插入图片描述

  • Adam结合动量法和RMSProp的优点,自适应调整学习率,适用于各种优化问题。

综合应用示例

假设我们在使用TensorFlow和PyTorch训练一个简单的神经网络,以下是如何应用这些优化方法的示例代码。

TensorFlow 示例

import tensorflow as tf

# 定义模型
model = tf.keras.Sequential([
    tf.keras.layers.Dense(128, activation='relu', input_shape=(784,)),
    tf.keras.layers.Dense(10, activation='softmax')
])

# 编译模型并选择优化器
optimizer = tf.keras.optimizers.Adam(learning_rate=0.001)
model.compile(optimizer=optimizer, loss='sparse_categorical_crossentropy', metrics=['accuracy'])

# 准备数据
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0

# 训练模型
model.fit(x_train, y_train, epochs=10, batch_size=32)

PyTorch 示例

import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
from torch.utils.data import DataLoader

# 定义模型
class SimpleNN(nn.Module):
    def __init__(self):
        super(SimpleNN, self).__init__()
        self.fc1 = nn.Linear(784, 128)
        self.fc2 = nn.Linear(128, 10)

    def forward(self, x):
        x = torch.relu(self.fc1(x))
        x = self.fc2(x)
        return x

model = SimpleNN()

# 选择优化器
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
criterion = nn.CrossEntropyLoss()

# 准备数据
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,))])
train_dataset = datasets.MNIST(root='./data', train=True, transform=transform, download=True)
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)

# 训练模型
for epoch in range(10):
    for batch in train_loader:
        x_train, y_train = batch
        x_train = x_train.view(x_train.size(0), -1)  # Flatten the images

        optimizer.zero_grad()
        outputs = model(x_train)
        loss = criterion(outputs, y_train)
        loss.backward()
        optimizer.step()

综合对比

优化方法优点缺点可能出现的问题适用场景
批量梯度下降(Batch GD)收敛稳定,适用于小规模数据集每次迭代计算开销大,速度慢难以处理大规模数据,容易陷入局部最优小规模数据集,适合精确收敛
随机梯度下降(SGD)计算效率高,适用于大规模数据集路径不稳定,波动较大收敛路径抖动大,不稳定大规模数据集,在线学习,快速迭代
小批量梯度下降(Mini-Batch GD)平衡了计算效率和收敛稳定性需要选择合适的小批量大小,计算量仍然较大小批量大小选择不当可能影响收敛效果大规模数据集,适合批量计算
动量法(Momentum)加速收敛,减少震荡需要调整动量系数,增加了参数选择的复杂性动量系数选择不当可能导致过冲深度神经网络训练,加速收敛
RMSProp动态调整学习率,适应非平稳目标需要调整参数β和ε,参数选择复杂参数选择不当可能影响收敛效果非平稳目标,复杂优化问题
Adam结合动量法和RMSProp优点,自适应调整学习率,收敛快需要调整多个参数,计算复杂性高参数选择不当可能影响收敛效果各种优化问题,特别是深度学习模型训练

更多问题咨询

CosAI

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ssm605基于SSM的游戏商城的设计与实现+jsp【已测试】

前言:👩‍💻 计算机行业的同仁们,大家好!作为专注于Java领域多年的开发者,我非常理解实践案例的重要性。以下是一些我认为有助于提升你们技能的资源: 👩‍💻 SpringBoot…

【c语言】qsort函数及泛型冒泡排序的模拟实现

🌟🌟作者主页:ephemerals__ 🌟🌟所属专栏:C语言 目录 一、qsort函数 1.回调函数 2.qsort函数 3.void* 指针 二、泛型冒泡排序的模拟实现 1.比较函数的编写 2.交换函数的编写 3.冒泡排序的编写 4…

ssm617基于协同过滤技术的网上书城的开发与研究+jsp【已测试】

前言:👩‍💻 计算机行业的同仁们,大家好!作为专注于Java领域多年的开发者,我非常理解实践案例的重要性。以下是一些我认为有助于提升你们技能的资源: 👩‍💻 SpringBoot…

loading组件封装原理

以vue3为例&#xff0c;采用ts 的语言 首先可对所需数据定义在接口中 interface Prop{ //核心所需的就是 lading:boolean ,type: lading | skeleton} 进行调用 封装的话采用的是插槽 <div v-if"loading" ><slot name"template"><…

Vue12-计算属性

一、姓名案例 1-1、插值语法实现 1、v-bind v-bind的问题&#xff1a; 所以&#xff1a;v-bind是单向绑定。 2、v-model 解决v-bind的问题。 3、输出全名 方式一&#xff1a; 方式二&#xff1a; 需求优化&#xff1a;全名中的姓氏&#xff0c;只取输入框中的前三位&#xf…

人工智能对话系统源码 手机版+电脑版二合一 全端支持 前后端分离 带完整的安装代码包以及搭建部署教程

系统概述 该系统采用前后端分离的设计模式&#xff0c;前端负责用户界面展示与交互&#xff0c;后端负责数据处理与业务逻辑实现。前后端通过API接口进行通信&#xff0c;实现数据的实时传输与处理。系统支持全端访问&#xff0c;无论是手机还是电脑&#xff0c;都能获得良好的…

ROS基础学习-ROS通信机制进阶

ROS通信机制进阶 目录 0.简介1.常用API1.1 节点初始化函数1.1.1 C++1.1.2 Python1.2 话题与服务相关函数1.2.1 对象获取相关1.2.1.1 C++1.2.1.2 Python1.2.2 订阅对象相关1.2.2.1 C++1.2.2.2 Python1.2.3 服务对象相关函数1.2.3.1 C++1.2.3.2 Python1.2.4 客户端对象相关1.2.4.…

Linux---sudo命令

文章目录 目录 文章目录 一.sudo命令简介 二.sudo 命令的特点 三.sudo 相关文件 四.sudo 命令授权配置 一.sudo命令简介 sudo 命令全称“SuperUser Do”&#xff0c;是Linux系统中的一个命令能够使普通用户以超级用户身份去执行某些命令。 二.sudo 命令的特点 sudo能够授权…

每日题库:Huawe数通HCIA——14(30道)

所有资料均来源自网络&#xff0c;但个人亲测有效&#xff0c;特来分享&#xff0c;希望各位能拿到好成绩&#xff01; PS&#xff1a;别忘了一件三连哈&#xff01; 今日题库&#xff1a; 201. 如下图所示的网络&#xff0c;主机存在ARP缓存&#xff0c;主机A.发送数据包给…

STM32快速入门(ADC数模转换)

STM32快速入门&#xff08;ADC数模转换&#xff09; 前言 ADC数模转换存在的意义就是将一些温度传感器、各自数据传感器产生的模拟信号转换成方便识别和计算的数字信号。 导航 图24 通用定时器框图&#xff1a; 图片截取自STM32 F1XX中文参考手册。还是以框图为中心&#x…

C++中的一些困惑(长期更新中)

C中的一些困惑 文章目录 C中的一些困惑1. using std::具体命名与using namespace std;2. 【int \*p[10] 】与 【int (\*p)[10]】3. main()函数可带参&#xff0c;参从何来&#xff1f;4. constexpr函数的返回值可不为常量&#xff0c;那这时constexpr关键字作用是什么&#xff…

【C语言】预处理详解(上卷)

前言 预处理也是C语言中非常重要的存在。那么就详细地来了解一下吧。 预定义符号 C语言设置了一些预定义符号&#xff0c;可以直接使用&#xff0c;预定义符号也是在预处理期间处理的。 1 __FILE__ //进行编译的源文件 2 __LINE__ //文件当前的…

LabVIEW硬件与仿真双模式设计液压系统

在实际项目中&#xff0c;结合LabVIEW与液压运动控制器&#xff0c;通过设计两种运行方式&#xff1a;硬件运行和仿真运行&#xff0c;使得系统既能进行实际操作又能进行仿真测试。此设计不仅方便了开发调试&#xff0c;也为教学培训和展示提供了极大的便利。本文将从项目背景、…

手把手AI实战(一)治愈系动画视频

手把手AI实战(一)治愈系动画视频 一、成果展示 二、步骤拆解 2.1 AI出图 可以使用你顺手的AI绘图工具&#xff0c;国外的像Midjouney、Stable Diffusion&#xff0c;国内的像扣子、智普清言等等。我这里用了剪映的&#xff0c;地址是&#xff1a;https://jimeng.jianying.com/a…

【AI论文与新生技术】Follow-Your-Emoji:精细可控且富有表现力的自由式人像动画技术

我们提出了 Follow-Your-Emoji&#xff0c;这是一种基于扩散的肖像动画框架&#xff0c;它使用目标地标序列对参考肖像进行动画处理。肖像动画的主要挑战是保留参考肖像的身份并将目标表情转移到该肖像&#xff0c;同时保持时间一致性和保真度。为了应对这些挑战&#xff0c;Fo…

C++11 列表初始化(initializer_list),pair

1. {} 初始化 C98 中&#xff0c;允许使用 {} 对数组进行初始化。 int arr[3] { 0, 1, 2 };C11 扩大了 {} 初始化 的使用范围&#xff0c;使其可用于所有内置类型和自定义类型。 struct Date {int _year;int _month;int _day;Date(int year, int month, int day):_year(year…

梯度下降: 02. 批量梯度下降BGD,随机梯度下降SGD,小批量梯度下降MBGD

简介 本文从原理上介绍了三种梯度下降的方法,相同点,异同点,优缺点。 内容包含了数学公式的推导与说明 1. 梯度下降的3种方法 梯度下降分三类,原理基本相同,操作方式略有区别 批量梯度下降BGD(BatchGradient Descent):使用全量数据进行特征抽取,模型训练小批量梯度下降…

tkinter颜色选择器

tkinter颜色选择器 颜色选择器效果代码 颜色选择器 Tkinter 提供了一个简单易用的颜色选择器模块 colorchooser&#xff0c;通过调用 colorchooser.askcolor() 方法&#xff0c;我们可以轻松实现颜色选择功能。 效果 代码 import tkinter as tk from tkinter import colorch…

启动xv6遇坑记录

我是在VMware上的Ubuntu22.04.4搭建的&#xff0c;启动xv6遇到超多bug&#xff0c;搞了好几天&#xff0c;所以记录一下。 目录 git push的时候报错 make qemu缺少包 运行make qemu时卡住 可能有影响的主机设置 git push的时候报错 remote: Support for password authent…

Soildworks学习笔记(二)

放样凸台基体&#xff1a; 自动生成连接两个物体两个面的基体&#xff1a; 2.旋转切除&#xff1a; 3.剪切实体&#xff1a; 4.转换实体引用&#xff1a; 将实体的轮廓线转换至当前草图使其成为当前草图的图元,主要用于在同一平面或另一个坐标中制作草图实体或其尺寸的副本。 …