深度学习-损失函数 python opencv源码(史上最全)

目录

定义

种类

如何选择损失函数?

平方(均方)损失函数(Mean Squared Error, MSE)

均方根误差

交叉熵

对数损失

笔记回馈

逻辑回归中一些注意事项:


定义

损失函数又叫误差函数、成本函数、代价函数,用来衡量算法的运行情况,用符号L表示。

假设我们的回归函数是:y = wx+b,那么损失函数的作用就是用来获取误差,然后来更新w和b,从而使预测值y更贴近真实值。也就是训练过程就是让这个损失越来越小的过程(最小化损失函数)。

作用:1衡量模型性能 2优化参数(w和b)

种类

均方误差(MSE)、均方根误差(RMSE)、平均绝对误差(MAE)、交叉熵误差、对数损失或逻辑回归损失、Hinge损失、Huber损失、余弦相似损失等。

问题一:为什么这么多损失函数?我该怎么选择?

因为损失函数是用于优化权重的函数,好的损失函数决定了训练的速度和质量,因此人们在损失函数下了很大功夫,做了很多研究,就发明了这么多损失函数,用于解决不同的需求和环境。怎么选择损失函数,其实这些损失函数都能优化权重,你可以随便选择一种,当然你也可以跟据损失函数的优缺点,选择对你任务最优的函数来尝试。

公式乱码了:以下是Huber损失的函数

如何选择损失函数?

选择损失函数时,您可以根据以下几个因素来决定:

  1. 任务类型:如果是回归问题,常用的损失函数有均方误差(MSE)、均方根误差(RMSE)、平均绝对误差(MAE);如果是分类问题,交叉熵(Cross-Entropy)或对数损失(Log Loss)是常见的选择。

  2. 数据特征:如果数据中包含异常值,使用均方误差可能会让模型过度关注这些异常值。此时可以考虑使用Huber损失平均绝对误差MAE

  3. 模型类型:一些特定的模型(如支持向量机)通常使用特定的损失函数,比如Hinge损失

  4. 计算要求:一些损失函数(如交叉熵)可能需要计算概率值,适用于概率模型;而像均方误差则适用于普通的回归模型

如果需要更多学习资料可以打开【咸鱼】https://m.tb.cn/h.6h707H6?tk=rRbqVZ2WNdh HU926 
点击链接直接打开,三0元以下带你完成人脸识别、关键点识别、手势识别等多个项目,涵盖SVM、knn、yolov8、语义分割!!!零基础适合小白

上面介绍损失函数的公式以及优缺点,但是大家还是难以有个直观感受,以下希望通过代码的形式让你有个直观体验:

平方(均方)损失函数(Mean Squared Error, MSE)

预测值与真实值的差的平方的n分之一。这个函数不适用于分类问题,而适用于预测的输出值是一个实数值的任务中,所以整体而言我们不会和他打太多交道(但是在强化学习的TD算法里,我们会遇到)

如图所示,假设我们有一条直线,如果我们的数据存在误差(比如一张猫的图片被我们标注成了狗),那么均方损失函数会偏向于惩罚较大的点,赋予了较大权重,如图蓝线靠近了红色圆圈区域。MSE对异常值非常敏感,因为较大的误差会受到更大的惩罚(误差的平方会放大差异)。它通常用于需要精确预测的场景,但可能不适用于异常值较多的数据集。

惩罚的意思就是,平方损失函数在误差较大时,由于他是平方,也就是误差的平方,那么训练的时候那些误差较大的数据会影响训练的效果。训练的模型会过度关注误差。

这里补充个知识点,离群点也就是红色圆圈圈起来的点。

代码:

import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(1, 20, 40)
y = x + [np.random.choice(4) for _ in range(40)]
y[-5:] -= 8
X = np.vstack((np.ones_like(x),x))    # 引入常数项 1
m = X.shape[1]
# 参数初始化
W = np.zeros((1,2))# 迭代训练 
num_iter = 20
lr = 0.01
J = []
for i in range(num_iter):y_pred = W.dot(X)loss = 1/(2*m) * np.sum((y-y_pred)**2)J.append(loss)W = W + lr * 1/m * (y-y_pred).dot(X.T)# 作图
y1 = W[0,0] + W[0,1]*1
y2 = W[0,0] + W[0,1]*20
plt.scatter(x, y)
plt.plot([1,20],[y1,y2])
plt.show()

