当前位置: 首页 > news >正文

深度学习中的EMA技术:原理、实现与实验分析

深度学习中的EMA技术:原理、实现与实验分析

1. 引言

指数移动平均(Exponential Moving Average, EMA)是深度学习中一种重要的模型参数平滑技术。本文将通过理论分析和实验结果,深入探讨EMA的实现和效果。

深度学习中的EMA技术:原理、实现与实验分析

1. 引言

指数移动平均(Exponential Moving Average, EMA)是深度学习中一种重要的模型参数平滑技术。在深度学习模型训练过程中,由于随机梯度下降的随机性以及数据分布的差异,模型参数往往会出现较大的波动。这种波动可能导致模型性能不稳定,影响最终的预测效果。EMA通过对模型参数进行时间维度上的平滑,能够有效减少参数波动,提升模型的稳定性和泛化能力。

1.1 研究背景

深度学习模型训练面临的主要挑战:

  1. 参数波动

    • 随机梯度下降带来的随机性
    • mini-batch训练导致的梯度方差
    • 学习率调整引起的震荡
  2. 过拟合风险

    • 模型容量过大
    • 训练数据有限
    • 噪声干扰
  3. 泛化性能

    • 训练集和测试集分布差异
    • 模型鲁棒性不足
    • 预测稳定性差

1.2 EMA的优势

EMA技术通过参数平滑来解决上述问题:

  1. 减少波动

    • 时间维度上的加权平均
    • 平滑历史参数信息
    • 降低随机性影响
  2. 提升稳定性

    • 参数轨迹更平滑
    • 预测结果更稳定
    • 减少异常波动
  3. 改善泛化

    • 综合历史信息
    • 避免过度拟合局部特征
    • 提高模型鲁棒性

2. EMA原理

2.1 数学基础

EMA的核心思想是对参数进行指数加权平均。给定时刻t的模型参数 θ t \theta_t θt,EMA参数 θ t ′ \theta_t' θt的计算公式为:

θ t ′ = β ⋅ θ t − 1 ′ + ( 1 − β ) ⋅ θ t \theta_t' = \beta \cdot \theta_{t-1}' + (1 - \beta) \cdot \theta_t θt=βθt1+(1β)θt

其中:

  • θ t ′ \theta_t' θt 是t时刻的参数平均值
  • θ t \theta_t θt 是t时刻的实际参数值
  • β \beta β 是平滑系数(通常接近1)

这个公式可以展开为:

θ t ′ = ( 1 − β ) ⋅ [ θ t + β θ t − 1 + β 2 θ t − 2 + β 3 θ t − 3 + . . . ] \theta_t' = (1-\beta) \cdot [\theta_t + \beta\theta_{t-1} + \beta^2\theta_{t-2} + \beta^3\theta_{t-3} + ...] θt=(1β)[θt+βθt1+β2θt2+β3θt3+...]

从展开式可以看出:

  1. 越近期的参数权重越大
  2. 历史参数的影响呈指数衰减
  3. β \beta β控制了历史信息的保留程度

2.2 理论分析

  1. 偏差修正

在训练初期,由于缺乏足够的历史信息,EMA会产生偏差。通过偏差修正可以得到无偏估计:

θ t , c o r r e c t e d ′ = θ t ′ 1 − β t \theta_{t,corrected}' = \frac{\theta_t'}{1 - \beta^t} θt,corrected=1βtθt

  1. 动态特性

EMA可以看作一个低通滤波器,其截止频率与 β \beta β相关:

  • β \beta β越大,滤波效果越强,平滑程度越高
  • β \beta β越小,对新数据的响应越快,但平滑效果减弱
  1. 收敛性分析

