深度学习——超参数调优

news2025/5/25 8:37:29

第一部分:什么是超参数?为什么要调优?

一、参数 vs 超参数(Parameter vs Hyperparameter)

类型定义举例是否通过训练自动学习?
参数(Parameter)是模型在训练过程中通过反向传播自动学习到的变量权重(Weights)、偏置(Biases) 是
超参数(Hyperparameter)是在训练开始前由人工指定的控制模型结构或训练方式的变量学习率、Batch Size、网络层数等 否

 一句话理解:

参数是模型自动“学”的,超参数是你手动“设”的。


二、为什么超参数调优如此重要?

超参数对训练过程的影响巨大。一个合理的超参数组合可能让模型快速收敛、泛化能力强;而不合适的设置可能导致:

  • 模型不收敛

  • 过拟合欠拟合

  • 训练速度极慢

  • 浪费大量资源与时间

举例说明:
  • 学习率太大 ➜ loss 震荡甚至发散

  • 学习率太小 ➜ loss 降得极慢,浪费时间

  • 网络太深 ➜ 训练困难,可能过拟合

  • Batch Size 太小 ➜ 收敛不稳定;太大 ➜ 内存吃紧


三、超参数调优的目标

调优的目标是找到一组最优超参数组合,使得模型在验证集上表现最优(即泛化能力强),而不是仅仅在训练集上表现好。

评估标准可能包括:
  • Accuracy(分类任务)

  • mIoU、Dice(分割任务)

  • Loss 曲线收敛速度

  • 参数/资源效率(比如在一定内存限制下的最好结果)


四、超参数分类示意图

                    超参数
                       │
  ┌────────────────────┼─────────────────────┐
  │                    │                     │
模型结构超参数     优化器超参数       训练过程超参数
(例如层数、宽度) (例如学习率、动量) (例如BatchSize、Epoch)

五、为什么不能“一次性设好”?

  1. 模型复杂非线性:超参数之间有复杂的相互作用(例如:Batch Size 和学习率不是独立的)。

  2. 任务差异:不同任务需要的超参数不同,例如图像分类 vs 图像分割。

  3. 数据集变化:数据大小、类别不均衡性都会影响超参数效果。

  4. 计算资源限制:硬件条件约束下无法盲目使用大模型、大Batch。


六、小结

重点回顾
 参数是学出来的,超参数是设出来的
 不同超参数影响训练不同方面(结构、优化、效率)
超参数调优的目标是提升模型泛化性能
 一个合理的超参数组合可能带来质变的性能提升

第二部分:常见的超参数类型

深度学习中涉及大量超参数,我们可以从三个维度来进行分类讲解:

分类维度包含超参数
模型结构相关网络层数、每层宽度、激活函数等
优化器相关学习率、动量、权重衰减、调度器等
训练过程相关Batch Size、Epoch、Dropout、正则化等

 一、模型结构相关超参数

 网络层数(Depth)
  • 定义:网络的“深度”,即堆叠了多少层神经网络。

  • 作用:

    • 更深的网络可以学习更复杂的特征。

    • 但过深会引发梯度消失/爆炸问题,训练困难。

  • 经验:

    • 小数据集或简单任务,浅网络(如3~5层)更稳妥。

    • 大数据集(如ImageNet)上可以使用 ResNet50/101 等深层网络。

  •  技巧:

    • 使用残差连接(ResNet)来训练更深的模型。

    • 在医学图像中,U-Net 结构的深度一般设置在4~5层左右。


 每层宽度(Width)
  • 定义:每一层神经元(或卷积通道)的数量。

  • 影响:

    • 控制模型的表达能力。

    • 太少容易欠拟合,太多可能过拟合且计算成本大。

  • 经验调节:

    • 卷积神经网络中,宽度通常从浅层的 64 逐渐加倍(如 64→128→256)。

    • 分类问题中,全连接层常用如 512、1024 等神经元。


 激活函数(Activation Function)
  • 常见选项:

    • ReLU:目前最常用,简单高效。

    • Leaky ReLU / PReLU:解决 ReLU 死亡问题。

    • Sigmoid:饱和慢,较少使用。

    • Tanh:比 Sigmoid 好些,但仍有梯度问题。

  •  实践建议:

    • 默认使用 ReLU 或 Leaky ReLU。

    • 对于输出层:

      • 分类:Softmax(多类),Sigmoid(二分类)

      • 分割:Sigmoid(二类掩膜),Softmax(多类掩膜)


 二、优化器相关超参数

 学习率(Learning Rate)
  • 训练中最关键的超参数,影响每一步参数更新的“幅度”。

  • 通常是调优的第一优先项

  • 值设得不合适可能:

    • 太小 → 训练慢,陷入局部最优;

    • 太大 → Loss 震荡甚至发散。

  • 典型值:

    • SGD:1e-2 ~ 1e-3

    • Adam:1e-3 ~ 1e-4

  •  建议:

    • 使用学习率调度器(如StepLR、CosineAnnealing)。


 动量(Momentum / β1 / β2)
  • 用于平滑梯度更新,防止震荡。

  • 在不同优化器中的形式:

    • SGD + Momentum:动量系数通常为 0.9。

    • Adam:β1 一般为 0.9,β2 一般为 0.999。

  • 不建议轻易更改,除非你很熟悉优化器行为。


 权重衰减(Weight Decay / L2 正则化)
  • 作用:防止过拟合,引入对权重大小的惩罚项。

  • 常设值:1e-5 ~ 1e-4。

  • 默认建议加上,可以提高泛化能力。


 学习率调度器(LR Scheduler)
  • 作用:在训练过程中动态调整学习率。

  • 常用策略:

    • StepLR: 每隔N个epoch乘以一个γ

    • CosineAnnealingLR: 余弦退火

    • ReduceLROnPlateau: 根据验证集Loss下降情况自动调整

  •  建议:

    • 推荐使用 CosineAnnealingLR + warmup 起步。


 三、训练过程相关超参数

 Batch Size
  • 决定每次梯度更新使用多少样本。

  • 大小影响:

    • 小 Batch(如 16、32):更噪声,收敛稳定性差但泛化强。

    • 大 Batch(如 128+):训练快但容易过拟合。

  • 实践建议:

    • 根据显存能力尽量调大,但通常不超过 256。

    • 注意学习率要跟 Batch Size 协调调整(比如大 Batch → 可增大学习率)。


 Epoch 数
  • 控制整个数据集被“看过”的轮数。

  • 太小 → 欠拟合,太大 → 过拟合。

  • 通常结合 EarlyStopping 或验证集监控动态决定训练时长。


 Dropout 比例
  • 防止过拟合的一种策略。

  • 建议值:0.3 ~ 0.5(不要超过0.7)

  • 不建议在卷积层用 Dropout(会破坏局部特征结构),常用于全连接层。


 正则化强度(L1 / L2)
  • L2(权重衰减)更常见,L1 可用于稀疏建模。

  • 多数情况下,设置一个小的 L2(如1e-4)即可。


 四、数据增强和预处理相关超参数

  • 例如图像翻转概率、亮度变化范围、裁剪尺寸等。

  • 合适的数据增强不仅能提升泛化能力,还能防止过拟合。

  • 医学图像中,增强不能过强,要考虑语义一致性。


 小结

超参数类别推荐调优顺序
学习率最重要,优先调
Batch Size次优先,影响显存
网络结构先简单→复杂,逐步加深
Dropout / 正则化防过拟合常用手段
LR Scheduler搭配学习率共同调整

第三部分:超参数调优方法论(策略、流程与工具)


 一、手动调参的经典策略(适合初期模型开发)

 原则:单变量控制 + 分阶段调优

不要一次改多个超参数。保持其他不变,逐个尝试,观察其对训练过程和验证集效果的影响。

 推荐调优顺序:
步骤优先级超参数类型说明
学习率首先确定模型是否能正常收敛
Batch Size尽可能大,但不爆显存为宜
优化器选择如 Adam、SGD+Momentum
LR Scheduler控制收敛速度和效果
网络结构小到大试试(层数/通道数)
Dropout、正则化控制过拟合

实战技巧举例:
  • 判断学习率设得好不好:

    • Loss 快速下降 → ✅

    • Loss 抖动大或直接发散 → 学习率太大 ❌

    • Loss 降得慢、像“爬坡”一样缓慢 → 学习率太小 ❌

  • 调整 Batch Size 后需要改学习率!

    • 经验公式:


 二、网格搜索(Grid Search)与随机搜索(Random Search)

这两个是传统的自动化调参策略,适用于搜索空间不大的情况。

网格搜索(Grid Search)
  • 穷举式搜索所有组合,例如:

    learning_rates = [0.01, 0.001, 0.0001]
    batch_sizes = [32, 64, 128]
    optimizers = [SGD, Adam]
    
  • 总共要跑 3×3×2 = 18 次实验。

  • 优点:简单直接,能找出局部最优组合。

  • 缺点:计算资源消耗大,不适合维度高或范围广的超参数。