这里只是画出了直线和数据集的表示,并不是拿了损失值优化直线的效果。怎么理解这句话呢,可能需要涉及到epoch概念,就好比我现在画出的直线就是一个模型,然后图中的点就是标签(测试集),可见我们的模型和这些点的距离很大,这个距离就是损失。我们拿着这个损失去优化下一个epoch,也就是下一次迭代中我们的直线就可以更好的拟合这些点。

我想说的是,你要分清损失函数起作用是在那个环节,上图显示的只是损失(真实-预测)的大小,并不是均方损失的大小。就是损失可能一般指两者间的距离,并不是损失函数。我们的MSE需要拿着损失再做一些计算,你不能看着上面的图就说是MSE损失函数,上面的图只是真实值与预测值的差距,也就是损失,并不是损失函数!

下面我们拿均方误差来进行优化w,看迭代20次后,分割的效果。原代码在下面。

可见我们20层后直线和数据的预测出现了较大的分割,为什么?这里我们通过debug模式发现计算后的损失很大,究其原因是一开始y - y_pred差距太大,而y_pred = X.dot(W)也就是第一层的时候w为0导致y_pred 等于0。这里就涉及初始化权重概念,请跳转链接。

这里我们需要先初始化权重,但是初始化后好像并没有解决问题。我们通过debug模式发现gradient很大,导致w变得很大,导致欠拟合了。欠拟合和过拟合是什么,请跳转链接

原先w:-50,b:-643

跳整后w:-27,b:-384

第一层接近很多了,但还是导致了梯度爆炸,什么是梯度爆炸,请跳转链接。

# 初始化参数
W = np.array([2.0, 3.0])  # 手动设定初始权重为 [2, 3]

看我们的预测好多了一点点。为什么一开始文章说需要根据数据集来选择不同的损失函数,这就一个方面,但是我们这里不在损失函数上的选择做文章,我们先通过初始化权重看能不能将直线更好的拟合数据。这里我们通过调整w初始值让gradient趋近于0,也就是第一层的损失接近于0。

W = np.array([1.5, 2.0])  # 调整1
W = np.array([4.0, 2.0])  # 后面再调整

由此可见拟合得很好了,但是这有什么意义呢?通过手动调参来使曲线拟合?首先分析问题出在这个梯度很大导致w变化很大,那么我们需要先解决梯度爆炸问题。

现在我们把权重重新设置为W = np.array([0.0, 0.0]),让模型产生梯度爆炸。梯度爆炸主要可以通过降低学习率、梯度裁剪、初始化权重、使用优化器、正则化、改变模型架构。

当我们将学习率调整到initial_lr = 0.001时发现,即使初始化权重为0可以拟合数据。

那么难道不是初始化权重的问题吗?怎么现在学习率更改了也能拟合曲线。我们寻找本质问题其实是由于损失值过大导致的。如果我们一开始的权重就比较好拟合曲线,那么损失值就不会太大,那么后期即使学习率很大,小损失*大学习率-》优化权重,权重变化不会很大,也就是会一值保持较低的损失。但是我们通过MSE评估模型时,发现损失并不是一直下降的。

正常情况下损失应该越来越小,单调递减的,而不是震荡的。导致震荡的原因就是学习率太大了。因此我们还需要调整学习率。那么我们直接调整学习率为什么也能解决问题,还是根据大损失*小学习率-》优化权重,这样我们的权重也不会出现很大变化,因此小的学习率也可以解决梯度爆炸的问题。

现在我们再来评估初始化权重最本质的作用。

当我们设置正常的学习率0.001

我们对比W = np.array([0.0, 0.0])和W = np.array([4.0, 2.0]) 导致MSE的变化。