假设参数序列 θ t {\theta_t} θt收敛到 θ ∗ \theta^* θ,则EMA序列 θ t ′ {\theta_t'} θt也将收敛到 θ ∗ \theta^* θ

lim ⁡ t → ∞ θ t ′ = θ ∗ \lim_{t \to \infty} \theta_t' = \theta^* tlimθt=θ

2.3 关键特性

  1. 计算效率

    • 只需存储一份参数副本
    • 计算复杂度O(1)
    • 内存开销小
  2. 自适应性

    • 自动调整权重分配
    • 适应参数变化速度
    • 保持历史信息
  3. 实现简单

    • 无需复杂的数据结构
    • 易于集成到现有模型
    • 训练过程透明
  4. 超参数少

    • 主要调节 β \beta β
    • 预热期设置
    • 更新频率选择

2.4 与其他技术的比较

  1. 简单移动平均(SMA)

    • EMA权重递减
    • SMA权重均等
    • EMA对新数据更敏感
  2. 随机权重平均(SWA)

    • EMA连续更新
    • SWA周期采样
    • EMA实现更简单
  3. 模型集成

    • EMA参数层面平均
    • 集成预测层面平均
    • EMA计算开销更小

3. 实验设置

3.1 实验脚本

import torch
import torch.nn as nn
import torch.optim as optim
from sklearn.model_selection import train_test_split
from sklearn.datasets import make_regression
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import r2_score, mean_absolute_error, mean_squared_error
import matplotlib.pyplot as plt
import numpy as np
import copydef exists(val):return val is not Nonedef clamp(value, min_value=None, max_value=None):assert exists(min_value) or exists(max_value)if exists(min_value):value = max(value, min_value)if exists(max_value):value = min(value, max_value)return valueclass EMA(nn.Module):"""Implements exponential moving average shadowing for your model.Utilizes an inverse decay schedule to manage longer term training runs.By adjusting the power, you can control how fast EMA will ramp up to your specified beta.@crowsonkb's notes on EMA Warmup:If gamma=1 and power=1, implements a simple average. gamma=1, power=2/3 aregood values for models you plan to train for a million or more steps (reaches decayfactor 0.999 at 31.6K steps, 0.9999 at 1M steps), gamma=1, power=3/4 for modelsyou plan to train for less (reaches decay factor 0.999 at 10K steps, 0.9999 at215.4k steps).Args:inv_gamma (float): Inverse multiplicative factor of EMA warmup. Default: 1.power (float): Exponential factor of EMA warmup. Default: 1.min_value (float): The minimum EMA decay rate. Default: 0."""def __init__(self,model,ema_model=None,# if your model has lazylinears or other types of non-deepcopyable modules, you can pass in your own ema modelbeta=0.9999,update_after_step=100,update_every=10,inv_gamma=1.0,power=2 / 3,min_value=0.0,param_or_buffer_names_no_ema=set(),ignore_names=set(),ignore_startswith_names=set(),include_online_model=True# set this to False if you do not wish for the online model to be saved along with the ema model (managed externally)):super().__init__()self.beta = beta# whether to include the online model within the module tree, so that state_dict also saves itself.include_online_model = include_online_modelif include_online_model:self.online_model = modelelse:self.online_model = [model]  # hack# ema modelself.ema_model = ema_modelif not exists(self.ema_model):try:self.ema_model = copy.deepcopy(model)except:print('Your model was not copyable. Please make sure you are not using any LazyLinear')exit()self.ema_model.requires_grad_(False)self.parameter_names = {name for name, param in self.ema_model.named_parameters() if param.dtype == torch.float}self.buffer_names = {name for name, buffer in self.ema_model.named_buffers() if buffer.dtype == torch.float}self.update_every = update_everyself.update_after_step = update_after_stepself.inv_gamma = inv_gammaself.power = powerself.min_value = min_valueassert isinstance(param_or_buffer_names_no_ema, (set, list))self.param_or_buffer_names_no_ema = param_or_buffer_names_no_ema  # parameter or bufferself.ignore_names = ignore_namesself.ignore_startswith_names = ignore_startswith_namesself.register_buffer('initted', torch.Tensor([False]))self.register_buffer('step', torch.tensor([0]))@propertydef model(self):return self.online_model if self.include_online_model else self.online_model[0]def restore_ema_model_device(self):device = self.initted.deviceself.ema_model.to(device)def get_params_iter(self, model):for name, param in model.named_parameters():if name not in self.parameter_names:continueyield name, paramdef get_buffers_iter(self, model):for name, buffer in model.named_buffers():if name not in self.buffer_names:continueyield name, bufferdef copy_params_from_model_to_ema(self):for (_, ma_params), (_, current_params) in zip(self.get_params_iter(self.ema_model),self.get_params_iter(self.model)):ma_params.data.copy_(current_params.data)for (_, ma_buffers), (_, current_buffers) in zip(self.get_buffers_iter(self.ema_model),self.get_buffers_iter(self.model)):ma_buffers.data.copy_(current_buffers.data)def get_current_decay(self):epoch = clamp(self.step.item() - self.update_after_step - 1, min_value=0.)value = 1 - (1 + epoch / self.inv_gamma) ** - self.powerif epoch <= 0:return 0.return clamp(value, min_value=self.min_value, max_value=self.beta)def update(self):step = self.step.item()self.step += 1if (step % self.update_every) != 0:returnif step <= self.update_after_step:self.copy_params_from_model_to_ema()returnif not self.initted.item():self.copy_params_from_model_to_ema()self.initted.data.copy_(torch.Tensor([True]))self.update_moving_average(self.ema_model, self.model)@torch.no_grad()def update_moving_average(self, ma_model, current_model):current_decay = self.get_current_decay()for (name, current_params), (_, ma_params) in zip(self.get_params_iter(current_model),self.get_params_iter(ma_model)):if name in self.ignore_names:continueif any([name.startswith(prefix) for prefix in self.ignore_startswith_names]):continueif name in self.param_or_buffer_names_no_ema:ma_params.data.copy_(current_params.data)continuema_params.data.lerp_(current_params.data, 1. - current_decay)for (name, current_buffer), (_, ma_buffer) in zip(self.get_buffers_iter(current_model),self.get_buffers_iter(ma_model)):if name in self.ignore_names:continueif any([name.startswith(prefix) for prefix in self.ignore_startswith_names]):continueif name in self.param_or_buffer_names_no_ema:ma_buffer.data.copy_(current_buffer.data)continuema_buffer.data.lerp_(current_buffer.data, 1. - current_decay)def __call__(self, *args, **kwargs):return self.ema_model(*args, **kwargs)# 数据准备
X, y = make_regression(n_samples=2000, n_features=20, noise=0.1, random_state=42)# 数据标准化
scaler_X = StandardScaler()
scaler_y = StandardScaler()X = scaler_X.fit_transform(X)
y = scaler_y.fit_transform(y.reshape(-1, 1))# 数据集分割
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=42)# 转换为 PyTorch 张量
X_train = torch.tensor(X_train, dtype=torch.float32)
y_train = torch.tensor(y_train, dtype=torch.float32)
X_val = torch.tensor(X_val, dtype=torch.float32)
y_val = torch.tensor(y_val, dtype=torch.float32)# 创建数据加载器
batch_size = 32
train_dataset = torch.utils.data.TensorDataset(X_train, y_train)
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
val_dataset = torch.utils.data.TensorDataset(X_val, y_val)
val_loader = torch.utils.data.DataLoader(val_dataset, batch_size=batch_size)# 改进的模型架构
class ImprovedModel(nn.Module):def __init__(self, input_dim):super(ImprovedModel, self).__init__()self.model = nn.Sequential(nn.Linear(input_dim, 64),nn.ReLU(),nn.Dropout(0.2),nn.Linear(64, 32),nn.ReLU(),nn.Dropout(0.2),nn.Linear(32, 1))# 初始化权重for m in self.modules():if isinstance(m, nn.Linear):nn.init.xavier_normal_(m.weight)nn.init.constant_(m.bias, 0)def forward(self, x):return self.model(x)# 评估函数
def evaluate_model(model, data_loader, criterion, device):model.eval()total_loss = 0predictions = []true_values = []with torch.no_grad():for X, y in data_loader:X, y = X.to(device), y.to(device)outputs = model(X)total_loss += criterion(outputs, y).item() * len(y)predictions.extend(outputs.cpu().numpy())true_values.extend(y.cpu().numpy())predictions = np.array(predictions)true_values = np.array(true_values)return {'loss': total_loss / len(data_loader.dataset),'mse': mean_squared_error(true_values, predictions),'mae': mean_absolute_error(true_values, predictions),'r2': r2_score(true_values, predictions)}# 训练函数
def train_one_epoch(model, train_loader, criterion, optimizer, ema, device):model.train()total_loss = 0for X, y in train_loader:X, y = X.to(device), y.to(device)optimizer.zero_grad()outputs = model(X)loss = criterion(outputs, y)loss.backward()optimizer.step()# 更新EMAema.update()total_loss += loss.item() * len(y)return total_loss / len(train_loader.dataset)# 设置设备
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')# 创建模型实例
model = ImprovedModel(input_dim=X_train.shape[1]).to(device)# 创建EMA实例
ema = EMA(model,beta=0.999,update_after_step=100,update_every=1,power=2/3
)# 定义损失函数和优化器
criterion = nn.MSELoss()
optimizer = optim.Adam(model.parameters(), lr=0.001, weight_decay=1e-5)
scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='min', factor=0.5, patience=10, verbose=True)# 训练参数
num_epochs = 500
best_val_loss = float('inf')
patience = 20
patience_counter = 0# 记录训练历史
history = {'train_loss': [],'val_loss_original': [],'val_loss_ema': [],'r2_original': [],'r2_ema': []
}# 训练循环
for epoch in range(num_epochs):# 训练阶段train_loss = train_one_epoch(model, train_loader, criterion, optimizer, ema, device)# 评估阶段original_metrics = evaluate_model(model, val_loader, criterion, device)ema_metrics = evaluate_model(ema.ema_model, val_loader, criterion, device)# 更新学习率scheduler.step(ema_metrics['loss'])# 记录历史history['train_loss'].append(train_loss)history['val_loss_original'].append(original_metrics['loss'])history['val_loss_ema'].append(ema_metrics['loss'])history['r2_original'].append(original_metrics['r2'])history['r2_ema'].append(ema_metrics['r2'])# 早停检查if ema_metrics['loss'] < best_val_loss:best_val_loss = ema_metrics['loss']patience_counter = 0else:patience_counter += 1if patience_counter >= patience:print(f"Early stopping at epoch {epoch+1}")break# 打印进度if (epoch + 1) % 10 == 0:print(f"\nEpoch [{epoch+1}/{num_epochs}]")print(f"Train Loss: {train_loss:.4f}")print(f"Original Val Loss: {original_metrics['loss']:.4f}, R2: {original_metrics['r2']:.4f}")print(f"EMA Val Loss: {ema_metrics['loss']:.4f}, R2: {ema_metrics['r2']:.4f}")# 绘制训练历史
plt.figure(figsize=(15, 5))# 损失曲线
plt.subplot(1, 2, 1)
plt.plot(history['train_loss'], label='Train Loss')
plt.plot(history['val_loss_original'], label='Original Val Loss')
plt.plot(history['val_loss_ema'], label='EMA Val Loss')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.title('Training and Validation Losses')
plt.legend()
plt.grid(True)# R2分数曲线
plt.subplot(1, 2, 2)
plt.plot(history['r2_original'], label='Original R2')
plt.plot(history['r2_ema'], label='EMA R2')
plt.xlabel('Epoch')
plt.ylabel('R2 Score')
plt.title('R2 Scores')
plt.legend()
plt.grid(True)plt.tight_layout()
plt.show()# 最终评估
final_original_metrics = evaluate_model(model, val_loader, criterion, device)
final_ema_metrics = evaluate_model(ema.ema_model, val_loader, criterion, device)print("\n=== Final Results ===")
print("\nOriginal Model:")
print(f"MSE: {final_original_metrics['mse']:.4f}")
print(f"MAE: {final_original_metrics['mae']:.4f}")
print(f"R2 Score: {final_original_metrics['r2']:.4f}")print("\nEMA Model:")
print(f"MSE: {final_ema_metrics['mse']:.4f}")
print(f"MAE: {final_ema_metrics['mae']:.4f}")
print(f"R2 Score: {final_ema_metrics['r2']:.4f}")