随机搜索(Random Search)
  • 在设定的搜索范围内随机采样组合,减少计算量。

研究表明,在高维空间中,随机搜索通常比网格搜索更高效(Bergstra & Bengio, 2012)。

  • 举例:随机采样 10 组学习率+Batch组合,而不是穷举全部组合。


 三、贝叶斯优化(Bayesian Optimization)

原理简介:
  • 构建一个超参数 → 验证效果之间的“代理模型”,如高斯过程回归(Gaussian Process),预测某组合的效果。

  • 然后在代理模型中选择最可能带来提升的超参数组合继续试验。

  • 是一种智能搜索策略,相比随机或网格更节省时间与资源。

工具推荐:
  •  Optuna

    • 支持分布式、多目标优化、可视化。

    • 非常适合深度学习超参数调优。

    • 后面我可以手把手教你用它调 UNet 或 CNN。


 四、学习率自动查找(Learning Rate Finder)

让模型自动找到最适合的学习率区间!

PyTorch 中的实现(如 fastai 的 lr_find()):
  1. 从一个极小学习率开始,指数增长;

  2. 绘制 Learning Rate vs Loss 曲线;

  3. 选取 loss 急剧下降前的最小值处作为起始学习率。


 五、一周期学习率策略(One Cycle Policy)

学习率不是越低越好,而是在训练初期升高、中期降低,能获得更好泛化效果。

  • 论文:Super-Convergence(2018) by Leslie Smith

  • 支持:torch.optim.lr_scheduler.OneCycleLR

  • 特别适合图像分类、分割等任务。


六、逐步调优流程总结图(推荐收藏)

        ↓ 定义模型结构
        ↓
  设置初始学习率、Batch Size
        ↓
  ↻ 调整学习率找收敛区间(LR Finder)
        ↓
  ↻ 调整 Batch Size + 学习率联动
        ↓
  ↻ 调整优化器参数(Momentum、Decay)
        ↓
  ↻ 调度器(Cosine / Step)选择
        ↓
  ↻ 网络结构细节优化(层数/通道数)
        ↓
  ↻ 加入 Dropout、正则化、EarlyStopping
        ↓
  ↻ 自动搜索工具(Optuna / Ray Tune)

 小结:调参三大黄金建议

  1. 控制变量法永不过时: 每次只改一个,效果才可解释。

  2. 调参顺序讲策略: 先优化能显著提升效果的(学习率、Batch)。

  3. 自动化工具是加速器: 用得好能帮你节省大量资源。

代码部分

学习率查找器(LR Finder)

# 先安装:pip install torch-lr-finder
from torch_lr_finder import LRFinder

model = SimpleCNN().to(device)
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=1e-7, momentum=0.9)

lr_finder = LRFinder(model, optimizer, criterion, device=device)
lr_finder.range_test(train_loader, end_lr=1, num_iter=100)
lr_finder.plot()  # 画出Loss随LR变化曲线
lr_finder.reset() # 恢复模型参数

 通过观察曲线,找到 loss 降得最快且开始发散前的那个学习率,作为训练起始学习率。

Batch Size与学习率联动调节 

base_batch_size = 64
base_lr = 0.01

new_batch_size = 128
new_lr = base_lr * (new_batch_size / base_batch_size)

print(f"当 batch_size={new_batch_size} 时,建议学习率设置为 {new_lr}")

一周期学习率策略(One Cycle Policy)

from torch.optim.lr_scheduler import OneCycleLR

optimizer = optim.SGD(model.parameters(), lr=0.1, momentum=0.9)
scheduler = OneCycleLR(optimizer, max_lr=0.1, steps_per_epoch=len(train_loader), epochs=10)

for epoch in range(10):
    model.train()
    for batch_idx, (data, target) in enumerate(train_loader):
        data, target = data.to(device), target.to(device)
        optimizer.zero_grad()
        output = model(data)
        loss = criterion(output, target)
        loss.backward()
        optimizer.step()
        scheduler.step()  # 学习率自动调整

        if batch_idx % 100 == 0:
            print(f"Epoch {epoch} Batch {batch_idx} Loss: {loss.item():.4f} LR: {scheduler.get_last_lr()[0]:.6f}")

网格搜索(Grid Search)

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