发现MSE在一开始就变得很小,不会从700多往下降。也就是好的初始化权重能让模型拟合的更快,但是我们多训练很多层也可以拟合模型,只是有了初始化权重会拟合的更快。

这时候我们再来看这个w0w1,分别是4和2,这和我们制造数据集的公式的两个权重很接近?

y = 2 * x + 5 + np.random.normal(0, 4, size=x.shape) # y = 2x + 5 + 噪声

这个公式的两个权重分别是2和5,我们计算的是2和4,为什么没有完全拟合,这是因为你有噪声。如果我们把噪声去掉呢?

看!多完美的直线哈哈。然后我们也关注到他的损失降低到了0.2左右了,但是我们的w0和w1为什么还是4和2呢?

看起来还没有拟合,我们加多训练层数。当训练层数达到60时,w0变成了4.14了,更靠近5了。70层时达到了4.22。到72层发现损失变大了,75层变得更大,这种现象是什么?这是因为长期损失下降,我们不断增加学习率,导致后期的学习率过大,小梯度在大的学习率下也会时权重变化过大。这里我们加入loss在小于0.16的时候就不增加学习率。

if i > 0 and loss < loss_history[i - 1] and loss > 0.16:

但是我们看损失函数在后期还有较大的波动,我们把loss大于0.17就不会出现了。

    # 动态调整学习率if i > 0 and  loss < loss_history[i - 1] and loss > 0.17:# 如果损失下降,则增加学习率(但不超过最大学习率)initial_lr = min(initial_lr * lr_adjustment_factor, lr_max)else:# 如果损失没有下降,减少学习率(但不低于最小学习率)if loss < 0.17 and initial_lr < 0.003:initial_lr = 0.003initial_lr = max(initial_lr / lr_adjustment_factor, lr_min)

这时候我们再增加层数到190时,损失能继续下降,然后继续修改层数到2000次时,发现此时的w0达到4.9315,已经相当靠近5了。这差不多也就拟合我们的数据了。

但是我们的数据不可能一直这么完美,我们加入点噪声+ np.random.normal(0, 2, size=x.shape)

我们用提前中断的方式,获得一个好的训练效果。那么我们得到一个判断就是训练层数越多,模型越不稳定。很可能在拟合一定效果后得不到提升,这就要提到残差网络了,这里不涉及。

总结如下:

1损失函数是每一次迭代后,更新权重,因此你每次看到的回归直线和数据集间的差距并不是平均损失,而是预测值和真实值之间的差距。我们的损失函数是拿着个差距来计算,更新下次权重的过程。

2梯度爆炸跟学习率和学习步长有关,当然还有初始化权重、正则化、模型、梯度裁剪等方式相关。我们这里尝试了学习率、权重初始化、梯度裁剪等方式。

3梯度爆炸主要看loss曲线。

4训练层数太深了模型可能并不能得到提升

#源代码 

#源代码
import numpy as np
import matplotlib.pyplot as plt# 数据生成
np.random.seed(42)
x = np.linspace(1, 20, 40)
y = 2 * x + 5 + np.random.normal(0, 4, size=x.shape)  # y = 2x + 5 + 噪声# 添加常数项
X = np.vstack((np.ones_like(x), x)).T  # 引入常数项
m = len(x)# 初始化参数
W = np.zeros(2)  # 初始权重# 设置超参数
num_iter = 20 # 迭代次数
initial_lr = 0.01  # 初始学习率
lr_adjustment_factor = 1.05  # 学习率调整因子
lr_min = 0.001  # 最小学习率
lr_max = 0.2  # 最大学习率# 存储损失
loss_history = []# 训练模型
for i in range(num_iter):# 预测y_pred = X.dot(W)# 计算MSE损失loss = np.mean((y - y_pred) ** 2)loss_history.append(loss)# 计算梯度gradient = -2 * X.T.dot(y - y_pred) / m# 更新参数W -= initial_lr * gradient# 动态调整学习率if i > 0 and loss < loss_history[i - 1]:# 如果损失下降,则增加学习率(但不超过最大学习率)initial_lr = min(initial_lr * lr_adjustment_factor, lr_max)else:# 如果损失没有下降,减少学习率(但不低于最小学习率)initial_lr = max(initial_lr / lr_adjustment_factor, lr_min)# 每10步打印一次学习率if i % 10 == 0:print(f"Iteration {i+1}/{num_iter}, Loss: {loss:.4f}, Learning Rate: {initial_lr:.5f}")# 创建两个子图,进行并排显示
fig, ax = plt.subplots(1, 2, figsize=(12, 6))
# 输出最终权重
print(f"Final parameters: W0 = {W[0]}, W1 = {W[1]}")
# 绘制损失曲线
ax[0].plot(loss_history)
ax[0].set_xlabel('Iterations')
ax[0].set_ylabel('Loss (MSE)')
ax[0].set_title('Loss vs Iterations with Adaptive Learning Rate')# 绘制回归效果
y_pred_final = X.dot(W)
ax[1].scatter(x, y, label='Data')
ax[1].plot(x, y_pred_final, color='r', label='Fitted Line')
ax[1].set_xlabel('x')
ax[1].set_ylabel('y')
ax[1].set_title('Linear Regression with Adaptive Learning Rate')
ax[1].legend()plt.tight_layout()  # 自动调整子图间的间距
plt.show()