4. 实验结果与分析

在这里插入图片描述

4.1 训练过程数据

EpochTrain LossOriginal Val LossOriginal R2EMA Val LossEMA R2
100.08430.02090.97960.02330.9773
200.05360.01000.99020.01100.9892
300.03980.00550.99470.00750.9927
400.03670.00430.99580.00510.9950
500.03690.00370.99640.00510.9951
600.02970.00530.99490.00410.9960
700.02710.00530.99480.00430.9958
800.02510.00520.99500.00440.9957
900.02740.00510.99500.00440.9957

4.2 训练过程分析

  1. 初期阶段(1-30 epoch)

    • 训练损失从0.0843快速下降到0.0398
    • EMA模型初期表现略逊于原始模型
    • 两个模型的R2分数都实现了快速提升
  2. 中期阶段(30-60 epoch)

    • 训练趋于稳定,损失下降速度减缓
    • 在第50轮时,原始模型达到最佳验证损失0.0037
    • EMA模型开始展现优势,在第60轮超越原始模型
  3. 后期阶段(60-97 epoch)

    • EMA模型持续保持更好的性能
    • 验证损失和R2分数趋于稳定
    • 在97轮触发早停机制

4.3 性能对比

指标原始模型EMA模型改进幅度
MSE0.00550.004420.0%
MAE0.05810.05269.5%
R20.99460.99570.11%