# 简单CNN模型定义(同前)
class SimpleCNN(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1 = nn.Conv2d(3, 16, 3, padding=1)
        self.pool = nn.MaxPool2d(2)
        self.fc = nn.Linear(16*16*16, 10)

    def forward(self, x):
        x = self.pool(torch.relu(self.conv1(x)))
        x = x.view(x.size(0), -1)
        x = self.fc(x)
        return x

# 数据加载
transform = transforms.Compose([transforms.ToTensor()])
train_dataset = datasets.CIFAR10(root='./data', train=True, download=True, transform=transform)
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

# 网格搜索超参数空间
learning_rates = [0.01, 0.001]
momentums = [0.8, 0.9]
batch_sizes = [32, 64]

best_loss = float('inf')
best_params = {}

for lr in learning_rates:
    for momentum in momentums:
        for batch_size in batch_sizes:
            print(f"训练参数: LR={lr}, Momentum={momentum}, Batch Size={batch_size}")

            # 重新加载数据集以调整batch size
            train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
            model = SimpleCNN().to(device)
            criterion = nn.CrossEntropyLoss()
            optimizer = optim.SGD(model.parameters(), lr=lr, momentum=momentum)

            model.train()
            total_loss = 0
            batches = 0
            for batch_idx, (data, target) in enumerate(train_loader):
                if batch_idx > 50:  # 为节约时间,只训练部分batch
                    break
                data, target = data.to(device), target.to(device)
                optimizer.zero_grad()
                output = model(data)
                loss = criterion(output, target)
                loss.backward()
                optimizer.step()

                total_loss += loss.item()
                batches += 1

            avg_loss = total_loss / batches
            print(f"平均损失: {avg_loss:.4f}")

            if avg_loss < best_loss:
                best_loss = avg_loss
                best_params = {'lr': lr, 'momentum': momentum, 'batch_size': batch_size}

print(f"最佳参数组合: {best_params},最优平均损失: {best_loss:.4f}")

随机搜索(Random Search)

import random

learning_rates = [0.01, 0.001, 0.0001, 0.005]
momentums = [0.7, 0.8, 0.9, 0.95]
batch_sizes = [32, 64, 128]

num_trials = 10  # 随机尝试次数

best_loss = float('inf')
best_params = {}

for _ in range(num_trials):
    lr = random.choice(learning_rates)
    momentum = random.choice(momentums)
    batch_size = random.choice(batch_sizes)
    
    print(f"训练参数: LR={lr}, Momentum={momentum}, Batch Size={batch_size}")

    train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
    model = SimpleCNN().to(device)
    criterion = nn.CrossEntropyLoss()
    optimizer = optim.SGD(model.parameters(), lr=lr, momentum=momentum)

    model.train()
    total_loss = 0
    batches = 0
    for batch_idx, (data, target) in enumerate(train_loader):
        if batch_idx > 50:
            break
        data, target = data.to(device), target.to(device)
        optimizer.zero_grad()
        output = model(data)
        loss = criterion(output, target)
        loss.backward()
        optimizer.step()

        total_loss += loss.item()
        batches += 1

    avg_loss = total_loss / batches
    print(f"平均损失: {avg_loss:.4f}")

    if avg_loss < best_loss:
        best_loss = avg_loss
        best_params = {'lr': lr, 'momentum': momentum, 'batch_size': batch_size}

print(f"随机搜索最佳参数组合: {best_params},最优平均损失: {best_loss:.4f}")

贝叶斯优化(Bayesian Optimization)

import optuna

def objective(trial):
    lr = trial.suggest_loguniform('lr', 1e-5, 1e-1)
    momentum = trial.suggest_uniform('momentum', 0.7, 0.99)
    batch_size = trial.suggest_categorical('batch_size', [32, 64, 128])

    train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
    model = SimpleCNN().to(device)
    criterion = nn.CrossEntropyLoss()
    optimizer = optim.SGD(model.parameters(), lr=lr, momentum=momentum)

    model.train()
    total_loss = 0
    batches = 0
    for batch_idx, (data, target) in enumerate(train_loader):
        if batch_idx > 50:
            break
        data, target = data.to(device), target.to(device)
        optimizer.zero_grad()
        output = model(data)
        loss = criterion(output, target)
        loss.backward()
        optimizer.step()

        total_loss += loss.item()
        batches += 1

    avg_loss = total_loss / batches
    return avg_loss

study = optuna.create_study(direction='minimize')
study.optimize(objective, n_trials=20)

print("贝叶斯优化最佳参数:", study.best_params)
print("最佳平均损失:", study.best_value)
方法优缺点代码复杂度
网格搜索简单、完全搜索;计算资源消耗大最简单
随机搜索计算资源节省;随机覆盖;适合高维参数简单
贝叶斯优化智能高效搜索;适合复杂空间需要库支持,稍复杂

 关于贝叶斯优化我自己的理解:经过多次训练后,软件库中的方法 会记录不同参数的效果, 形成一个类似曲线的形式, 观察参数变化和模型性能之间的关系后 有选择的选择下一次测试的参数组合,最终选择出最优的参数组合。

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

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

相关文章

创建型:建造者模式

目录 1、核心思想 2、实现方式 2.1 模式结构 2.2 工作流程 2.3 实现案例 2.4 变体&#xff1a;链式建造者&#xff08;常见于多参数对象&#xff0c;无需指挥者&#xff09; 3、优缺点分析 4、适用场景 1、核心思想 目的&#xff1a;将复杂对象的构建过程与其表示分离…

UE4游戏查找本地角色数据的方法-SDK

UE4中&#xff0c;玩家的表示通常涉及以下几个类&#xff1a; APlayerController: 代表玩家的控制逻辑&#xff0c;处理输入等。 APawn: 代表玩家在世界中的实体&#xff08;比如一个角色、一辆车&#xff09;。APlayerController 控制一个 APawn。 ACharacter: APawn 的一个…

Java 连接并操作 Redis 万字详解:从 Jedis 直连到 RedisTemplate 封装,5 种方式全解析

引言 在分布式系统和高并发场景中&#xff0c;Redis 作为高性能内存数据库的地位举足轻重。对于 Java 开发者而言&#xff0c;掌握 Redis 的连接与操作是进阶必备技能。然而&#xff0c;从基础的 Jedis 原生客户端到 Spring 封装的 RedisTemplate&#xff0c;不同连接方式的原…

python web 开发-Flask-Login使用详解

Flask-Login使用详解&#xff1a;轻松实现Flask用户认证 1. Flask-Login简介 Flask-Login是Flask框架的一个扩展&#xff0c;专门用于处理用户认证相关的功能。它提供了用户会话管理、登录/注销视图、记住我功能等常见认证需求&#xff0c;让开发者能够快速实现安全的用户认证…

快速排序算法的C++和C语言对比

快速排序算法简介&#xff1a; 快速排序(Quick Sort)是一种高效的排序算法&#xff0c;采用分治法策略。它的基本思想是&#xff1a; 1. 从数列中挑出一个元素作为"基准" 2. 重新排序数列&#xff0c;所有比基准值小的元素放在基准前面&#xff0c;所有比基准值大的…

分布式事务知识点整理

目录 分布式事务问题&#xff1f;问题场景引入分布式事务的理论标准BASE理论附CAP理论 Two-phase Commit&#xff0c;2PC2PC系统组件两阶段执行过程2PC缺点 Three-Phase Commit&#xff0c;3PC三阶段执行过程 TTC(Try-Confirm-Cancel)seata项目以及原理how to define a Distrib…

鸿蒙UI开发——badge角标的使用

1、概 述 badge小红点角标是我们项目开发中常见的需求&#xff0c;信息标记组件&#xff0c;可以附加在单个组件上用于信息提醒的容器组件。效果如下&#xff1a; 2、Badge 接口定义如下&#xff1a; &#x1f449;&#x1f3fb; 根据数字创建标记组件&#xff1b; Badge(v…

批量打印的趣事

前言 PC端网页打印大量数据的时候&#xff0c;比如批量打印100个标签&#xff0c;会出现打印样式混乱的问题 问题 数据可以设定100~自定义阈值 {data.map((_, idx) > {return <Tag qrCode啊程是个大帅逼 code{AB-${idx1}} title雷猴 key{idx} />})} 打印预览到第3…

车载中央域控制器测试【BCM模块介绍-外灯3】

文章目录 1 摘要2 倒车灯2.1 倒车灯的作用与功能2.2 控制实现方案2.3 需求分析2.3.1系统需求2.3.2 功能安全需求&#xff08;ISO 26262 ASIL B&#xff09;*2.3.3 关联功能需求 3 角灯3.1 角灯&#xff08;Cornering Lamp&#xff09;核心作用与功能3.2 控制实现方案3.3 需求分…

Linux系统基础——是什么、适用在哪里、如何选

一、Linux是什么 Linux最初是由林纳斯托瓦兹&#xff08;Linus Torvalds&#xff09;基于个人兴趣爱好开发的个人项目&#xff0c;他编写了最核心的内核&#xff1b;后面为了发展壮大Linux系统他将整个项目开源到GitHub上&#xff0c;可以让全世界的人都参与到项目的开发维护中…

C++标准库中 std::string 类提供的 insert 成员函数的不同重载版本

下图是C标准库中 std::string 类提供的 insert 成员函数的不同重载版本&#xff0c;可点击C标准库获取 以下是std::string::insert各重载版本的功能及参数解释&#xff1a; 1. 插入完整字符串 string& insert(size_t pos, const string& str); 功能&#xff1a;在字…

Qt window frame + windowTitle + windowIcon属性(3)

文章目录 window frame属性window frame的概念1. window frame的影响2. 图片演示3. 代码演示 API接口widget.cpp&#xff08;测试代码&#xff09; windowTitle属性API接口问题 注意点widget.cpp&#xff08;属性用法&#xff09; windowIcon属性API接口啥是窗口图标玩法1. 先…

Dify源码学习

文章目录 1 大模型基本原理1.1 model_context_tokens、max_tokens和prompt_tokens1.1.1 三者之间的关系1.1.2 总结对比 2 Dify源代码2.0 前后端代码跑起来【0】准备开发环境【1】下载代码【2】运行后端&#xff08;1&#xff09;Start the docker-compose stack&#xff08;2&a…

静态网站部署:如何通过GitHub免费部署一个静态网站

GitHub提供的免费静态网站托管服务可以无需担心昂贵的服务器费用和复杂的设置步骤&#xff0c;本篇文章中将一步步解如何通过GitHub免费部署一个静态网站&#xff0c;帮助大家将创意和作品快速展现给世界。 目录 了解基础情况 创建基础站点 在线调试站点 前端项目部署 部署…

【拯救小狗】2022-1-3

缘由c学校练习试题&#xff0c;求解决-编程语言-CSDN问答 void 拯救小狗() {//缘由https://ask.csdn.net/questions/7622294?spm1005.2025.3001.5141int d 0, g 0, tfh[100][3]{}, x 0, c 10, dd d;std::cin >> d >> g; dd d;while (x < g && d…

PS2025 v26.7 Photoshop2025+AI生图扩充版,支持AI画图

软件下载 【名称】&#xff1a;PS2025 v26.7 Photoshop2025AI生图扩充版 【大小】&#xff1a;4.9G 【语言】&#xff1a;简体中文 【安装环境】&#xff1a;Win10/Win11 【网盘下载链接】&#xff08;务必手机注册&#xff09;&#xff1a; https://pan.quark.cn/s/51f5…

怎么开发一个网络协议模块(C语言框架)之(三) 全局实例

1. gVrrpInstance 是什么? 这是 VRRP 全局控制结构体,命名为 vrrpGlbInstance_t,定义了整个协议运行时的 内核资源、全局状态、各类对象池、AVL 树、计时器、套接字等。 它本质上是一个单例(singleton),用于全局访问 VRRP 实例、资源、统计、socket 等。 vrrpGlbInsta…

ShenNiusModularity项目源码学习(30:ShenNius.Admin.Mvc项目分析-15)

广告管理页面用于新建、维护及删除系统CMS管理模块的广告信息&#xff0c;其后台控制器类AdvListController位于ShenNius.Admin.Mvc项目的Areas\Cms\Controllers内&#xff0c;页面文件位于同项目的Areas\Cms\Views\AdvList内&#xff0c;其中Index.cshtml页面为主页面&#xf…

香港维尔利健康科技集团全面推进AI医疗落地,构建智慧健康管理新模式

在人工智能重塑全球医疗格局的新浪潮中&#xff0c;香港维尔利健康科技集团再次抢占技术高地&#xff0c;宣布正式启动“AI医疗健康场景融合工程”&#xff0c;将人工智能深度嵌入健康管理的全链条服务之中。该计划不仅涵盖设备智能化、诊疗辅助算法、用户健康行为建模等核心环…

选择合适的Azure数据库监控工具

Azure云为组织提供了众多服务&#xff0c;使其能够无缝运行应用程序、Web服务和服务器部署&#xff0c;其中包括云端数据库部署。Azure数据库能够与云应用程序实现无缝集成&#xff0c;具备可靠、易扩展和易管理的特性&#xff0c;不仅能提升数据库可用性与性能&#xff0c;同时…