#修改后 

#修改后
import numpy as np
import matplotlib.pyplot as plt# 数据生成
np.random.seed(42)
x = np.linspace(1, 20, 40)
y = 2 * x + 5   # y = 2x + 5 + 噪声+ np.random.normal(0, 4, size=x.shape)# 添加常数项
X = np.vstack((np.ones_like(x), x)).T  # 引入常数项
m = len(x)# 初始化参数
W = np.array([4.0, 2.0])  # 手动设定初始权重为 [2, 3]
# regularization_strength = 0.01#加入正则化# 设置超参数
num_iter = 2000  # 迭代次数
initial_lr = 0.001  # 初始学习率
lr_adjustment_factor = 1.05  # 学习率调整因子
lr_min = 0.001  # 最小学习率
lr_max = 0.005  # 最大学习率# 存储损失
loss_history = []# 训练模型
for i in range(num_iter):# 预测y_pred = X.dot(W)# 计算MSE损失# loss = np.mean((y - y_pred) ** 2) + regularization_strength * np.sum(W**2)loss = np.mean((y - y_pred) ** 2)#MSE# loss = 1/m * np.sum(np.abs(y-y_pred))#MAE# loss = np.sqrt(1/m * np.sum((y - y_pred)**2))#均方根# epsilon = 1e-10  # 避免log(0)的错误 交叉熵 有误 放弃# loss = -np.mean(y * np.log(y_pred + epsilon))loss_history.append(loss)# 计算梯度gradient = -2 * X.T.dot(y - y_pred) / m# 更新参数W -= initial_lr * gradient# 动态调整学习率if i > 0 and  loss < loss_history[i - 1] and loss > 0.17:# 如果损失下降,则增加学习率(但不超过最大学习率)initial_lr = min(initial_lr * lr_adjustment_factor, lr_max)else:# 如果损失没有下降,减少学习率(但不低于最小学习率)if loss < 0.17 and initial_lr < 0.003:initial_lr = 0.003initial_lr = max(initial_lr / lr_adjustment_factor, lr_min)# 每10步打印一次学习率if i % 10 == 0:print(f"Iteration {i+1}/{num_iter}, Loss: {loss:.4f}, Learning Rate: {initial_lr:.5f}")# 创建两个子图,进行并排显示
fig, ax = plt.subplots(1, 2, figsize=(12, 6))
# 输出最终权重
print(f"Final parameters: W0 = {W[0]}, W1 = {W[1]}")
# 绘制损失曲线
ax[0].plot(loss_history)
ax[0].set_xlabel('Iterations')
ax[0].set_ylabel('Loss (MSE)')
ax[0].set_title('Loss vs Iterations with Adaptive Learning Rate')# 绘制回归效果
y_pred_final = X.dot(W)
ax[1].scatter(x, y, label='Data')
ax[1].plot(x, y_pred_final, color='r', label='Fitted Line')
ax[1].set_xlabel('x')
ax[1].set_ylabel('y')
ax[1].set_title('Linear Regression with Adaptive Learning Rate')
ax[1].legend()plt.tight_layout()  # 自动调整子图间的间距
plt.show()