4.4 关键观察

  1. 收敛特性

    • EMA模型展现出更平滑的收敛曲线
    • 训练过程中波动明显小于原始模型
    • 最终性能优于原始模型
  2. 稳定性分析

    标准差比较:
    - 原始模型验证损失标准差:0.0023
    - EMA模型验证损失标准差:0.0015
    
  3. 早停现象

    • 在97轮触发早停
    • 表明模型达到最优性能
    • 避免了过拟合风险

4.5 可视化分析

从训练曲线图可以观察到:

  1. 损失曲线

    • 训练损失(蓝线)整体呈下降趋势
    • EMA验证损失(绿线)波动小于原始验证损失(红线)
    • 后期EMA曲线始终低于原始模型曲线
  2. R2分数曲线

    • 两条曲线都呈现快速上升后平稳的趋势
    • EMA模型在后期表现更稳定
    • 最终R2分数都达到了0.99以上

4.6 结论

实验结果表明EMA技术能够:

  1. 提供更稳定的训练过程
  2. 降低模型预测误差
  3. 改善最终模型性能

特别是在训练后期,EMA模型展现出明显优势:

  • MSE降低20%
  • MAE降低9.5%
  • R2分数提升0.11%

这些改进证实了EMA在深度学习模型训练中的有效性。

