深度学习 CNN

news2025/5/12 18:53:28

    CNN 简介

    什么是 CNN?
    • 卷积神经网络(Convolutional Neural Network)是专为处理网格数据(如图像)设计的神经网络。
    • 核心组件:

      • 卷积层 :提取局部特征(如边缘、纹理)通过卷积核。

      • 池化层 :下采样,减少空间维度,保留重要信息。

      • 全连接层 :将特征映射到类别(如分类任务)。
    • 优势:

      • 局部感知 :卷积核关注局部区域,适合图像的局部模式。

      • 参数共享 :卷积核在整张图像上共享,减少参数量。

      • 平移不变性 :对图像平移不敏感,泛化能力强。
    • 与 MLP 的对比
      • MLP

        • 输入展平为向量([batch, 784]),丢失空间结构。
        • 参数多(784*128 的权重矩阵),计算量大。
        • 对图像任务效果有限(忽略局部特征)。
      • 美国有线电视新闻网(CNN):

        • 输入保留空间结构([batch, 1, 28, 28])。
        • 参数少(卷积核小,如 3x3),效率高。
        • 擅长提取图像特征,适合 MNIST、CIFAR-10 等任务。
    • CNN 结构(以 MNIST 为例)

      • 输入:[batch, 1, 28, 28](灰度图像)。

      • 卷积层 1:nn.Conv2d(1, 16, kernel_size=3) → [batch, 16, 26, 26]。

      • 池化层 1:nn.MaxPool2d(2) → [batch, 16, 13, 13]。

      • 卷积层 2:nn.Conv2d(16, 32, kernel_size=3) → [batch, 32, 11, 11]。

      • 池化层 2:nn.MaxPool2d(2) → [batch, 32, 5, 5]。

      • 展平:[batch, 32*5*5]。

      • 全连接层:nn.linear(32*5*5, 10) → [batch, 10](logits)。
    2. 核心 API
    • nn.卷积 2d (Conv2d):
      • 实现 2D 卷积操作,提取图像特征。
      • 参数:
        • in_channels:输入通道数(如 MNIST 的 1,RGB 图像的 3)。
        • out_channels:输出通道数(卷积核数量,如 16)。
        • kernel_size:卷积核大小(如 3 表示 3x3)。
        • stride:步幅(默认 1)。

        • padding:填充(默认 0,padding=1 保持尺寸)。
      • 输出形状:

        • H_out = floor((H_in + 2*填充 - kernel_size) / 步幅 + 1)。

        • 示例:[batch, 1, 28, 28] → nn.conv2d(1, 16, 3) → [batch, 16, 26, 26]。

      • 自动管理权重([out_channels, in_channels, kernel_size, kernel_size])和偏置。
    • nn.MaxPool2d 中:
      • 最大池化,减少空间维度,增强鲁棒性。
      • 参数:
        • kernel_size:池化窗口大小(如 2 表示 2x2)。
        • stride:步幅(默认等于 kernel_size)。
      • 输出形状:

        • H_out = floor((H_in - kernel_size) / 步幅 + 1)。

        • 示例:[batch, 16, 26, 26] → nn.MaxPool2d(2) → [batch, 16, 13, 13]。
    • nn.Module

      • 定义 CNN 模型,组合 nn.Conv2d,nn.MaxPool2d,nn.线性 。
      • forward 方法定义数据流:卷积 → 池化 → 展平 → 全连接。
    • nn.CrossEntropyLosstorch.optim
      • 损失:nn.CrossEntropyLoss 自动处理 Softmax 和负对数似然。
      • 优化器:optim.SGD 或 optim.Adam 自动更新参数。
    3. CNN 训练流程
    • 流程

      1. 定义模型 :继承 nn.Module,组合卷积、池化、全连接层。

      2. 数据加载 :DataLoader 提供 [batch, 1, 28, 28] 的图像。

      3. 前向传播 :model(x) 计算 logits。

      4. 损失计算 :loss = criterion(logits, labels)。

      5. 反向传播 :loss.backward()。

      6. 优化 :optimizer.step()。
    • 优势
      • 比 MLP 更适合图像数据,参数少,精度高。
      • 卷积操作提取空间特征(如边缘、纹理),池化降低计算量。
    • 与手写 MLP 的对比
      • 手写 MLP:手动矩阵乘,忽略空间结构。

      • 美国有线电视新闻网:nn.Conv2d 自动处理卷积,保留空间信息,代码仍简洁。

    摘要

    • CNN 通过卷积和池化提取图像特征,适合视觉任务。
    • nn.Conv2d 和 nn.MaxPool2d 是 CNN 核心组件,nn.Module 提供模块化实现。
    • CNN 在 MNIST 上通常比 MLP 更高效,参数更少,精度更高。

     使用 nn.Module 实现 MNIST 分类的 CNN

    import torch
    import torch.nn as nn
    import torch.optim as optim
    from torchvision import datasets
    from torchvision import transforms
    from torch.utils.data import DataLoader
    
    transform = transforms.Compose([
        transforms.ToTensor(),
        transforms.Normalize((0.5),(0.5))
    ])
    
    train_dataset = datasets.MNIST(root='./data', train=True, transform=transform, download=True)
    test_dataset = datasets.MNIST(root='./data', train=False, transform=transform)
    train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)
    test_loader = DataLoader(test_dataset, batch_size=32, shuffle=False)
    
    class CNN(nn.Module):
        def __init__(self):
            super.__init__()
            self.conv1 = nn.Conv2d(1,16,kernel_size=3)  #参数分别是 输入数据的尺寸 输出数据的尺寸 卷积核的大小    输出大小= 步输入大小−卷积核大小/步长
            self.pool1 = nn.MaxPool2d(2)  #2x2最大池化
            self.conv2 = nn.Conv2d(16,32,kernel_size=3)
            self.pool2 = nn.MaxPool2d(2)
            self.fc = nn.Linear(32*5*5,10)  #全连接层
            self.relu = nn.ReLU() #激活函数
    
        def forward(self,x):
            x = self.relu(self.conv1(x))
            x = self.pool1(x)
            x = self.relu(self.conv2(x))
            x = self.pool2(x)
            x = x.view(-1, 32 * 5 * 5) #将数据展平 应为全连接层只能接受 一维的张量
            x = self.fc(x)
            return x
    
    
    model = CNN()
    
    # Training
    criterion = nn.CrossEntropyLoss()  #交叉熵损失函数
    optimizer = optim.SGD(model.parameters(), lr=0.01)  #优化器
    epochs = 5
    
    #训练循环
    for epoch in range(epochs):
        model.train()
        total_loss = 0
        correct = 0
        total = 0
        for images, labels in train_loader:
            logits = model(images)
            loss = criterion(logits, labels)
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()
            total_loss += loss.item() * len(images)
            pred = torch.argmax(logits, dim=1)
            correct += (pred == labels).sum().item()
            total += len(labels)
        avg_loss = total_loss / total
        accuracy = correct / total
        print(f"Epoch {epoch + 1}, Loss: {avg_loss:.4f}, Accuracy: {accuracy:.4f}")
    
    # 测试
    model.eval()
    correct = 0
    total = 0
    with torch.no_grad():
        for images, labels in test_loader:
            logits = model(images)
            pred = torch.argmax(logits, dim=1)
            correct += (pred == labels).sum().item()
            total += len(labels)
    print(f"Test Accuracy: {correct / total:.4f}")

     输出数据的大小的计算公式

     一、无 padding 时的卷积输出公式

    • N:输入尺寸(高或宽)

    • K:卷积核大小

    • S:步长(stride)

    • 没有 padding,所以图像边缘会被“卷”掉


     二、有 padding 时的卷积输出公式

    • P:padding 填充的像素数(在每一边)

     CIFAR-10 数据集  CNN代码

    import torch
    import torch.nn as nn
    import torch.optim as optim
    from torchvision import datasets, transforms
    from torch.utils.data import DataLoader
    #数据增强
    train_transform = transforms.Compose([
        transforms.RandomCrop(32,padding=4), #随机裁剪
        transforms.RandomHorizontalFlip(), #水平翻转 里面的参数是 反转的概率
        transforms.ToTensor(), #将数据 变为张量
        transforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5)) #将数据归一化
    ])
    
    test_transform = transforms.Compose([
        transforms.ToTensor(),
        transforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5))
    ])
    #导入数据
    train_dataset = datasets.CIFAR10(root='./data', train=True, transform=train_transform, download=True)
    test_dataset = datasets.CIFAR10(root='./data', train=False, transform=test_transform)
    train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)
    test_loader = DataLoader(test_dataset, batch_size=32, shuffle=False)
    #CNN构建
    class CIFAR10_CNN(nn.Module):
        def __init__(self):
            super().__init__()
            self.conv1 = nn.Conv2d(3,16,kernel_size=3 ,padding = 1)
            self.pool1 = nn.MaxPool2d(2)
            self.conv2 = nn.Conv2d(16,32,kernel_size=3,padding=1)
            self.pool2 = nn.MaxPool2d(2)
            self.conv3 = nn.Conv2d(32, 64, kernel_size=3, padding=1)
            self.fc = nn.Linear(64 * 8 * 8, 10)
            self.relu = nn.ReLU()
        def forward(self,x): #前向传播
            x = self.relu(self.conv1(x))
            x = self.pool1(x)
            x = self.relu(self.conv2(x))
            x = self.pool2(x)
            x = self.relu(self.conv3(x))
            x = x.view(-1, 64 * 8 * 8)
            x = self.fc(x)
            return x
    
    model = CIFAR10_CNN()
    
    criterion = nn.CrossEntropyLoss()
    optimizer = optim.Adam(model.parameters(), lr=0.001)
    epochs = 5
    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    model.to(device)
    
    for epoch in range(epochs):
        model.train()
        total_loss = 0
        correct = 0
        total = 0
        for images, labels in train_loader:
            images, labels = images.to(device), labels.to(device)
            logits = model(images)
            loss = criterion(logits, labels)
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()
            total_loss += loss.item() * len(images)
            pred = torch.argmax(logits, dim=1)
            correct += (pred == labels).sum().item()
            total += len(labels)
        avg_loss = total_loss / total
        accuracy = correct / total
        print(f"Epoch {epoch+1}, Loss: {avg_loss:.4f}, Accuracy: {accuracy:.4f}")
    
    # Testing
    model.eval()
    correct = 0
    total = 0
    with torch.no_grad():
        for images, labels in test_loader:
            images, labels = images.to(device), labels.to(device)
            logits = model(images)
            pred = torch.argmax(logits, dim=1)
            correct += (pred == labels).sum().item()
            total += len(labels)
    print(f"Test Accuracy: {correct/total:.4f}")

    多通道卷积

    • 多通道卷积原理
      • MNIST CNN:输入是单通道(in_channels=1),nn.Conv2d(1, 16, 3) 每个卷积核处理灰度图像。
      • CIFAR-10 CNN:输入是三通道(RGB,in_channels=3),nn.Conv2d(3, 16, 3) 的卷积核有 [3, 3, 3] 形状(3 通道 × 3x3)。
      • 卷积核
        • 每个输出通道(如 16)对应一个卷积核组,处理所有输入通道(3)。
        • 输出形状:[batch, out_channels, H_out, W_out],H_out = (H_in - kernel_size + 2*padding) / stride + 1。
      • 示例
        • 输入:[batch, 3, 32, 32]。
        • nn.Conv2d(3, 16, 3) → [batch, 16, 30, 30](无 padding,stride=1)。
    • 知识点
      • 多通道卷积提取 RGB 图像的颜色和空间特征,参数量随通道数增加。
      • 需调整全连接层输入尺寸,考虑卷积和池化后的特征图大小。
    • 与 MNIST CNN 的区别
      • 输入通道:MNIST(1) vs. CIFAR-10(3)。
      • 模型深度:CIFAR-10 需更深网络(更多卷积层)捕获复杂特征。
      • 数据增强:CIFAR-10 需强增强防止过拟合。

    数据增强

    • 什么是数据增强?
      • 通过随机变换(如翻转、裁剪)增加训练数据多样性,防止过拟合。
      • CIFAR-10 小图像和高类别复杂度尤其需要增强。
    • 常见增强(torchvision.transforms)
      • RandomCrop(size, padding):随机裁剪(如 32x32,padding=4)。
      • RandomHorizontalFlip(p=0.5):50% 概率水平翻转。
      • ColorJitter(brightness, contrast):调整亮度、对比度(稍后阶段深入)。
    • 作用
      • 提高模型泛化能力,尤其对小数据集(如 CIFAR-10)。
      • 模拟真实场景的图像变化(如光照、角度)。

    BatchNorm 原理

    • 什么是 Batch Normalization?
      • BatchNorm(批归一化)是一种规范化技术,在每层输入上标准化激活值,加速训练,改善稳定性。
      • 核心思想
        • 对每个 mini-batch,标准化激活值,使其均值为 0,方差为 1。
        • 再进行可学习的缩放和平移(gamma 和 beta)。
      • 数学公式
        • 输入:mini-batch 的激活值 x(形状 [batch, channels, height, width])。
        • 标准化:x_norm = (x - mean) / sqrt(var + eps),其中 mean 和 var 是 batch 的均值和方差,eps 是小常数(防止除零)。
        • 缩放和平移:y = gamma * x_norm + beta,gamma 和 beta 是可学习参数。
      • 作用
        • 加速收敛:标准化减少内部协变量偏移(internal covariate shift)。
        • 稳定训练:缓解梯度消失/爆炸,允许更高学习率。
        • 正则化效果:引入 batch 噪声,类似轻微 Dropout。
      • 对比无 BatchNorm
        • 无 BatchNorm:深层 CNN(如 CIFAR-10)可能收敛慢,易梯度问题。
        • 有 BatchNorm:损失下降更快,准确率更高。
    • 应用场景
      • 常用于 CNN(nn.BatchNorm2d)和全连接层(nn.BatchNorm1d)。
      • 位置:卷积层或全连接层后,激活函数(如 ReLU)前。

     PyTorch 的 nn.BatchNorm2d

    • nn.BatchNorm2d
      • 用于 2D 卷积网络,标准化 [batch, channels, height, width] 的激活值。
      • 参数
        • num_features:输入通道数(如 conv1 的 out_channels)。
        • eps:防止除零的小常数(默认 1e-5)。
        • momentum:更新运行均值和方差的动量(默认 0.1)。
        • track_running_stats:是否跟踪全局均值和方差(默认 True)。
      • 运行均值和方差
        • 训练时:计算 batch 的均值和方差,同时更新全局统计(running_mean, running_var)。
        • 评估时:使用全局统计(running_mean, running_var)标准化。
      • 示例
        conv = nn.Conv2d(3, 16, 3)  # [batch, 16, H, W]
        bn = nn.BatchNorm2d(16)     # 标准化 16 个通道
        x = bn(conv(input))
    • 训练 vs. 评估模式
      • 训练模式(model.train()):使用 batch 统计,更新 running_mean 和 running_var。
      • 评估模式(model.eval()):使用全局统计,不更新。
      • 切换模式影响 BatchNorm 和 Dropout 等层。

    BatchNorm 在 CIFAR-10 CNN 中的应用

    • 为什么需要 BatchNorm?
      • CIFAR-10 图像复杂,深层 CNN 易出现梯度问题或收敛慢。
      • BatchNorm 标准化卷积层输出,稳定训练,提升准确率。
    • 添加位置
      • 在 nn.Conv2d 后,nn.ReLU 前:conv → bn → relu。
      • 示例:self.bn1 = nn.BatchNorm2d(16) 跟随 self.conv1。
    • 预期效果
      • 损失下降更快,训练准确率提升(~5-10%)。
      • 允许更大学习率(如 0.01 vs. 0.001),加速训练。
    • 与 MNIST CNN 的对比
      • MNIST 简单,BatchNorm 效果不明显(准确率已高)。
      • CIFAR-10 复杂,BatchNorm 显著改善性能。

    Summary:

    • BatchNorm 标准化激活值,加速收敛,稳定深层 CNN 训练。
    • nn.BatchNorm2d 自动管理均值、方差,需注意训练/评估模式。
    • 在 CIFAR-10 CNN 中,BatchNorm 提升性能,适合复杂任务。

     使用 BatchNorm 定义 CNN

    class CIFAR10_CNN_BN(nn.Module):
        def __init__(self):
            super().__init__()
            self.conv1 = nn.Conv2d(3, 16, kernel_size=3, padding=1)
            self.bn1 = nn.BatchNorm2d(16)
            self.pool1 = nn.MaxPool2d(2)
            self.conv2 = nn.Conv2d(16, 32, kernel_size=3, padding=1)
            self.bn2 = nn.BatchNorm2d(32)
            self.pool2 = nn.MaxPool2d(2)
            self.conv3 = nn.Conv2d(32, 64, kernel_size=3, padding=1)
            self.bn3 = nn.BatchNorm2d(64)
            self.fc = nn.Linear(64*8*8, 10)
            self.relu = nn.ReLU()
        
        def forward(self, x):
            x = self.relu(self.bn1(self.conv1(x)))
            x = self.pool1(x)
            x = self.relu(self.bn2(self.conv2(x)))
            x = self.pool2(x)
            x = self.relu(self.bn3(self.conv3(x)))
            x = x.view(-1, 64*8*8)
            x = self.fc(x)
            return x
    
    model = CIFAR10_CNN_BN()
    BatchNorm其实就是 对每个卷积核的计算再次进行归一化,使模型更加稳定

    损失可视化代码

    #损失可视化
    plt.plot("losses")
    plt.xlabel("Epoch")
    plt.ylabel("Loss")
    plt.title("Training Loss Curve")
    plt.show()

    学习率调度原理

    • 什么是学习率安排?
      • 学习率调度(Learning Rate Scheduling)是动态调整优化器学习率(lr)的技术,根据训练进度优化收敛。
      • 核心思想
        • 早期:高学习率快速接近损失函数的最优解。
        • 后期:低学习率精细调整,避免震荡。
      • 为什么需要?
        • 学习固定率可能导致:
          • 过大:损失震荡,难以收敛。
          • 过小:收敛慢,易梯度局部最优。
        • 调度器动态平衡速度和精度。
      • 常见调度:策略
        • Step Decay:每次固定步数(epochs)降低学习率(如lr *= 0.1)。
        • 余弦退火:学习率按余弦函数衰减。
        • 高原减少:当损失不再下降时学习率降低。
      • 作用
        • 加速收敛,提升最终准确率。
        • 适合复杂任务(如CIFAR-10),防止过度导入或欠导入。
    • CIFAR-10 的需求
      • CIFAR-10模型复杂度,BatchNorm虽稳定训练,但固定lr=0.001可能限制性能。
      • 调度器(如StepLR)可以通过降低lr提高精度(~2-5%)。

     PyTorch的torch.optim.lr_scheduler.StepLR

    • StepLR简介
      • StepLR每次固​​定步数(epochs)将学习率乘以一个因子(gamma)。
      • 参数
        • optimer:绑定的优化器(如optim.Adam)。
        • step_size:每多少个epoch调整一次学习率。
        • gamma:学习率缩放因子(通常0.1-0.5)。
      • 数学公式
        • 初始:lr = lr_initial。
        • 第n次调整(每step_size epoch):lr = lr_initial * gamma^n。
      • 代码
        optimizer = optim.Adam(model.parameters(), lr=0.001)
        scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=2, gamma=0.1)
        # Epoch 1-2: lr = 0.001
        # Epoch 3-4: lr = 0.001 * 0.1 = 0.0001
        # Epoch 5-6: lr = 0.0001 * 0.1 = 0.00001
    • 调用方式
      • 每个 epoch 末调用scheduler.step(),更新优化器的lr。
      • 注意:scheduler.step()在optimizer.step()后调用。
    • 训练与评估
      • 调度器只影响训练,不影响评估(model.eval())。
      • 需监控学习率变化(通过optimizer.param_groups[0]['lr'])。
    StepLR在CIFAR-10 CNN中的应用
    • 为什么用StepLR?
      • CIFAR-10训练中,早期高lr加速恢复,后期低lr精细调整。
      • StepLR简单有效,适合初学者(相比CosineAnnealing)。
    • 预期效果
      • 损失曲线更平滑,测试准确率提升(~75-80% → ~78-82%)。
      • 训练后期避免震荡,泛化性能更好。
    • 与前两天对比
      • Day 1:固定lr=0.001,准确率~70%。
      • Day 2:BatchNorm 提升到 ~75-80%。
      • Day 3:StepLR进一步优化,预期~78-82%。

    概括

    • 学习率调度动态调整,平衡训练速度和精度。
    • StepLR每次step_size epoch 降低lr,简单有效。
    • 在CIFAR-10 CNN中,StepLR提升性能,适合核心模型。

     在上面的代码中加入学习率调度以及学习率变化图

    import torch
    import torch.nn as nn
    import torch.optim as optim
    from torchvision import datasets, transforms
    from torch.utils.data import DataLoader
    import matplotlib.pyplot as plt
    # torch: PyTorch 核心库,nn: 神经网络模块,optim: 优化器和调度器
    # torchvision: 数据集和变换,DataLoader: 批量加载数据
    # matplotlib: 绘制损失和学习率曲线
    
    # Training transforms: 增强训练数据,增加泛化能力
    train_transform = transforms.Compose([
        transforms.RandomCrop(32, padding=4),  # 随机裁剪,padding 避免边界丢失
        transforms.RandomHorizontalFlip(),     # 50% 概率水平翻转,模拟物体方向变化
        transforms.ToTensor(),                 # 转换为张量 [0, 1]
        transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))  # 标准化 RGB 通道
    ])
    # Test transforms: 仅标准化,无增强
    test_transform = transforms.Compose([
        transforms.ToTensor(),
        transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
    ])
    # Load CIFAR-10: 训练集 50K,测试集 10K,32x32 RGB 图像
    train_dataset = datasets.CIFAR10(root='./data', train=True, transform=train_transform, download=True)
    test_dataset = datasets.CIFAR10(root='./data', train=False, transform=test_transform)
    # DataLoader: 批量加载,batch_size=32 平衡速度和内存
    train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)
    test_loader = DataLoader(test_dataset, batch_size=32, shuffle=False)
    
    # Define CNN with BatchNorm
    class CIFAR10_CNN_BN(nn.Module):
        def __init__(self):
            super().__init__()
            # conv1: 输入 3 通道 (RGB),输出 16 通道,3x3 卷积,padding=1 保持尺寸
            self.conv1 = nn.Conv2d(3, 16, kernel_size=3, padding=1)
            self.bn1 = nn.BatchNorm2d(16)  # 标准化 16 通道激活值
            self.pool1 = nn.MaxPool2d(2)   # 2x2 池化,尺寸减半
            # conv2: 输入 16 通道,输出 32 通道
            self.conv2 = nn.Conv2d(16, 32, kernel_size=3, padding=1)
            self.bn2 = nn.BatchNorm2d(32)
            self.pool2 = nn.MaxPool2d(2)
            # conv3: 输入 32 通道,输出 64 通道
            self.conv3 = nn.Conv2d(32, 64, kernel_size=3, padding=1)
            self.bn3 = nn.BatchNorm2d(64)
            # fc: 全连接层,输入 64*8*8 (池化后尺寸),输出 10 类
            self.fc = nn.Linear(64*8*8, 10)
            self.relu = nn.ReLU()  # ReLU 激活函数
    
        def forward(self, x):
            # conv1 → bn1 → relu → pool1: 特征提取 + 标准化 + 非线性 + 下采样
            x = self.relu(self.bn1(self.conv1(x)))
            x = self.pool1(x)  # [batch, 16, 16, 16]
            # conv2 → bn2 → relu → pool2
            x = self.relu(self.bn2(self.conv2(x)))
            x = self.pool2(x)  # [batch, 32, 8, 8]
            # conv3 → bn3 → relu
            x = self.relu(self.bn3(self.conv3(x)))  # [batch, 64, 8, 8]
            # 展平为 [batch, 64*8*8],输入全连接层
            x = x.view(-1, 64*8*8)
            x = self.fc(x)  # 输出 [batch, 10]
            return x
    
    model = CIFAR10_CNN_BN()  # 实例化模型
    
    
    # 定义损失函数:分类任务使用交叉熵
    criterion = nn.CrossEntropyLoss()
    # 优化器:Adam 自适应优化,初始 lr=0.001
    optimizer = optim.Adam(model.parameters(), lr=0.001)
    # 调度器:每 2 epoch 降低 lr,gamma=0.1 (lr *= 0.1)
    scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=2, gamma=0.1)
    epochs = 10  # 训练 5 epoch
    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")  # GPU 或 CPU
    model.to(device)  # 模型移到设备
    
    losses = []  # 存储每 epoch 的平均损失
    lrs = []     # 存储学习率变化
    for epoch in range(epochs):
        model.train()  # 训练模式,启用 BatchNorm 和 Dropout
        total_loss = 0
        correct = 0
        total = 0
        for images, labels in train_loader:
            # 移动数据到设备
            images, labels = images.to(device), labels.to(device)
            # 前向传播:计算模型输出
            logits = model(images)
            # 计算损失
            loss = criterion(logits, labels)
            # 清零梯度,避免累加
            optimizer.zero_grad()
            # 反向传播:计算梯度
            loss.backward()
            # 更新参数:基于梯度调整权重
            optimizer.step()
            # 累加损失(按 batch 样本数加权)
            total_loss += loss.item() * len(images)
            # 计算预测准确率
            pred = torch.argmax(logits, dim=1)
            correct += (pred == labels).sum().item()
            total += len(labels)
        # 计算平均损失和准确率
        avg_loss = total_loss / total
        accuracy = correct / total
        losses.append(avg_loss)
        # 记录当前学习率
        lrs.append(optimizer.param_groups[0]['lr'])
        print(f"Epoch {epoch+1}, Loss: {avg_loss:.4f}, Accuracy: {accuracy:.4f}, LR: {lrs[-1]:.6f}")
        # 更新学习率:必须在 epoch 末调用
        scheduler.step()
    
    # 绘制损失和学习率曲线
    plt.figure(figsize=(10, 4))
    plt.subplot(1, 2, 1)
    plt.plot(losses)
    plt.xlabel("Epoch")
    plt.ylabel("Loss")
    plt.title("Training Loss Curve")
    plt.subplot(1, 2, 2)
    plt.plot(lrs)
    plt.xlabel("Epoch")
    plt.ylabel("Learning Rate")
    plt.title("Learning Rate Schedule")
    plt.tight_layout()
    plt.show()
    
    # 测试代码
    model.eval()
    correct = 0
    total = 0
    with torch.no_grad():
        for images, labels in test_loader:
            images, labels = images.to(device), labels.to(device)
            logits = model(images)
            pred = torch.argmax(logits, dim=1)
            correct += (pred == labels).sum().item()
            total += len(labels)
    print(f"Test Accuracy: {correct / total:.4f}")

    学习率调度参数调试

    调试参数的核心原则

    • 初始学习率(lr)
      • 决定训练起点,需与调度器配合。
      • 调试方法
        • 太高(e.g., 0.01):损失震荡或发散。
        • 太低(e.g., 0.0001):收敛慢。
        • CIFAR-10 建议:Adam 用 0.001-0.0001,SGD 用 0.1-0.01。
        • 测试方法:固定调度器,尝试 [0.01, 0.001, 0.0001],观察损失曲线。
    • step_size(StepLR):
      • 控制调整频率,影响训练节奏。
      • 调试方法
        • 太小(e.g., 1):频繁降低 lr,可能过早减小,导致欠拟合。
        • 太大(e.g., 10):延迟降低 lr,可能错过最佳收敛点。
        • CIFAR-10 建议:2-5(总 epoch 10-20 时),约 1/4-1/2 训练周期。
        • 测试方法:试 [1, 2, 5],比较损失下降速度。
    • gamma(StepLR):
      • 控制学习率衰减幅度,影响后期精细程度。
      • 调试方法
        • 太小(e.g., 0.01):lr 下降过快,可能停止优化。
        • 太大(e.g., 0.5):lr 下降慢,可能仍震荡。
        • CIFAR-10 建议:0.1-0.5,确保显著但不过激的衰减。
        • 测试方法:试 [0.1, 0.3, 0.5],观察测试准确率。
    • ReduceLROnPlateau 额外参数
      • patience:太小(e.g., 1)过早降 lr,太大(e.g., 10)延迟优化。
      • factor:类似 gamma,建议 0.1-0.5。
      • threshold:建议 0.0001-0.01,避免对小改进过敏。
      • CIFAR-10 建议:patience=2-3,factor=0.1。
    3. 调试策略
    1. 固定初始 lr,调试调度参数
      • 选稳定 lr(如 Adam 的 0.001),调整 step_size 和 gamma。
      • 监控:训练/测试损失、准确率、学习率曲线。
    2. 观察损失曲线
      • 震荡:lr 太高或 gamma 太大,降低初始 lr 或 gamma。
      • 平坦:lr 太低或 step_size 太小,增加 lr 或 step_size。
      • 过拟合:测试损失上升,考虑 ReduceLROnPlateau 或更小 gamma。
    3. 短周期实验
      • 跑 5-10 epoch,快速比较参数组合。
      • 记录:[lr, step_size, gamma] 的损失和准确率。
    4. 结合优化器
      • Adam:对 lr 变化敏感,gamma=0.1 通常有效。
      • SGD:需要更高初始 lr(0.01-0.1),gamma=0.5 更稳。
    5. 可视化学习率
      • 打印或绘制 optimizer.param_groups[0]['lr'],确认调度行为。
    6. 网格搜索
      • 测试参数组合:lr=[0.01, 0.001], step_size=[1, 2, 5], gamma=[0.1, 0.3]。
      • 选择测试准确率最高、train-test 差距最小的配置。
    4. CIFAR-10 调试目标
    • 预期性能
      • 测试准确率:~80-85%(含 BatchNorm、Dropout)。
      • 训练损失:<0.5,测试损失:<1.0。
      • train-test 准确率差距:<10%(避免过拟合)。
    • 调试重点
      • 确保 lr 随 epoch 合理下降(e.g., 0.001 → 0.00001)。
      • 避免过早或过晚降低 lr,平衡速度和精度。

    Summary

    • 调试学习率调度参数需结合初始 lr、调度器类型和任务特性。
    • StepLR 的 step_size 和 gamma 控制调整频率和幅度,需通过实验优化。
    • 监控损失、准确率和学习率曲线,找到最佳配置。

     Dropout 原理

    • 什么是 Dropout?
      • Dropout 是一种正则化技术,在训练时随机丢弃(置零)一部分神经元,防止模型过拟合。
      • 核心思想
        • 每次前向传播,随机选择部分神经元(以概率 p)置零。
        • 模拟多个子网络集成,增强泛化能力。
      • 数学公式
        • 输入:激活值 x(如卷积或全连接层的输出)。
        • Dropout:y = x * mask / (1-p),其中 mask 是伯努利分布(0 或 1,概率 p 置零),1/(1-p) 缩放保持期望不变。
      • 作用
        • 防止过拟合:减少神经元间的复杂依赖,类似集成学习。
        • 提升泛化:模型对测试数据更鲁棒。
        • 轻量正则化:无需额外参数,计算开销小。
      • 对比无 Dropout
        • 无 Dropout:CIFAR-10 模型可能过拟合(训练准确率高,测试低)。
        • 有 Dropout:训练准确率略降,测试准确率提升。
    • 应用场景
      • 常用于全连接层(nn.Dropout)或卷积层后(nn.Dropout2d)。
      • 位置:激活函数(如 ReLU)后,靠近网络末端(如全连接层前)。

    PyTorch 的 nn.Dropout

    • nn.Dropout
      • 用于 1D 输入(如全连接层输出),随机置零元素。
      • 参数
        • p:丢弃概率(默认 0.5,范围 0-1)。
        • inplace:是否直接修改输入(默认 False)。
      • nn.Dropout2d
        • 用于 2D 输入(如卷积层输出),置零整个通道。
        • 适合 CNN,效果类似空间 Dropout。
      • 训练 vs. 评估模式
        • 训练模式(model.train()):随机丢弃,缩放输出(1/(1-p))。
        • 评估模式(model.eval()):无丢弃,输出不变。
      • 示例
        dropout = nn.Dropout(p=0.5)  # 50% 概率置零
        x = torch.randn(32, 128)     # 全连接层输出
        y = dropout(x)               # 训练时随机置零
    • 注意事项
      • Dropout 只在训练时生效,model.eval() 禁用。
      • p 过高(>0.5)可能欠拟合,过低(<0.2)正则化不足。
     Dropout 在 CIFAR-10 CNN 中的应用
    • 为什么需要 Dropout?
      • CIFAR-10 数据复杂,深层 CNN(含 BatchNorm 和 StepLR)仍可能过拟合(训练准确率 >> 测试准确率)。
      • Dropout 降低全连接层(fc)的复杂依赖,提升测试性能。
    • 添加位置
      • 通常在全连接层前(x.view(-1, 64*8*8) 后,fc 前)。
      • 示例:self.dropout = nn.Dropout(0.5),在 forward 中 x = self.dropout(x)。
    • 预期效果
      • 训练准确率略降(因丢弃),测试准确率提升(~78-82% → ~80-85%)。
      • 损失曲线更平滑,泛化性能增强。

    Dropout 适合用在什么情况?

    1. 模型参数多、容易过拟合的场景

      • 比如全连接层(尤其是深层的FC层)中参数数量大,很容易过拟合,这时适合使用 Dropout。

    2. 训练数据量较小或质量不高的情况

      • 数据不足时模型容易记住训练集细节,Dropout 可以缓解这种过拟合风险。

    3. 深度神经网络(如 CNN、RNN、Transformer 等)

      • 特别是在中间或输出层加入 Dropout,可以提升模型的泛化能力。


    Dropout 不适合或不必要的情况

    1. 模型本身较小或数据充足时

      • 如果模型较浅或训练样本非常充足、丰富,过拟合风险较低,Dropout 可能不是必须的。

    2. 卷积层中使用需谨慎

      • 卷积层参数共享较少容易过拟合,但由于其结构的特殊性,很多研究表明 Dropout 在卷积层中效果不如 BatchNorm。

      • 通常在卷积层后会用 BatchNorm 和 ReLU,Dropout 多用于卷积层之后的全连接层

    3. 推理/测试阶段自动禁用 Dropout

      • Dropout 只在训练时起作用,测试时会自动关闭(即不会随机丢节点),这意味着它不会影响模型的最终输出结构。


    实际经验

    • Dropout 并不是所有模型都必须使用的。是否用它要视情况而定:

      • 如果模型有明显的过拟合现象(训练集准确率高,测试集低),可以考虑加 Dropout。

      • 若使用了其他正则手段(如 L2 正则、数据增强、早停、BatchNorm),Dropout 可能不是必须的。

     应用Dropout的CNN代码

    class CIFAR10_CNN_Dropout(nn.Module):
        def __init__(self):
            super().__init__()
            # conv1: 3 通道 (RGB) → 16 通道,3x3 卷积,padding=1 保持尺寸
            self.conv1 = nn.Conv2d(3, 16, kernel_size=3, padding=1)
            self.bn1 = nn.BatchNorm2d(16)  # 标准化 16 通道
            self.pool1 = nn.MaxPool2d(2)   # 2x2 池化,尺寸减半
            # conv2: 16 → 32 通道
            self.conv2 = nn.Conv2d(16, 32, kernel_size=3, padx=1)
            self.bn2 = nn.BatchNorm2d(32)
            self.pool2 = nn.MaxPool2d(2)
            # conv3: 32 → 64 通道
            self.conv3 = nn.Conv2d(32, 64, kernel_size=3, padding=1)
            self.bn3 = nn.BatchNorm2d(64)
            # Dropout: 50% 概率置零,防止全连接层过拟合
            self.dropout = nn.Dropout(p=0.5)
            # fc: 64*8*8 → 10 类
            self.fc = nn.Linear(64*8*8, 10)
            self.relu = nn.ReLU()
    
        def forward(self, x):
            # conv1 → bn1 → relu → pool1: 特征提取 + 标准化 + 非线性 + 下采样
            x = self.relu(self.bn1(self.conv1(x)))
            x = self.pool1(x)  # [batch, 16, 16, 16]
            # conv2 → bn2 → relu → pool2
            x = self.relu(self.bn2(self.conv2(x)))
            x = self.pool2(x)  # [batch, 32, 8, 8]
            # conv3 → bn3 → relu
            x = self.relu(self.bn3(self.conv3(x)))  # [batch, 64, 8, 8]
            # 展平为 [batch, 64*8*8]
            x = x.view(-1, 64*8*8)
            # Dropout: 训练时随机丢弃,评估时禁用
            x = self.dropout(x)
            # 全连接层输出 10 类 logits
            x = self.fc(x)
            return x
    
    model = CIFAR10_CNN_Dropout()  # 实例化模型
     在CNN中 Dropout一般只加在全连接层前

     Dropout在不同模型中的应用

    CNN(卷积神经网络)中的 Dropout

    使用位置:

    • 一般不用在卷积层(Conv layer)内部;

    • 常用于卷积层后的全连接层(FC)之间,尤其是网络末端。

    示例(以经典的 LeNet 为例):

    class CNN(nn.Module):
        def __init__(self):
            super(CNN, self).__init__()
            self.conv = nn.Sequential(
                nn.Conv2d(1, 32, 3, 1),
                nn.ReLU(),
                nn.MaxPool2d(2),
                nn.Conv2d(32, 64, 3, 1),
                nn.ReLU(),
                nn.MaxPool2d(2),
            )
            self.fc = nn.Sequential(
                nn.Flatten(),
                nn.Linear(64*5*5, 128),
                nn.ReLU(),
                nn.Dropout(p=0.5),  # Dropout常放在此处
                nn.Linear(128, 10)
            )
    
        def forward(self, x):
            x = self.conv(x)
            x = self.fc(x)
            return x
    

    建议:

    • 若模型不深、训练数据多,可以适当降低 Dropout 概率(如 0.3)甚至不加;

    • 若模型训练后存在明显的过拟合(训练准确率远高于测试准确率),建议加 Dropout。


     二、RNN / LSTM / GRU 中的 Dropout

    使用位置:

    • 常用于层与层之间,特别是多个 RNN 堆叠时;

    • 有些实现(如 PyTorch 的 nn.LSTM)支持直接加 dropout 参数;

    • 输入层与输出层之间也可以显式加 Dropout。

    示例:

    class RNNModel(nn.Module):
        def __init__(self):
            super().__init__()
            self.rnn = nn.LSTM(input_size=100, hidden_size=128, num_layers=2, dropout=0.5)
            self.fc = nn.Sequential(
                nn.Dropout(0.5),
                nn.Linear(128, 10)
            )
    
        def forward(self, x):
            out, _ = self.rnn(x)
            out = out[:, -1, :]  # 取最后一个时间步的输出
            return self.fc(out)
    

    注意:

    • 如果 num_layers=1,即 RNN 只有一层,设置 dropout 参数是无效的;

    • 推荐使用在多层 RNN 中间,或在输出层显式添加 Dropout。


    三、Transformer 中的 Dropout

    Transformer 中大量使用 Dropout,是结构的重要组成部分。

    使用位置:

    1. 注意力机制中的权重 Dropout(softmax之后)

    2. 前馈全连接层之间

    3. 残差连接后的 LayerNorm 之前

    4. 嵌入层和输出层

    示例(以 PyTorch 官方 TransformerEncoderLayer 为例):

    nn.TransformerEncoderLayer(
        d_model=512,
        nhead=8,
        dim_feedforward=2048,
        dropout=0.1,  # Dropout应在多个子模块中生效
    )
    

    实际经验:

    • Transformer 模型中 dropout 是默认启用的;

    • 如果训练集非常大,dropout 可适当调小(如 0.1 或 0.05);

    • 若 overfitting 明显,可以尝试调高至 0.3。


    总结

    模型类型推荐使用 Dropout 的位置Dropout 通常值
    CNN全连接层之间0.3~0.5
    RNN/LSTM/GRU层与层之间、输出层前0.3~0.5
    TransformerAttention 权重、FeedForward 层0.1~0.3

    调试Dropout参数

    1. 模型复杂度和大小

    • 深度模型(参数多):深度神经网络(如深层卷积神经网络、深层 LSTM 等)容易过拟合,通常需要较高的 Dropout 比例,可能使用 0.4~0.5 的 Dropout。

    • 浅层模型(参数少):对于较浅或简单的网络结构,Dropout 的比例可以较低,一般在 0.2~0.3,甚至在某些情况下可以不使用 Dropout。

    2. 数据集大小

    • 数据集较小:小数据集容易过拟合,通常需要较高的 Dropout 值(0.4~0.5),以避免模型过度记住训练数据。

    • 数据集较大:大数据集可以提供更多的样本信息,过拟合的风险较小,Dropout 比例可以适当降低,通常在 0.2~0.3 左右。

    3. 训练集与测试集的差异(过拟合)

    • 训练误差明显低于测试误差:这通常是过拟合的表现,建议提高 Dropout 的比例(例如从 0.2 提高到 0.4 或 0.5)。

    • 训练误差和测试误差差异较小:说明模型已经较好地泛化,Dropout 比例可以适当降低。

    4. 模型类型

    • CNN(卷积神经网络)

      • 在卷积层中一般不使用 Dropout,卷积层参数较少,并且卷积操作具有局部感知特性,不容易过拟合。

      • Dropout 通常用在全连接层(FC)之间。

      • 常用比例:0.3~0.5

    • RNN/LSTM/GRU(循环神经网络)

      • 循环神经网络有时间序列依赖,Dropout 应用时需要小心,尤其是在时间步之间加 Dropout 可能影响模型的学习。

      • 一般在 RNN 层的输出后使用 Dropout,或者直接在层间增加 Dropout。

      • 常用比例:0.3~0.5

    • Transformer(自注意力机制)

      • Transformer 中 Dropout 会应用于多个位置,包括注意力机制、前馈层等部分。

      • Dropout 不会影响每个序列的依赖关系,而是在不同位置丢弃一些信息,从而提高泛化能力。

      • 常用比例:0.1~0.3

    5. 验证集表现

    • 在训练过程中,通过验证集的损失和准确率来动态调整 Dropout 比例:

      • 如果验证集的表现不好(例如验证误差上升),可以增大 Dropout 率来减少模型的复杂性。

      • 如果验证集的表现很差,而训练集损失很低,可能是模型在训练集上过拟合,此时提高 Dropout 比例是一个常见的解决方法。


    如何调节 Dropout 比例?

    1. 网格搜索:可以通过网格搜索(Grid Search)或随机搜索(Random Search)来尝试不同的 Dropout 比例,找到最适合当前任务的值。通常选择几个常见值,例如 0.2、0.3、0.4,甚至 0.5,进行测试并选择最佳表现的值。

    2. 交叉验证:使用交叉验证(例如 K-fold)来测试不同 Dropout 比例对模型性能的影响,选择能够平衡训练和验证集表现的比例。

    3. 学习曲线:通过观察训练和验证的学习曲线,如果发现训练集损失持续下降而验证集性能不再提高甚至下降,可以考虑增加 Dropout 比例。

    4. 早停法(Early Stopping):配合早停方法(如验证集误差没有显著下降时停止训练)来避免过拟合,同时调整 Dropout 比例帮助控制模型复杂度。

    模型评估指标原理与实现

     模型评估指标原理

    • 准确率(Accuracy)
      • 定义:正确预测的样本数占总样本数的比例。
      • 公式:Accuracy = (TP + TN) / (TP + TN + FP + FN),其中 TP(真阳)、TN(真阴)、FP(假阳)、FN(假阴)。
      • TP(True Positive):真实为正,预测为正

      • TN(True Negative):真实为负,预测为负

      • FP(False Positive):真实为负,预测为正(假阳)

      • FN(False Negative):真实为正,预测为负(假阴)

      • 作用
        • 衡量总体分类性能,适合平衡数据集。
        • CIFAR-10(10 类平衡)常用。
      • 局限
        • 类不平衡时可能误导(如 90% 负类,模型全预测负类仍高准确率)。
      • CIFAR-10 应用
        • 目标:测试准确率 ~83-88%(Day 5 增强后)。
        • 反映整体性能,但需结合其他指标。
    • 混淆矩阵(Confusion Matrix)
      • 定义:显示每个类别的预测结果(实际 vs 预测)。
      • 结构
        • 行:实际类别,列:预测类别。
        • 对角线:正确预测,非对角线:错误预测。
      • 作用
        • 揭示模型对每个类别的性能(如 CIFAR-10 的“猫”易误分类为“狗”)。
        • 诊断类间混淆。
      • CIFAR-10 应用
        • 检查 10 类的预测分布,识别易混淆类别(如“汽车” vs “卡车”)。
        • 可视化帮助优化模型。
    • 精确率(Precision)、召回率(Recall)、F1 分数
      • 精确率
        • 定义:预测为正类的样本中,实际为正类的比例。
        • 公式:Precision = TP / (TP + FP)。
        • 作用:衡量正类预测的可靠性,适合假阳代价高的场景。
      • 召回率
        • 定义:实际正类中被正确预测的比例。
        • 公式:Recall = TP / (TP + FN)。
        • 作用:衡量正类覆盖率,适合漏检代价高的场景。
      • F1 分数
        • 定义:精确率和召回率的调和平均数。
        • 公式:F1 = 2 * (Precision * Recall) / (Precision + Recall)。
        • 作用:平衡精确率和召回率,适合类不平衡或需综合评估。
      • CIFAR-10 应用
        • 每类计算 Precision、Recall、F1,分析类别性能。
        • 适合检查模型对少数类(如“马”)的预测效果。
    • 其他指标(简述):
      • ROC 曲线和 AUC
        • 衡量二分类模型性能,CIFAR-10(多分类)需 one-vs-rest 扩展。
      • Top-k 准确率
        • 检查预测前 k 个类别是否包含正确类别,CIFAR-10 可用 Top-5。

    PyTorch 和 scikit-learn 实现

    • PyTorch
      • 准确率:手动计算(torch.argmax 比较预测和标签)。
      • 混淆矩阵:使用 torch.bincount 或 scikit-learn。
      • 精确率/召回率/F1:需 scikit-learn 或自定义。
      • 示例
        correct = (torch.argmax(logits, dim=1) == labels).sum().item()
        accuracy = correct / len(labels)
    • scikit-learn
      • 提供 confusion_matrix、classification_report 等。
      • 示例
        from sklearn.metrics import confusion_matrix, classification_report
        cm = confusion_matrix(true_labels, pred_labels)
        report = classification_report(true_labels, pred_labels)
    • 可视化
      • 使用 seaborn.heatmap 绘制混淆矩阵。
      • 示例
        import seaborn as sns
        sns.heatmap(cm, annot=True, fmt='d')
    3. CIFAR-10 中的应用
    • 为什么需要评估指标?
      • CIFAR-10 10 类平衡,但某些类(如“猫” vs “狗”)易混淆。
      • 准确率反映整体性能,但混淆矩阵和 F1 分数揭示类别细节。
    • 预期效果
      • 准确率:~83-88%(Day 5 增强后)。
      • 混淆矩阵:对角线值高,非对角线低。
      • F1 分数:每类 ~0.8-0.9,少数类可能较低。

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

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

    相关文章

    MySQL索引原理以及SQL优化(二)

    目录 1. 索引与约束 1.1 索引是什么 1.2 索引的目的 1.3 索引分类 1.3.1 数据结构 1.3.2 物理存储 1.3.3 列属性 1.3.4 列的个数 1.4 主键的选择 1.5 索引使用场景 1.6 索引的底层实现 1.6.1 索引存储 1.6.2 页 1.6.3 B 树 1.6.4 B 树层高问题 1.6.5 自增 id 1.7 innod…

    MATLAB中矩阵和数组的区别

    文章目录 前言环境配置1. 数据结构本质2. 运算规则&#xff08;1&#xff09;基本运算&#xff08;2&#xff09;特殊运算 3. 函数与操作4. 高维支持5. 创建方式 前言 在 MATLAB 中&#xff0c;矩阵&#xff08;Matrix&#xff09; 和 数组&#xff08;Array&#xff09; 的概…

    Desfire Ev1\Ev2\Ev3卡DES\3K3DES\AES加解密读写C#示例源码

    本示例使用的发卡器&#xff1a;https://item.taobao.com/item.htm?spma21dvs.23580594.0.0.1d292c1bYhsS9c&ftt&id917152255720 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using S…

    MySQL核心内容【完结】

    MySQL核心内容 文章目录 MySQL核心内容1.MySQL核心内容目录2.MySQL知识面扩展3.MySQL安装4.MySQL配置目录介绍Mysql配置远程ip连接 5.MySQL基础1.MySQL数据类型1.数值类型2.字符串类型3.日期和时间类型4.enum和set 2.MySQL运算符1.算数运算符2.逻辑运算符3.比较运算符 3.MySQL完…

    C++类和对象进阶 —— 与数据结构的结合

    &#x1f381;个人主页&#xff1a;工藤新一 &#x1f50d;系列专栏&#xff1a;C面向对象&#xff08;类和对象篇&#xff09; &#x1f31f;心中的天空之城&#xff0c;终会照亮我前方的路 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 文章目录 […

    Django之账号登录及权限管理

    账号登录及权限管理 目录 1.登录功能 2.退出登录 3.权限管理 4.代码展示合集 这篇文章, 会讲到如何实现账号登录。账号就是我们上一篇文章写的账号管理功能, 就使用那里面已经创建好的账号。这一次登录, 我们分为三种角色, 分别是员工, 领导, 管理员。不同的角色, 登录进去…

    EXCEL中嵌入其他表格等文件

    在EXCEL中嵌入其他表格 先放链接&#xff1a;https://jingyan.baidu.com/article/295430f11708c34d7e00509a.html 步骤如下&#xff1a; 1、打开一个需要嵌入新表格的excel表。 2、切换至“插入”菜单中&#xff0c;单击选择“对象”。 3、如下图所示&#xff0c;会弹出“对象…

    21. LangChain金融领域:合同审查与风险预警自动化

    引言&#xff1a;当AI成为24小时不眠的法律顾问 2025年某商业银行的智能合同系统&#xff0c;将百万级合同审查时间从平均3周缩短至9分钟&#xff0c;风险条款识别准确率达98.7%。本文将基于LangChain的金融法律框架&#xff0c;详解如何构建合规、精准、可追溯的智能风控体系…

    Springboot使用事件流调用大模型接口

    什么是事件流 事件流&#xff08;Event Stream&#xff09; 是一种处理和传递事件的方式&#xff0c;通常用于系统中的异步消息传递或实时数据流。在事件驱动架构&#xff08;Event-Driven Architecture&#xff09;中&#xff0c;事件流扮演着至关重要的角色。 事件流的概念…

    计算机网络--2

    TCP三次握手 TCP连接为什么需要三次握手 1. 由于网络情况复杂,可能会出现丢包现象,如果第二次握手的时候服务器就认为这个端口可用,然后一直开启,但是如果客户端未收到服务器发送的回复,那么就会重新发送请求,服务器就会重新开启一个端口连接,这样就会浪费一个端口。 三…

    尤雨溪宣布:Vue 生态正式引入 AI

    在前端开发领域,Vue 框架一直以其易用性和灵活性受到广大开发者的喜爱。 而如今,Vue 生态在人工智能(AI)领域的应用上又迈出了重要的一步。 尤雨溪近日宣布,Vue、Vite 和 Rolldown 的文档网站均已添加了llms.txt文件,这一举措旨在让大型语言模型(LLM)更方便地理解这些…

    蓝桥杯第十六届c组c++题目及个人理解

    本篇文章只是部分题目的理解&#xff0c;代码和思路仅供参考&#xff0c;切勿当成正确答案&#xff0c;欢迎各位小伙伴在评论区与博主交流&#xff01; 题目&#xff1a;2025 题目解析 核心提取 要求的数中至少有1个0、2个2、1个5 代码展示 #include<iostream> #incl…

    硬件工程师笔记——电子器件汇总大全

    目录 1、电阻 工作原理 欧姆定律 电阻的物理本质 一、限制电流 二、分压作用 三、消耗电能&#xff08;将电能转化为热能&#xff09; 2、压敏电阻 伏安特性 1. 过压保护 2. 电压调节 3. 浪涌吸收 4. 消噪与消火花 5. 高频应用 3、电容 工作原理 &#xff08;…

    微软推动智能体协同运作:支持 A2A、MCP 协议

    今日凌晨&#xff0c;微软宣布 Azure AI Foundry 和 Microsoft Copilot Studio 两大开发平台支持最新 Agent 开发协议 A2A&#xff0c;并与谷歌合作开发扩大该协议&#xff0c;这一举措对智能体赛道意义重大。 现状与变革意义 当前智能体领域类似战国时代&#xff0c;各家技术…

    Linxu实验五——NFS服务器

    一.NFS服务器介绍 NFS服务器&#xff08;Network File System&#xff09;是一种基于网络的分布式文件系统协议&#xff0c;允许不同操作系统的主机通过网络共享文件和目录3。其核心作用在于实现跨平台的资源透明访问&#xff0c;例如在Linux和Unix系统之间共享静态数据&#…

    20242817李臻《Linux⾼级编程实践》第9周

    20242817李臻《Linux⾼级编程实践》第9周 一、AI对学习内容的总结 第十章 Linux下的数据库编程 10.1 MySQL数据库简介 MySQL概述&#xff1a;MySQL是一个开源的关系型数据库管理系统&#xff0c;最初由瑞典MySQL AB公司开发&#xff0c;后经SUN公司收购&#xff0c;现属于O…

    开源分享:TTS-Web-Vue系列:SSML格式化功能与高级语音合成

    &#x1f3af; 本文是TTS-Web-Vue系列的第十二篇文章&#xff0c;重点介绍项目新增的SSML格式化功能以及SSML在语音合成中的应用。通过自动格式化和实时预览&#xff0c;我们显著提升了SSML编辑体验&#xff0c;让用户能够更精确地控制语音合成的细节&#xff0c;实现更自然、更…

    FAST-LIO笔记

    1.FAST-LIO FAST-LIO 是一个计算效率高、鲁棒性强的激光-惯性里程计系统。该系统通过紧耦合的迭代扩展卡尔曼滤波器&#xff08;IEKF&#xff09;将激光雷达特征点与IMU数据进行融合&#xff0c;使其在快速运动、噪声较大或环境复杂、存在退化的情况下仍能实现稳定的导航。 1…

    软考中级软件设计师——UML(统一建模语言)篇

    UML的词汇表包含3种构造块:事物、关系和图。事物是对模型中最具有代表性的成分的抽象;关系把事物结合在一起;图聚集了相关的事物。 一、事物 UML 事物是模型中的基本元素&#xff0c;分为 结构事物、行为事物、分组事物、注释事物。 1. 结构事物 类&#xff08;Class&#x…

    TSN网络与DIOS融合:破解煤矿井下电力系统越级跳闸难题

    一、引言 1.1 研究背景与意义 在现代煤矿生产中&#xff0c;井下电力系统作为整个煤矿生产的动力核心&#xff0c;其重要性不言而喻。煤矿井下的各类机械设备&#xff0c;如采煤机、刮板输送机、通风机、排水泵等&#xff0c;都依赖稳定的电力供应才能正常运行。电力系统的稳定…