平均绝对误差(Mean Absolute Error,MAE):绝对误差(MAE)计算的是预测值与真实值之间差的绝对值的平均值。

相比于均方误差,平均绝对误差对于离群点惩罚力度没有MSE那么强烈,因为MSE没有进行平方,而MAE是对误差进行了平方。你可以将MSE直接替换成MAE,然后看一下最后的训练效果,我的2000层最后达到了4.9972,比MSE更接近。我们从损失值来判断两个函数的效果,发现MAE在训练中途上升了。而MSE的loss很快就小于0.17了,也就是很快学习率趋于0.003梯度截断了。这是为什么呢?

两个函数MSE比MAE更快降低loss,让学习率趋于稳定。但是我们还是遇到了一个老问题就是中途为什么损失值又上升了。我们是否可以做一些尝试来避免?其实究其原因还是在较低的损失了,还采用了较高的学习率导致的,即使我们采用了梯度截断。我们把这个截断提前或许可以解决这个问题,但是我们是否可以设置一个学习率最大值降低,这样就可以通过层数来弥补,也不会出现过大的学习率了。

这里我填报了lr_max = 0.005 # 最大学习率

我们看到MAE总是能比MSE更靠近真实值,我是这么认为的,因为MSE是平方,他对loss很敏感。而我们加入了小于0.17就开始减少学习率,也就是说MSE更容易超过0.17,他的步伐迈的比MAE大,因此在小的差距下处理的没有MAE细腻。

代码:

    # loss = np.mean((y - y_pred) ** 2)#MSEloss = 1/m * np.sum(np.abs(y-y_pred))#MAE

均方根误差

相比于MSE,由于最后进行开根,所以他的量纲和数据本身是一致的,可以更好理解,而MSE则是误差的平方,RMSE是误差的平方又开根号,维度是没有变化的,也就是量纲没有变化。在效果对于误差的惩罚力度没有MSE强。但是处理效果比MSE细腻。

loss = np.sqrt(1/m * np.sum((y - y_pred)**2))#均方根

这里我们对三个损失进行了比较,发现RMSE损失降低的最慢,得到的权重更接近于5

交叉熵

交叉熵适合用于处理概率问题,就是他比较适合那种归一化的问题,并且他会有两种y和(1-y)两种情况,适合二分类。

    # epsilon = 1e-10  # 避免log(0)的错误 交叉熵 有误 放弃# loss = -np.mean(y * np.log(y_pred + epsilon))#由于我们的是回归问题

这是每个样本进行的损失计算,因为y只有0和1两种可能,因此当y=1计算的是-ylog(y^),而右边部分因为(1-y)=0,所以只计算左边部分。

其次为什么是负号,这是因为我们的预测值y^是一个概率,只有0到1,log函数在0到1是负数,我们再加一个负号就是正数了,也就是说损失只有正号。

有人要问了,我们优化不是一个类似凸优化的计算吗,那梯度应该是有正有负的。其实我们的损失计算的只是一个差距,真正的方向(±)是要靠求导后去确定。

对数损失

对数损失其实和交叉熵损失一样。也就是我们上面那种更像是对数损失。

笔记回馈

  1. 什么梯度爆炸?(基础知识)

  2. 损失是什么?损失函数和损失的关系是什么?(基础知识)

  3. 请列举你知道的损失函数,并且公式是什么?他的缺点和优点是什么?适合什么任务?(面试会考)

  4. 要如何避免梯度爆炸?(面试会考)

逻辑回归中一些注意事项:

y = wx+b逻辑回归公式

这个是做线性回归用的,对于二分类,评分某个类别的概率需要用到激活函数西格玛

逻辑回归

逻辑回归的代价函数

梯度下降法

为什么损失函数会有两部分,我的猜想是二分类需要分别评估他是两种类别的损失,然后加起来。