相关文章:

深度学习中的EMA技术:原理、实现与实验分析

深度学习中的EMA技术&#xff1a;原理、实现与实验分析 1. 引言 指数移动平均(Exponential Moving Average, EMA)是深度学习中一种重要的模型参数平滑技术。本文将通过理论分析和实验结果&#xff0c;深入探讨EMA的实现和效果。 深度学习中的EMA技术&#xff1a;原理、实现与…...

win32汇编环境,窗口程序中对按钮控件常用操作的示例

;运行效果 ;win32汇编环境&#xff0c;窗口程序中对按钮控件常用操作的示例 ;常用的操作&#xff0c;例如创建按钮控件&#xff0c;使其无效&#xff0c;改变文本&#xff0c;得到文本等。 ;将代码复制进radasm软件里&#xff0c;直接就可以编译运行。重点部分加备注。 ;>&g…...

CentOS 7.9 通过 yum 安装 Docker

文章目录 前言一、删除已安装的 Docker二、网络设置三、设置 yum 源&#xff0c;并安装依赖四、设置 Docker 仓库五、安装及使用 Docker六、镜像仓库总结 前言 CentOS 7.9 过了维护期&#xff0c;Docker 官方文档没有了相关的安装文档。记录一下&#xff0c;备用&#xff01; …...

【开源免费】基于Vue和SpringBoot的英语知识应用网站(附论文)

本文项目编号 T 138 &#xff0c;文末自助获取源码 \color{red}{T138&#xff0c;文末自助获取源码} T138&#xff0c;文末自助获取源码 目录 一、系统介绍二、数据库设计三、配套教程3.1 启动教程3.2 讲解视频3.3 二次开发教程 四、功能截图五、文案资料5.1 选题背景5.2 国内…...

工具推荐:PDFgear——免费且强大的PDF编辑工具 v2.1.12

PDFgear——免费且强大的PDF编辑工具 v2.1.12 软件简介 PDFgear 是一款 完全免费的 PDF 软件&#xff0c;支持 阅读、编辑、转换、合并 以及 跨设备签署 PDF 文件&#xff0c;无需注册即可使用。它提供了丰富的 PDF 处理功能&#xff0c;极大提升了 PDF 文件管理的便捷性和效…...

Web渗透测试之XSS跨站脚本 防御[WAF]绕过手法

目录 XSS防御绕过汇总 参考这篇文章绕过 XSS payload XSS防御绕过汇总 服务端知道有网络攻击或者xss攻 Html...

MMDetection框架下的常见目标检测与分割模型综述与实践指南

目录 综述与实践指南 SSD (Single Shot MultiBox Detector) 基本配置和使用代码 RetinaNet 基本配置和使用代码 Faster R-CNN 基本配置和使用代码 Mask R-CNN 基本配置和使用代码 Cascade R-CNN 基本配置和使用代码 总结 综述与实践指南 MMDetection是一个基于Py…...

怎么实现Redis的高可用?

大家好&#xff0c;我是锋哥。今天分享关于【怎么实现Redis的高可用&#xff1f;】面试题。希望对大家有帮助&#xff1b; 怎么实现Redis的高可用&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 为了实现 Redis 的高可用性&#xff0c;我们需要保证在发…...

OpenCV实现Kuwahara滤波

Kuwahara滤波是一种非线性的平滑滤波技术&#xff0c;其基本原理在于通过计算图像模板中邻域内的均值和方差&#xff0c;选择图像灰度值较为均匀的区域的均值来替代模板中心像素的灰度值。以下是Kuwahara滤波的详细原理说明&#xff1a; 一、基本思想 Kuwahara滤波的基本思想…...

WINFORM - DevExpress -> DevExpress总结[安装、案例]

安装devexpress软件 路径尽量不换&#xff0c;后面破解不容易出问题 vs工具箱添加控件例如: ①使用控制台进入DevExpress安装目录: cd C:\Program Files (x86)\DevExpress 20.1\Components\Tools ②添加DevExpress控件&#xff1a; ToolboxCreator.exe/ini:toolboxcreator…...

Golang学习笔记_22——Reader示例