对数损失和叫交叉熵损失

 如果需要更多学习资料可以打开【咸鱼】https://m.tb.cn/h.6h707H6?tk=rRbqVZ2WNdh HU926 
点击链接直接打开,三0元以下带你完成人脸识别、关键点识别、手势识别等多个项目,涵盖SVM、knn、yolov8、语义分割!!!零基础适合小白

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

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

相关文章

poll为什么使用poll_list链表结构而不是数组 - 深入内核源码分析

一&#xff1a;引言 在Linux内核中,poll机制是一个非常重要的I/O多路复用机制。它允许进程监视多个文件描述符,等待其中任何一个进入就绪状态。poll的内部实现使用了poll_list链表结构而不是数组,这个设计选择背后有其深层的技术考量。本文将从内核源码层面深入分析这个设计决…

使用 Azure AKS 保护 Kubernetes 部署的综合指南

企业不断寻求增强其软件开发和部署流程的方法。DevOps 一直是这一转型的基石,弥合了开发与运营之间的差距。然而,随着安全威胁日益复杂,将安全性集成到 DevOps 流水线(通常称为 DevSecOps)已变得势在必行。本指南深入探讨了如何使用 Azure Kubernetes 服务 (AKS) 来利用 D…

2025年常见渗透测试面试题-webshell免杀思路(题目+回答)

网络安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 webshell免杀思路 PHP免杀原理 webshell免杀测试&#xff1a; webshell免杀绕过方法&#xff1a; 编…

访问不到服务器上启动的llamafactory-cli webui

采用SSH端口转发有效&#xff0c;在Windows上面进行访问 在服务器上启动 llamafactory-cli webui 后&#xff0c;访问方式需根据服务器类型和网络环境选择以下方案&#xff1a; 一、本地服务器&#xff08;物理机/虚拟机&#xff09; 1. 直接访问 若服务器与操作设备处于同一…

基于 LSTM 的多特征序列预测-SHAP可视化!

往期精彩内容&#xff1a; 单步预测-风速预测模型代码全家桶-CSDN博客 半天入门&#xff01;锂电池剩余寿命预测&#xff08;Python&#xff09;-CSDN博客 超强预测模型&#xff1a;二次分解-组合预测-CSDN博客 VMD CEEMDAN 二次分解&#xff0c;BiLSTM-Attention预测模型…

C++ 编程指南35 - 为保持ABI稳定,应避免模板接口

一&#xff1a;概述 模板在 C 中是编译期展开的&#xff0c;不同模板参数会生成不同的代码&#xff0c;这使得模板类/函数天然不具备 ABI 稳定性。为了保持ABI稳定&#xff0c;接口不要直接用模板&#xff0c;先用普通类打个底&#xff0c;模板只是“外壳”&#xff0c;这样 AB…

【iOS】OC高级编程 iOS多线程与内存管理阅读笔记——自动引用计数(二)

自动引用计数 前言ARC规则所有权修饰符**__strong修饰符**__weak修饰符__unsafe_unretained修饰符__autoreleasing修饰符 规则属性数组 前言 上一篇我们主要学习了一些引用计数方法的内部实现&#xff0c;现在我们学习ARC规则。 ARC规则 所有权修饰符 OC中&#xff0c;为了处…

可信空间数据要素解决方案

可信空间数据要素解决方案 一、引言 随着数字经济的蓬勃发展&#xff0c;数据已成为重要的生产要素。可信空间数据要素解决方案旨在构建一个安全、可靠、高效的数据流通与应用环境&#xff0c;促进数据要素的合理配置和价值释放&#xff0c;推动各行业的数字化转型和创新发展…

mysql删除表后重建表报错Tablespace exists