Golang学习笔记_19——Stringer Golang学习笔记_20——error Golang学习笔记_21——Reader 文章目录 io.Reader 示例从字符串中读取从文件中读取从HTTP响应中读取从内存的字节切片中读取自定义io.Reader实现 源码 io.Reader 示例 从字符串中读取 func ReadFromStrDemo() {str…...

【2024年华为OD机试】(A卷,100分)- 猜字谜(Java JS PythonC/C++)

一、问题描述 小王设计了一个简单的猜字谜游戏&#xff0c;游戏的谜面是一个错误的单词&#xff0c;比如 nesw&#xff0c;玩家需要猜出谜底库中正确的单词。猜中的要求如下&#xff1a; 对于某个谜面和谜底单词&#xff0c;满足下面任一条件都表示猜中&#xff1a; 变换顺序…...

iostat命令详解

iostat 命令是 I/O statistics(输入/输出统计)的缩写&#xff0c;用来报告系统的 CPU 统计信息和块设备及其分区的 IO 统计信息。iostat 是 sysstat 工具集的一个工具&#xff0c;在 Ubuntu 系统中默认是不带 iostat 命令的&#xff0c;需要自行安装&#xff1a; $ sudo apt in…...

Linux:操作系统简介

前言&#xff1a; 在本片文章&#xff0c;小编将带大家理解冯诺依曼体系以及简单理解操作喜欢&#xff0c;并且本篇文章将围绕什么以及为什么两个话题进行展开说明。 冯诺依曼体系&#xff1a; 是什么&#xff1a; 冯诺依曼体系&#xff08;Von Neumann architecture&#xff…...

企业级信息系统开发讲课笔记4.12 Spring Boot默认缓存管理

文章目录 1. Spring Boot默认缓存管理2. Spring的缓存机制2.1 缓存机制概述2.2 缓存接口和缓存管理接口3. 声明式缓存注解3.1 @EnableCaching注解3.2 @Cacheable注解3.2.1 value/cacheNames属性3.2.2 key属性3.2.3 keyGenerator属性3.2.4 cacheManager/cacheResolver属性3.2.5 …...

2025制定一个高级java开发路线:分布式系统、多线程编程、高并发经验

1-熟悉分布式系统的设计和应用&#xff0c;熟悉分布式、缓存、消息、负载均衡等机制和实现者优先。 2-熟悉多线程编程&#xff0c;具备高并发经验优先。 技术学习规划&#xff1a;熟悉分布式系统和高并发技术 以下是针对目标要求的系统性学习规划&#xff0c;分为 阶段目标 和…...

20250110_ PyTorch中的张量操作

文章目录 前言1、torch.cat 函数2、索引、维度扩展和张量的广播3、切片操作3.1、 encoded_first_node3.2、probs 4、长难代码分析4.1、selected4.1.1、multinomial(1)工作原理&#xff1a; 总结 前言 1、torch.cat 函数 torch.cat 函数将两个张量拼接起来&#xff0c;具体地是…...

hadoop-yarn常用命令

一、YARN命令介绍 1. YARN命令简介 YARN提供了一组命令行工具&#xff0c;用于管理和监控YARN应用程序和集群。 2. yarn application命令 (1) yarn application命令的基本语法 yarn application命令的基本语法如下&#xff1a; yarn application [genericOptions] [comma…...

LabVIEW滤波器功能

程序通过LabVIEW生成一个带噪声的正弦波信号&#xff0c;并利用滤波器对其进行信号提取。具体来说&#xff0c;它生成一个正弦波信号&#xff0c;叠加高频噪声后形成带噪信号&#xff0c;再通过低通滤波器滤除噪声&#xff0c;提取原始正弦波信号。整个过程展示了信号生成、噪声…...

【Unity3D日常开发】Unity3D中打开Window文件对话框打开文件(PC版)

推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享QQ群&#xff1a;398291828小红书小破站 大家好&#xff0c;我是佛系工程师☆恬静的小魔龙☆&#xff0c;不定时更新Unity开发技巧&#xff0c;觉得有用记得一键三连哦。 一、前言 这篇文章继续讲如何使用Unity3D打开Window文…...

HTML 语义化

目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案&#xff1a; 语义化标签&#xff1a; <header>&#xff1a;页头<nav>&#xff1a;导航<main>&#xff1a;主要内容<article>&#x…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密

在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

【JVM】- 内存结构

引言 JVM&#xff1a;Java Virtual Machine 定义&#xff1a;Java虚拟机&#xff0c;Java二进制字节码的运行环境好处&#xff1a; 一次编写&#xff0c;到处运行自动内存管理&#xff0c;垃圾回收的功能数组下标越界检查&#xff08;会抛异常&#xff0c;不会覆盖到其他代码…...

LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》

这段 Python 代码是一个完整的 知识库数据库操作模块&#xff0c;用于对本地知识库系统中的知识库进行增删改查&#xff08;CRUD&#xff09;操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 &#x1f4d8; 一、整体功能概述 该模块…...

CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!

本文介绍了一种名为AnomalyAny的创新框架&#xff0c;该方法利用Stable Diffusion的强大生成能力&#xff0c;仅需单个正常样本和文本描述&#xff0c;即可生成逼真且多样化的异常样本&#xff0c;有效解决了视觉异常检测中异常样本稀缺的难题&#xff0c;为工业质检、医疗影像…...

图解JavaScript原型:原型链及其分析 | JavaScript图解

​​ 忽略该图的细节&#xff08;如内存地址值没有用二进制&#xff09; 以下是对该图进一步的理解和总结 1. JS 对象概念的辨析 对象是什么&#xff1a;保存在堆中一块区域&#xff0c;同时在栈中有一块区域保存其在堆中的地址&#xff08;也就是我们通常说的该变量指向谁&…...

6.9-QT模拟计算器

源码: 头文件: widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QMouseEvent>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent nullptr);…...

数据结构第5章:树和二叉树完全指南(自整理详细图文笔记)

名人说&#xff1a;莫道桑榆晚&#xff0c;为霞尚满天。——刘禹锡&#xff08;刘梦得&#xff0c;诗豪&#xff09; 原创笔记&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 上一篇&#xff1a;《数据结构第4章 数组和广义表》…...

Spring AOP代理对象生成原理

代理对象生成的关键类是【AnnotationAwareAspectJAutoProxyCreator】&#xff0c;这个类继承了【BeanPostProcessor】是一个后置处理器 在bean对象生命周期中初始化时执行【org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization】方法时…...