版本 mysql:8.0.23 复现步骤 1、删除表 DROP TABLE IF EXISTS xxx_demo; 2、新建表 CREATE TABLE xxx_demo (id bigint NOT NULL AUTO_INCREMENT COMMENT 主键id,creator varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT COMMENT 创建者,c…

【Leetcode-Hot100】缺失的第一个正数

题目 解答 有一处需要注意&#xff0c;我使用注释部分进行交换值&#xff0c;报错&#xff1a;超出时间限制。有人知道是为什么吗&#xff1f;难道是先给nums[i]赋值后&#xff0c;从而改变了后一项的索引&#xff1f; class Solution(object):def firstMissingPositive(sel…

从单模态到多模态:五大模型架构演进与技术介绍

前言 1. ResNet — 残差神经网络背景核心问题与解决方案原理模型架构ResNet 系列变体技术创新与影响 2. ViT — Vision Transformer背景核心思想发展历程Transformer的起源&#xff1a;ViT的出现&#xff1a;ViT的进一步发展&#xff1a; 模型架构技术创新与影响 3. Swin Trans…

JavaScript事件循环

目录 JavaScript 执行机制与事件循环 一、同步与异步代码 1. 同步代码&#xff08;Synchronous Code&#xff09; 2. 异步代码&#xff08;Asynchronous Code&#xff09; 二、事件循环&#xff08;Event Loop&#xff09; 1. 核心组成 2. 事件循环基本流程 3. 运行机制…

Java Collection(7)——Iterable接口

1.Iterator接口 1.1 Iterator接口和其他集合类的关系 Java集合类中&#xff0c;Iterable接口属于顶层接口&#xff0c;除Map接口外&#xff0c;其他都实现了Iterable接口&#xff0c;这意味着它们都可以重写和使用Iterable接口中的方法 1.2 Iterable接口简介 在JDK1.7以前&a…

若依微服务版启动小程序后端

目录标题 本地启动&#xff0c;dev对应 nacos里的 xxx-xxx-dev配置文件 本地启动&#xff0c;dev对应 nacos里的 xxx-xxx-dev配置文件

STM32基础教程——DMA+ADC多通道

目录 前言 ​编辑 技术实现 连线图 代码实现 技术要点 实验结果 问题记录 前言 DMA(Direct Memory Access)直接存储器存取&#xff0c;用来提供在外设和存储器 之间或者存储器和存储器之间的高速数据传输。无需CPU干预&#xff0c;数据可以通过DMA快速地移动&#xff0…

23黑马产品经理Day01

今天过了一遍23黑马产品经理的基础视频 问题思考维度 抓住核心用户 为什么需要抓住核心用户&#xff1f; 主要原因&#xff1a;用户越来越细分&#xff0c;保持市场竞争力&#xff0c;产品开发推广更聚焦 做产品为什么要了解用户&#xff1a;了解用户的付费点&#xff0c;…

C/C++ 通用代码模板

✅ C 语言代码模板&#xff08;main.c&#xff09; 适用于基础项目、算法竞赛或刷题&#xff1a; #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdbool.h> #include <math.h>// 宏定义区 #define MAX_N 1000 #defi…

【数据结构_7】栈和队列(上)

一、概念 栈和队列&#xff0c;也是基于顺序表和链表实现的 栈是一种特殊的线性表&#xff0c;其只允许在固定的一段进行插入和删除元素操作。 遵循后进先出的原则 此处所见到的栈&#xff0c;本质上就是一个顺序表/链表&#xff0c;但是&#xff0c;实在顺序表/链表的基础…

git UserInterfaceState.xcuserstate 文件频繁更新

1> 退出 Xcdoe&#xff0c;打开终端&#xff08;Terminal&#xff09;&#xff0c;进入到你的项目目录下。 2> 在终端键入 git rm --cached <YourProjectName>.xcodeproj/project.xcworkspace/xcuserdata/<YourUsername>.xcuserdatad/UserInterfaceState.x…

【Ai】MCP实战:手写 client 和 server [Python版本]

什么是mcp MCP 是一个开放协议&#xff0c;它为应用程序向 LLM 提供上下文的方式进行了标准化。你可以将 MCP 想象成 AI 应用程序的 USB-C 接口。就像 USB-C 为设备连接各种外设和配件提供了标准化的方式一样&#xff0c;MCP 为 AI 模型连接各种数据源和工具提供了标准化的接口…