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

P20:Inception v3算法实战与解析

  • 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
  • 🍖 原作者:K同学啊
    使用InceptionV3实现天气识别

一、模型结构

Inception v3是Google团队在2015年提出的第三代Inception模型,属于卷积神经网络(CNN)的经典架构之一,主要用于图像分类任务。它在Inception v1(即GoogLeNet)的基础上进行了多项优化,显著提升了模型性能和计算效率。以下是Inception v3的核心特点及其与v1的主要区别:


Inception v3的核心改进

  1. 卷积核分解与优化

    • 对称分解:将大卷积核(如5×5)分解为多个小卷积核(如两个3×3),减少参数量的同时保持感受野范围。例如,5×5卷积分解为两个3×3卷积,参数量减少约28%。
    • 非对称分解:进一步将3×3卷积分解为1×3和3×1的串联结构,减少计算成本(例如,3×3卷积分解后计算量降低33%)。这种设计不仅节约参数,还能捕获更丰富的空间特征。
  2. 高效的网格尺寸缩减(Grid Size Reduction)

    • 通过结合步长为2的卷积层和池化层,并行处理特征图后再拼接,避免信息丢失。例如,使用3×3卷积(步长2)和3×3最大池化(步长2)并行,扩大特征图通道数同时缩小尺寸。
  3. 正则化与训练策略

    • 标签平滑(Label Smoothing):通过软化标签(如将正确标签从1改为0.9,其他类别均分0.1),减少模型过拟合,提升泛化能力。
    • 批量归一化(Batch Normalization):广泛用于卷积层后,加速训练收敛并提高稳定性。
    • 优化器改进:采用RMSProp替代传统SGD,自适应调整学习率,提升训练效率。
  4. 模块化设计

    • Inception v3包含三种不同结构的Inception模块(35×35、17×17、8×8网格),分别用于处理不同尺度的特征图。模块内部进一步引入分支中的分支(如1×3和3×1卷积的组合),形成更复杂的非线性表达。

Inception v3与v1的主要区别

特性Inception v1Inception v3
卷积核分解引入对称与非对称分解(如3×3→1×3+3×1)
网络深度22层(含9个Inception模块)46层(含11个Inception模块)
正则化技术无批量归一化,使用辅助分类器缓解梯度消失批量归一化 + 标签平滑 + 辅助分类器正则化
计算效率5×5卷积计算成本高通过分解卷积核降低计算量,参数量减少约30%
错误率(ImageNet)Top-5错误率6.67%Top-5错误率3.5%
模块设计基础Inception模块(含1×1、3×3、5×5卷积)复杂模块(如非对称卷积、多分支组合)

关键改进的意义

  1. 性能提升:通过卷积分解和模块优化,v3在保持较低计算成本的同时,显著降低了分类错误率(较v1提升近50%)。
  2. 灵活性增强:非对称卷积和模块化设计使模型能更灵活地捕捉多尺度特征,适应不同输入尺寸。
  3. 训练稳定性:批量归一化和标签平滑等技术有效缓解了过拟合,加速了模型收敛。

程序结构图

在这里插入图片描述

二、 前期准备

1. 导入库

import torch
import torch.nn as nn
import torchvision.transforms as transforms
import torchvision
from torchvision import transforms, datasets
import os,PIL,pathlib
import os,PIL,random,pathlib
import torch.nn.functional as F
from PIL import Image
import matplotlib.pyplot as plt
#隐藏警告
import warnings

2.导入数据

data_dir = './data/4-data/'
data_dir = pathlib.Path(data_dir)
#print(data_dir)
data_paths = list(data_dir.glob('*'))
classeNames = [str(path).split("\\")[2] for path in data_paths]
#print(classeNames)
total_datadir = './data/4-data/'train_transforms = transforms.Compose([transforms.Resize([224, 224]),  # 将输入图片resize成统一尺寸transforms.ToTensor(),          # 将PIL Image或numpy.ndarray转换为tensor,并归一化到[0,1]之间transforms.Normalize(           # 标准化处理-->转换为标准正太分布(高斯分布),使模型更容易收敛mean=[0.485, 0.456, 0.406],std=[0.229, 0.224, 0.225])  # 其中 mean=[0.485,0.456,0.406]与std=[0.229,0.224,0.225] 从数据集中随机抽样计算得到的。
])total_data = datasets.ImageFolder(total_datadir,transform=train_transforms)

3.划分数据集

train_size = int(0.8 * len(total_data))
test_size  = len(total_data) - train_size
train_dataset, test_dataset = torch.utils.data.random_split(total_data, [train_size, test_size])
batch_size = 32train_dl = torch.utils.data.DataLoader(train_dataset,batch_size=batch_size,shuffle=True,num_workers=1)
test_dl = torch.utils.data.DataLoader(test_dataset,batch_size=batch_size,shuffle=True,num_workers=1)

三、模型设计

1. 神经网络的搭建

class BasicConv2d(nn.Module):def __init__(self, in_channels, out_channels, **kwargs):super().__init__()self.conv = nn.Conv2d(in_channels, out_channels, bias=False, **kwargs)self.bn = nn.BatchNorm2d(out_channels, eps=0.001)def forward(self, x):x = self.conv(x)x = self.bn(x)return F.relu(x, inplace=True)class InceptionA(nn.Module):def __init__(self, in_channels, pool_features):super(InceptionA, self).__init__()self.branch1x1 = BasicConv2d(in_channels, 64, kernel_size=1)  # 1self.branch5x5_1 = BasicConv2d(in_channels, 48, kernel_size=1)self.branch5x5_2 = BasicConv2d(48, 64, kernel_size=5, padding=2)self.branch3x3dbl_1 = BasicConv2d(in_channels, 64, kernel_size=1)self.branch3x3dbl_2 = BasicConv2d(64, 96, kernel_size=3, padding=1)self.branch3x3dbl_3 = BasicConv2d(96, 96, kernel_size=3, padding=1)self.branch_pool = BasicConv2d(in_channels, pool_features, kernel_size=1)def forward(self, x):branch1x1 = self.branch1x1(x)branch5x5 = self.branch5x5_1(x)branch5x5 = self.branch5x5_2(branch5x5)branch3x3dbl = self.branch3x3dbl_1(x)branch3x3dbl = self.branch3x3dbl_2(branch3x3dbl)branch3x3dbl = self.branch3x3dbl_3(branch3x3dbl)branch_pool = F.avg_pool2d(x, kernel_size=3, stride=1, padding=1)branch_pool = self.branch_pool(branch_pool)outputs = [branch1x1, branch5x5, branch3x3dbl, branch_pool]return torch.cat(outputs, 1)class InceptionB(nn.Module):def __init__(self, in_channels, channels_7x7):super(InceptionB, self).__init__()self.branch1x1 = BasicConv2d(in_channels, 192, kernel_size=1)c7 = channels_7x7self.branch7x7_1 = BasicConv2d(in_channels, c7, kernel_size=1)self.branch7x7_2 = BasicConv2d(c7, c7, kernel_size=(1, 7), padding=(0, 3))self.branch7x7_3 = BasicConv2d(c7, 192, kernel_size=(7, 1), padding=(3, 0))self.branch7x7dbl_1 = BasicConv2d(in_channels, c7, kernel_size=1)self.branch7x7dbl_2 = BasicConv2d(c7, c7, kernel_size=(7, 1), padding=(3, 0))self.branch7x7dbl_3 = BasicConv2d(c7, c7, kernel_size=(1, 7), padding=(0, 3))self.branch7x7dbl_4 = BasicConv2d(c7, c7, kernel_size=(7, 1), padding=(3, 0))self.branch7x7dbl_5 = BasicConv2d(c7, 192, kernel_size=(1, 7), padding=(0, 3))self.branch_pool = BasicConv2d(in_channels, 192, kernel_size=1)def forward(self, x):branch1x1 = self.branch1x1(x)branch7x7 = self.branch7x7_1(x)branch7x7 = self.branch7x7_2(branch7x7)branch7x7 = self.branch7x7_3(branch7x7)branch7x7dbl = self.branch7x7dbl_1(x)branch7x7dbl = self.branch7x7dbl_2(branch7x7dbl)branch7x7dbl = self.branch7x7dbl_3(branch7x7dbl)branch7x7dbl = self.branch7x7dbl_4(branch7x7dbl)branch7x7dbl = self.branch7x7dbl_5(branch7x7dbl)branch_pool = F.avg_pool2d(x, kernel_size=3, stride=1, padding=1)branch_pool = self.branch_pool(branch_pool)outputs = [branch1x1, branch7x7, branch7x7dbl, branch_pool]return torch.cat(outputs, 1)class InceptionC(nn.Module):def __init__(self, in_channels):super(InceptionC, self).__init__()self.branch1x1 = BasicConv2d(in_channels, 320, kernel_size=1)self.branch3x3_1 = BasicConv2d(in_channels, 384, kernel_size=1)self.branch3x3_2a = BasicConv2d(384, 384, kernel_size=(1, 3), padding=(0, 1))self.branch3x3_2b = BasicConv2d(384, 384, kernel_size=(3, 1), padding=(1, 0))self.branch3x3dbl_1 = BasicConv2d(in_channels, 448, kernel_size=1)self.branch3x3dbl_2 = BasicConv2d(448, 384, kernel_size=3, padding=1)self.branch3x3dbl_3a = BasicConv2d(384, 384, kernel_size=(1, 3), padding=(0, 1))self.branch3x3dbl_3b = BasicConv2d(384, 384, kernel_size=(3, 1), padding=(1, 0))self.branch_pool = BasicConv2d(in_channels, 192, kernel_size=1)def forward(self, x):branch1x1 = self.branch1x1(x)branch3x3 = self.branch3x3_1(x)branch3x3 = [self.branch3x3_2a(branch3x3),self.branch3x3_2b(branch3x3),]branch3x3 = torch.cat(branch3x3, 1)branch3x3dbl = self.branch3x3dbl_1(x)branch3x3dbl = self.branch3x3dbl_2(branch3x3dbl)branch3x3dbl = [self.branch3x3dbl_3a(branch3x3dbl),self.branch3x3dbl_3b(branch3x3dbl),]branch3x3dbl = torch.cat(branch3x3dbl, 1)branch_pool = F.avg_pool2d(x, kernel_size=3, stride=1, padding=1)branch_pool = self.branch_pool(branch_pool)outputs = [branch1x1, branch3x3, branch3x3dbl, branch_pool]return torch.cat(outputs, 1)class ReductionA(nn.Module):def __init__(self, in_channels):super(ReductionA, self).__init__()self.branch3x3 = BasicConv2d(in_channels, 384, kernel_size=3, stride=2)self.branch3x3dbl_1 = BasicConv2d(in_channels, 64, kernel_size=1)self.branch3x3dbl_2 = BasicConv2d(64, 96, kernel_size=3, padding=1)self.branch3x3dbl_3 = BasicConv2d(96, 96, kernel_size=3, stride=2)def forward(self, x):branch3x3 = self.branch3x3(x)branch3x3dbl = self.branch3x3dbl_1(x)branch3x3dbl = self.branch3x3dbl_2(branch3x3dbl)branch3x3dbl = self.branch3x3dbl_3(branch3x3dbl)branch_pool = F.max_pool2d(x, kernel_size=3, stride=2)outputs = [branch3x3, branch3x3dbl, branch_pool]return torch.cat(outputs, 1)class ReductionB(nn.Module):def __init__(self, in_channels):super(ReductionB, self).__init__()self.branch3x3_1 = BasicConv2d(in_channels, 192, kernel_size=1)self.branch3x3_2 = BasicConv2d(192, 320, kernel_size=3, stride=2)self.branch7x7x3_1 = BasicConv2d(in_channels, 192, kernel_size=1)self.branch7x7x3_2 = BasicConv2d(192, 192, kernel_size=(1, 7), padding=(0, 3))self.branch7x7x3_3 = BasicConv2d(192, 192, kernel_size=(7, 1), padding=(3, 0))self.branch7x7x3_4 = BasicConv2d(192, 192, kernel_size=3, stride=2)def forward(self, x):branch3x3 = self.branch3x3_1(x)branch3x3 = self.branch3x3_2(branch3x3)branch7x7x3 = self.branch7x7x3_1(x)branch7x7x3 = self.branch7x7x3_2(branch7x7x3)branch7x7x3 = self.branch7x7x3_3(branch7x7x3)branch7x7x3 = self.branch7x7x3_4(branch7x7x3)branch_pool = F.max_pool2d(x, kernel_size=3, stride=2)outputs = [branch3x3, branch7x7x3, branch_pool]return torch.cat(outputs, 1)class InceptionAux(nn.Module):def __init__(self, in_channels, num_classes):super(InceptionAux, self).__init__()self.conv0 = BasicConv2d(in_channels, 128, kernel_size=1)self.conv1 = BasicConv2d(128, 768, kernel_size=5)self.conv1.stddev = 0.01self.fc = nn.Linear(768, num_classes)self.fc.stddev = 0.001def forward(self, x):# 17 x 17 x 768x = F.avg_pool2d(x, kernel_size=5, stride=3)# 5 x 5 x 768x = self.conv0(x)# 5 x 5 x 128x = self.conv1(x)# 1 x 1 x 768x = x.view(x.size(0), -1)# 768x = self.fc(x)# 1000return ximport torch.nn.functional as Fclass BasicConv2d(nn.Module):def __init__(self, in_channels, out_channels, **kwargs):super(BasicConv2d, self).__init__()self.conv = nn.Conv2d(in_channels, out_channels, bias=False, **kwargs)self.bn = nn.BatchNorm2d(out_channels, eps=0.001)def forward(self, x):x = self.conv(x)x = self.bn(x)return F.relu(x, inplace=True)class InceptionV3(nn.Module):def __init__(self, num_classes=1000, aux_logits=False, transform_input=False):super(InceptionV3, self).__init__()self.aux_logits = aux_logitsself.transform_input = transform_inputself.Conv2d_1a_3x3 = BasicConv2d(3, 32, kernel_size=3, stride=2)self.Conv2d_2a_3x3 = BasicConv2d(32, 32, kernel_size=3)self.Conv2d_2b_3x3 = BasicConv2d(32, 64, kernel_size=3, padding=1)self.Conv2d_3b_1x1 = BasicConv2d(64, 80, kernel_size=1)self.Conv2d_4a_3x3 = BasicConv2d(80, 192, kernel_size=3)self.Mixed_5b = InceptionA(192, pool_features=32)self.Mixed_5c = InceptionA(256, pool_features=64)self.Mixed_5d = InceptionA(288, pool_features=64)self.Mixed_6a = ReductionA(288)self.Mixed_6b = InceptionB(768, channels_7x7=128)self.Mixed_6c = InceptionB(768, channels_7x7=160)self.Mixed_6d = InceptionB(768, channels_7x7=160)self.Mixed_6e = InceptionB(768, channels_7x7=192)if aux_logits:self.AuxLogits = InceptionAux(768, num_classes)self.Mixed_7a = ReductionB(768)self.Mixed_7b = InceptionC(1280)self.Mixed_7c = InceptionC(2048)self.fc = nn.Linear(2048, num_classes)def forward(self, x):if self.transform_input:  # 1x = x.clone()x[:, 0] = x[:, 0] * (0.229 / 0.5) + (0.485 - 0.5) / 0.5x[:, 1] = x[:, 1] * (0.224 / 0.5) + (0.456 - 0.5) / 0.5x[:, 2] = x[:, 2] * (0.225 / 0.5) + (0.406 - 0.5) / 0.5# 299 x 299 x 3x = self.Conv2d_1a_3x3(x)# 149 x 149 x 32x = self.Conv2d_2a_3x3(x)# 147 x 147 x 32x = self.Conv2d_2b_3x3(x)# 147 x 147 x 64x = F.max_pool2d(x, kernel_size=3, stride=2)# 73 x 73 x 64x = self.Conv2d_3b_1x1(x)# 73 x 73 x 80x = self.Conv2d_4a_3x3(x)# 71 x 71 x 192x = F.max_pool2d(x, kernel_size=3, stride=2)# 35 x 35 x 192x = self.Mixed_5b(x)# 35 x 35 x 256x = self.Mixed_5c(x)# 35 x 35 x 288x = self.Mixed_5d(x)# 35 x 35 x 288x = self.Mixed_6a(x)# 17 x 17 x 768x = self.Mixed_6b(x)# 17 x 17 x 768x = self.Mixed_6c(x)# 17 x 17 x 768x = self.Mixed_6d(x)# 17 x 17 x 768x = self.Mixed_6e(x)# 17 x 17 x 768if self.training and self.aux_logits:aux = self.AuxLogits(x)# 17 x 17 x 768x = self.Mixed_7a(x)# 8 x 8 x 1280x = self.Mixed_7b(x)# 8 x 8 x 2048x = self.Mixed_7c(x)# 8 x 8 x 2048x = F.avg_pool2d(x, kernel_size=8)# 1 x 1 x 2048x = F.dropout(x, training=self.training)# 1 x 1 x 2048x = x.view(x.size(0), -1)# 2048x = self.fc(x)# 1000 (num_classes)if self.training and self.aux_logits:return x, auxreturn x#model = InceptionV3().to(device)

2.设置损失值等超参数

# 修改3: 初始化InceptionV3模型
model = InceptionV3(num_classes=len(classeNames),  # 适配数据集类别数aux_logits=False,  # 禁用辅助分类器transform_input=False  # 禁用内置输入转换
).to(device)
print(summary.summary(model, (3, 299, 299)))
loss_fn = nn.CrossEntropyLoss()
learn_rate = 1e-4
# 修改4: 推荐使用Adam优化器
opt = torch.optim.Adam(model.parameters(), lr=learn_rate, weight_decay=1e-4)
----------------------------------------------------------------Layer (type)               Output Shape         Param #
================================================================Conv2d-1         [-1, 32, 149, 149]             864BatchNorm2d-2         [-1, 32, 149, 149]              64BasicConv2d-3         [-1, 32, 149, 149]               0Conv2d-4         [-1, 32, 147, 147]           9,216BatchNorm2d-5         [-1, 32, 147, 147]              64BasicConv2d-6         [-1, 32, 147, 147]               0Conv2d-7         [-1, 64, 147, 147]          18,432BatchNorm2d-8         [-1, 64, 147, 147]             128BasicConv2d-9         [-1, 64, 147, 147]               0....								.....BatchNorm2d-288            [-1, 384, 8, 8]             768BasicConv2d-289            [-1, 384, 8, 8]               0Conv2d-290            [-1, 192, 8, 8]         393,216BatchNorm2d-291            [-1, 192, 8, 8]             384BasicConv2d-292            [-1, 192, 8, 8]               0InceptionC-293           [-1, 2048, 8, 8]               0Linear-294                    [-1, 4]           8,196
================================================================
Total params: 21,793,764
Trainable params: 21,793,764
Non-trainable params: 0
----------------------------------------------------------------
Input size (MB): 1.02
Forward/backward pass size (MB): 224.12
Params size (MB): 83.14
Estimated Total Size (MB): 308.28
----------------------------------------------------------------

3. 设置训练函数

def train(dataloader, model, loss_fn, optimizer):model.train()total_loss, correct = 0, 0for X, y in dataloader:X, y = X.to(device), y.to(device)pred = model(X)loss = loss_fn(pred, y)optimizer.zero_grad()loss.backward()optimizer.step()total_loss += loss.item()correct += (pred.argmax(1) == y).type(torch.float).sum().item()return correct / len(dataloader.dataset), total_loss / len(dataloader)

4. 设置测试函数

def test(dataloader, model, loss_fn):model.eval()total_loss, correct = 0, 0with torch.no_grad():for X, y in dataloader:X, y = X.to(device), y.to(device)pred = model(X)total_loss += loss_fn(pred, y).item()correct += (pred.argmax(1) == y).type(torch.float).sum().item()return correct / len(dataloader.dataset), total_loss / len(dataloader)

5. 创建导入本地图片预处理模块

def preprocess_image(image_path):transform = transforms.Compose([transforms.Resize([299, 299]),transforms.ToTensor(),transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])])image = Image.open(image_path).convert('RGB')  # 确保RGB格式return transform(image).unsqueeze(0).to(device)

6. 主函数

if __name__ == '__main__':epochs = 10train_acc, train_loss = [], []test_acc, test_loss = [], []for epoch in range(epochs):epoch_train_acc, epoch_train_loss = train(train_dl, model, loss_fn, opt)epoch_test_acc, epoch_test_loss = test(test_dl, model, loss_fn)# 记录指标train_acc.append(epoch_train_acc)train_loss.append(epoch_train_loss)test_acc.append(epoch_test_acc)test_loss.append(epoch_test_loss)# 打印进度print(f"Epoch {epoch + 1}/{epochs}")print(f"Train Acc: {epoch_train_acc * 100:.2f}% | Test Acc: {epoch_test_acc * 100:.2f}%")print(f"Train Loss: {epoch_train_loss:.4f} | Test Loss: {epoch_test_loss:.4f}\n")# 保存模型torch.save(model.state_dict(), "inceptionv3_weather.pth")# 示例预测test_image = preprocess_image('./data/img.jpg')with torch.no_grad():output = model(test_image)prediction = classeNames[output.argmax().item()]print(f"\nFinal Prediction: {prediction}")

结果

Epoch 1/10
Train Acc: 75.33% | Test Acc: 24.89%
Train Loss: 0.6807 | Test Loss: 3.5399
Epoch 2/10
Train Acc: 89.00% | Test Acc: 93.33%
Train Loss: 0.3573 | Test Loss: 0.1631
Epoch 3/10
Train Acc: 90.33% | Test Acc: 94.67%
Train Loss: 0.3525 | Test Loss: 0.1844
Epoch 4/10
Train Acc: 89.78% | Test Acc: 93.78%
Train Loss: 0.3061 | Test Loss: 0.2160
Epoch 5/10
Train Acc: 91.44% | Test Acc: 95.56%
Train Loss: 0.2578 | Test Loss: 0.1473
Epoch 6/10
Train Acc: 93.67% | Test Acc: 90.22%
Train Loss: 0.2180 | Test Loss: 0.3774
Epoch 7/10
Train Acc: 92.78% | Test Acc: 96.44%
Train Loss: 0.2151 | Test Loss: 0.0971
Epoch 8/10
Train Acc: 94.89% | Test Acc: 94.67%
Train Loss: 0.1631 | Test Loss: 0.1472
Epoch 9/10
Train Acc: 92.56% | Test Acc: 94.22%
Train Loss: 0.2332 | Test Loss: 0.1486
Epoch 10/10
Train Acc: 93.89% | Test Acc: 95.11%
Train Loss: 0.2795 | Test Loss: 0.1317

在这里插入图片描述

相关文章:

P20:Inception v3算法实战与解析

🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 使用InceptionV3实现天气识别 一、模型结构 Inception v3是Google团队在2015年提出的第三代Inception模型,属于卷积神经网络(CNN&…...

C++ - 数据容器之 list(创建与初始化、元素访问、容量判断、元素遍历、添加元素、删除元素)

一、创建与初始化 引入 <list> 并使用 std 命名空间 #include <list>using namespace std;创建一个空 list list<int> my_list;创建一个包含 5 个元素&#xff0c;每个元素初始化为 0 的 list list<int> my_list(5);创建一个包含 5 个元素&#xf…...

deepseek 技巧整理

1、导出word 和excel 功能&#xff0c;在使用以下提示词。 请帮我列出减肥期间可以吃的水果&#xff0c;并分析该水果含有的营养元素&#xff0c;以表格的形式星现。1.要以html的方式输出 2.要可以直接运行 3.页面要提供可以直接下载word和excel功能...

柔性PZT压电薄膜多维力传感器在微创手术机器人的应用

随着医疗技术的迅速发展&#xff0c;微创手术机器人正在成为外科手术的重要助手。与传统开放式手术相比&#xff0c;微创手术创伤小、恢复快、感染率低&#xff0c;对手术器械的精细操控性和感知能力提出了更高要求。多维力传感器作为机器人“触觉”的核心部件&#xff0c;对提…...

Java学习手册:Spring Boot 自动配置与快速开发

一、Spring Boot 自动配置概述 Spring Boot 的自动配置是其核心特性之一&#xff0c;它能够根据项目的依赖和配置自动地进行 Spring 应用程序的配置。自动配置的工作流程如下&#xff1a; SpringBootApplication 注解 &#xff1a;这是自动配置的起点&#xff0c;它是一个组合…...

ValueError: expected sequence of length 8 at dim 2 (got 0)

问题描述 在PyCharm中使用强化学习运行Python代码时报错ValueError: expected sequence of length 8 at dim 2 (got 0)。 问题原因 实际上原因就是gym中的env对象的reset、step等方法的返回值作了改动 解决方法 1、第一步&#xff1a; 将代码块中的&#xff08;记得改的需…...

AI赋能新媒体运营:效率提升与能力突破实战指南

AI赋能新媒体运营&#xff1a;效率提升与能力突破实战指南 在信息爆炸的新媒体时代&#xff0c;运营人员面临着内容产出压力大、数据分析复杂、用户互动需求高等多重挑战。AI技术的迅猛发展为新媒体运营带来了革命性的变革可能。本文将为您揭示如何利用AI工具提升工作效率、培…...

单词规律(简单)

思路和同构字符串那道题一样。、但是这道题要注意的地方就是&#xff0c;检查 pattern 和 s 的单词数量是否一致以及在进行字符串比较的时候应该用equals来进行比较&#xff0c;而不能用“&#xff01;”&#xff0c;“&#xff01;”比较的是对象引用而非内容。 class Soluti…...

QGraphicsView QGraphicsScene QGraphicsItem 的关系

在Qt的图形视图框架中&#xff0c;QGraphicsView、QGraphicsScene和QGraphicsItem 三者协同工作&#xff0c;构成一个分层的结构&#xff0c;用于高效管理和显示复杂的图形界面。以下是它们的关系和职责的详细说明&#xff1a; 1. 核心角色 类名职责类比QGraphicsItem场景中的…...

re题(52)BUUCTF-[FlareOn5]Minesweeper Championship Registration

BUUCTF在线评测 jadx打开if条件就是flag...

c++环境和vscode常用的一些有用插件

环境 WSL需要安装cmake 编译器g14 应该是包含了所有std:c23把好像包含部分c26 vscode 需要插件cmake vscode clangd 方便提示吧 File Watch 插件目的在保存.h/.cpp文件时候自动执行vscode 的cmake吧 error lens 方便每次显示错误和警告的提示懒得每次点击去看错误 Edit Sugge…...

UE自动索敌插件Target System Component

https://www.fab.com/zh-cn/listings/9088334d-3bde-4e10-a937-baeb780f880f ​ 一个完全用 C 编写的 UE插件&#xff0c;添加了对简单相机锁定/瞄准系统的支持。它最初​​在蓝图中开发和测试&#xff0c;然后转换并重写为 C 模块和插件。 特征&#xff1a; 可通过一组可在…...

从括号匹配看栈:数据结构入门的实战与原理

在计算机科学的世界里&#xff0c;数据结构是程序员的 “瑞士军刀”&#xff0c;不同的数据结构适用于不同的场景&#xff0c;能高效解决各类问题。其中&#xff0c;栈作为一种简单却强大的数据结构&#xff0c;在很多实际应用中发挥着关键作用。今天&#xff0c;我们就通过一个…...

ReLU函数及其Python实现

ReLU函数及其Python实现 文章目录 ReLU函数及其Python实现1. ReLU函数定义2. Python实现3. 在深度学习中的应用总结 1. ReLU函数定义 ReLU&#xff08;Rectified Linear Unit&#xff0c;修正线性单元&#xff09;函数是深度学习中常用的激活函数之一。它的定义非常简单&#…...

Rain World 雨世界 [DLC 解锁] [Steam Epic] [Windows SteamOS]

Rain World 雨世界 [DLC 解锁] [Steam & Epic] [Windows & SteamOS] 需要有游戏正版基础本体&#xff0c;安装路径不能带有中文&#xff0c;或其它非常规拉丁字符&#xff1b; DLC 版本 至最新全部 DLC 后续可能无法及时更新文章&#xff0c;具体最新版本见下载文件说明…...

n8n 工作流画布上下左右移动的操作方法

n8n 工作流画布上下左右移动的操作方法 1. n8n 工作流画布上下移动2. n8n 工作流画布左右移动3. n8n 工作流画布扩大和缩小4. n8n 工作流画布缩放到适合 1. n8n 工作流画布上下移动 鼠标滚轮向上滚动是向上移动鼠标滚轮向下滚动是向下移动 2. n8n 工作流画布左右移动 按照Shi…...

Linux 常用命令合集

一、用户权限管理 切换管理员身份 sudo su&#xff1a;普通用户临时获取 root 权限&#xff0c;需输入当前用户密码。管理员提示符&#xff1a;root主机名:路径#。退出管理员&#xff1a;exit&#xff0c;返回普通用户状态。 以管理员身份执行命令 sudo 命令 参数&#xff1a;…...

B站Michale_ee——ESP32_IDF SDK——FreeRTOS_7 流数据缓冲区、消息缓冲区

一、Stream Buffer流数据缓冲区 流数据缓冲区用来处理像音频之类的流数据&#xff1b; 1.API简介 &#xff08;1&#xff09;创建流数据缓冲区 &#xff08;2&#xff09;向流数据缓冲区中发送数据 &#xff08;3&#xff09;从流数据缓冲区中接收数据 2.示例代码及运行结果…...

HCL(HashiCorp Configuration Language)是一种结构化配置语言

HCL&#xff08;HashiCorp Configuration Language&#xff09;是一种结构化配置语言&#xff0c;语法简洁且可读性强&#xff0c;广泛用于 Docker Buildx Bake、Terraform、Nomad 等工具的配置。以下是其核心语法规则和示例&#xff1a; 1. 基础结构 HCL 使用 块&#xff08;…...

k9s 一个基于终端的 Kubernetes 集群管理工具(TUI)

k9s 是一个基于终端的 Kubernetes 集群管理工具&#xff08;TUI&#xff09;&#xff0c;通过快捷键和交互式命令快速操作资源。以下是其核心用法和常见场景&#xff1a; 1. 基本命令 启动 k9s k9s # 默认连接当前 kubeconfig 配置的集群k9s -n <namespace> # 指定命…...

高等数学-第七版-下册 选做记录 习题10-1

1. 4. 5....

DBeaver连接人大金仓数据库V9

1、官网下载驱动jdbc 打开官网地址&#xff0c;找到下面的V9R1-JDBC&#xff0c;点击后面的下载即可&#xff0c;保存到本地 2、解压最新版的驱动程序 3、把***_JDBC文件夹内的驱动程序复制到DBeaver安装目录下的plugins文件夹里 4、打开dbeaver程序&#xff0c;增加kingbase…...

跟韩学AiOps系列之2025学MySQL系列_如何在MySQL中开启和提交事务?!

跟韩学AiOps系列之2025学MySQL系列_如何在MySQL中开启和提交事务&#xff1f;! 文章目录 一、事务的基本操作1. 开启事务2. 执行事务内操作3. 提交事务4. 回滚事务 二、验证示例&#xff08;适用于 MySQL 5.7&#xff09;步骤 1&#xff1a;准备测试表和数据步骤 2&#xff1a…...

【KWDB 创作者计划】利用KWDB解决工业物联网场景中的海量数据管理难题的思考

利用KWDB解决工业物联网场景中的海量数据管理难题 一、什么是KWDB&#xff1f;二、工业物联网场景中的数据管理痛点2.1 数据量大且增长迅速2.2 数据多样性2.3 实时性需求2.4 数据分析复杂性 三、KWDB 的技术优势与架构解读3.1 时间序列数据的高效管理3.2 高吞吐写入性能3.3 灵活…...

分享国产AI工作流集成数据库完成业务处理

在现代企业应用中&#xff0c;业务流程的自动化和数据管理是提高效率的关键。Taskflow 作为一个强大的任务流管理工具&#xff0c;可以通过集成数据库实现复杂业务逻辑的处理。本文将分享如何利用 Taskflow 集成数据库&#xff0c;优化业务流程&#xff0c;并展示一个实际案例。…...

【每日八股】复习 Redis Day5:集群(上)

文章目录 复习昨日内容缓存雪崩、击穿、穿透的问题描述及解决方案如何保证数据库和缓存的一致性普通方案进阶方案 如何保证缓存删除一定成功&#xff1f;针对业务一致性要求高的场景&#xff0c;如何确保缓存与数据库的一致性&#xff1f;如何避免缓存失效&#xff1f;如何实现…...

linux进程的复制和替换

Linux 进程的复制与替换 一、主函数参数 在 C 语言里&#xff0c;main 函数能够接收参数&#xff0c;其标准形式如下&#xff1a; int main(int argc, char* argv[], char* envp[]);argc&#xff1a;代表命令行参数的数量&#xff0c;为整数类型。argv&#xff1a;是一个字符…...

【质量管理】现代TRIZ问题识别中的功能分析——相互接触分析

在文章【质量管理】现代TRIZ中问题识别中的功能分析——组件分析-CSDN博客中我们知道了如何对产品进行组件分析&#xff0c;那么组件分析出来有什么作用呢&#xff1f;组件分析就是为了接下来相互接触分析使用的。 什么是相互接触 相互接触分析是功能分析的一部分&#xff0c;…...

一种快速计算OTA PSRR的方法(Ⅱ)

1.仿真验证 1.1仿真设置 1.1.1 Test-bench原理 1.1.2 管子参数设置 为了公平地比较性能&#xff0c;设置所有OTA 的输入晶体管M1和M2为相同的gm和偏置电流1uA。 具体晶体管宽长比设置参见5.参考资料中的论文2。 1.2仿真验证 1.2.1 CM OTA 1&#xff09;小信号参数 M1 M…...

【C++】通过红黑树封装map和set

前言&#xff1a; 通过之前的学习&#xff0c;我们已经学会了红黑树和map、set。这次我们要实现自己的map和set&#xff0c;对&#xff0c;使用红黑树进行封装&#xff01; 当然&#xff0c;红黑树内容这里就不在赘述&#xff0c;我们会复用红黑树的代码&#xff0c;所以先将…...

【Java IO流】字节输入流FileInputStream、字节输出流FileOutputStream

目录 0.前言 1.FileInputStream 1.1 概述 1.2 构造方法 1.3 成员方法 1.4 FileInputStream读取文件案例演示 2.FileOutputStream 2.1 概述 2.2 构造方法 2.3 成员方法 2.4 写入文本文件案例演示 3.FileInputStream FileOutputStream拷贝文件 0.前言 本文讲解的是…...

信息收集新利器:SSearch Chrome 插件来了

SSearch 下载地址 SSearch &#x1f623;用途 每次谷歌语法搜索时还得自己写&#xff0c;我想省事一点&#xff0c;弄了一个插件&#xff0c;先加了几个常用的语法&#xff0c;点击后会跳转到对应搜索页面&#xff0c;也可以直接在搜索框微调 后续也会加些其他语法 &#…...

【AI面试准备】AI误判案例知识库优化方案

面试题&#xff1a;建立内部知识库&#xff1a;收集AI误判案例训练领域专属模型。 在回答关于“建立内部知识库收集AI误判案例训练领域专属模型”的面试问题时&#xff0c;建议从以下结构化框架展开&#xff0c;既能体现专业性&#xff0c;又能展现解决问题的系统性和实际落地…...

从零开始讲DDR(8)——AXI 接口MIG 使用(1)

一、前言 在之前的系列文章中&#xff0c;我们已经讨论过了MIG ip的接口内容&#xff0c;配置方式和modelsim独立仿真相关的内容&#xff0c;因此&#xff0c;本文对于之前已经讨论过的相关内容只做简单描述&#xff0c;着重介绍AXI 接口MIG使用上与普通ui接口的不同之处。感兴…...

字符和编码(python)

位数&#xff1a;英文字符使用 1 个字节表示&#xff0c;中文字符通常使用 3 个字节。示例&#xff1a;汉字 “汉” 的 UTF-8 编码是 \xE6\xB1\x89。优点&#xff1a;兼容 ASCII&#xff0c;广泛用于网络传输和文件存储。 Python 中的字符串类型 在 Python 中&#xff0c;字…...

【STM32】定时器输入捕获

STM32 定时器输入捕获功能笔记 一、什么是输入捕获&#xff08;Input Capture&#xff09; 输入捕获是利用定时器的输入通道&#xff0c;在检测到信号电平变化&#xff08;如上升沿或下降沿&#xff09;时&#xff0c;立即将当前计数器的值捕获并保存到捕获寄存器&#xff08…...

spring-ai集成langfuse

1、pom文件 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.…...

SALOME源码分析: ParaVis

本文分析SALOME中ParaVis模块。 注1&#xff1a;限于研究水平&#xff0c;分析难免不当&#xff0c;欢迎批评指正。注2&#xff1a;文章内容会不定期更新。 一、核心组件 二、关键流程 三、FAQs 网络资料 SALOME Scientific visualisationPARAVIS Module - Architecture …...

Ubuntu 安装 MySQL8

在 Ubuntu 下安装 MySQL 服务&#xff0c;推荐使用 apt install 官方的 APT 仓库安装方式&#xff0c;这种方式最安全、最稳定、能自动处理依赖关系&#xff0c;也支持后续升级。不推荐在官网手动下载 .deb 包的方式。 配置 Ubuntu 服务器 1. 确认 Ubuntu 系统版本 使用如下命…...

MATLAB图像加密案例

下面是一个使用 MATLAB 编写的简单图像块置乱加密/解密程序,主要利用了函数来组织代码。 这个程序通过将图像分割成小块,然后根据一个密钥(用于随机数生成器种子)打乱这些块的顺序来实现加密。解密过程则使用相同的密钥恢复原始块顺序。 核心思想: 分块: 将图像划分为 …...

同构字符串(简单)

新建两个哈希表&#xff0c;构建s到t中的字母的映射以及t到s中的字母的映射。 class Solution {public boolean isIsomorphic(String s, String t) {Map<Character,Character> s2tnew HashMap<Character,Character>();Map<Character,Character> t2snew Hash…...

红米Note9 4G版拆开后盖操作细节

先把sim卡槽整个拔出 然后如下图做试&#xff0c;4个箭头的位置塞塑料片或者指甲插入&#xff0c;弄开&#xff0c;然后从图中右侧抠开&#xff08;左侧不行&#xff0c;有排线连着后面手机主板&#xff09; 如果不按照这种办法&#xff0c;会把后盖很多地方抠烂...

Qt通过QXlsx库文件写入到excl文件,读取excl文件

第一&#xff1a;下载QXlsx库文件 https://download.csdn.net/download/qq_32663053/90739425 第二&#xff1a;在Qt项目中引入QXlsx库&#xff0c;需要把QXlsx库文件放在项目文件夹下 第三&#xff1a;将tableview中的数据存入到excl文件 代码&#xff1a; void MainWindow…...

ESP32 在Platform Arduino平台驱动外部PSAM,进行内存管理

一&#xff0c;基本介绍 本文中主要介绍ESP32、ESP32S3系列单片机&#xff0c;基于Vscode Platform Arduino和Arduino框架下如何使用外部PSAM&#xff0c;以及必要的API调用函数进行内存分配和管理。 使用前提是开发板有外部PSRAM。 二&#xff0c;平台配置 2.1 Arduino平台 …...

【AI论文】WebThinker:赋予大型推理模型深度研究能力

摘要&#xff1a;大型推理模型&#xff08;LRMs&#xff09;&#xff0c;如OpenAI-o1和DeepSeek-R1&#xff0c;展示了令人印象深刻的长期推理能力。 然而&#xff0c;他们对静态内部知识的依赖限制了他们在复杂的知识密集型任务上的表现&#xff0c;并阻碍了他们生成需要综合各…...

Python爬虫基础总结

Python爬虫基础总结 一、爬虫概述 1.1 什么是爬虫 网络爬虫&#xff08;Web Crawler&#xff09;是一种自动浏览万维网的程序或脚本&#xff0c;它按照一定的规则&#xff0c;自动抓取互联网上的信息并存储到本地数据库中。 1.2 爬虫工作流程 ​​URL管理器​​&#xff1…...

如何构建跨平台可复用的业务逻辑层(Web、App、小程序)

从传统的Web应用到移动端的App&#xff0c;再到近年来快速崛起的小程序&#xff0c;用户的触点变得异常分散且多样化。这种多端并存的现状一方面为企业提供了更广阔的市场机会&#xff0c;另一方面也对开发团队提出了更高的要求&#xff1a;如何在不同平台间实现高效开发、降低…...

本地大模型编程实战(32)用websocket显示大模型的流式输出

在与 LLM(大语言模型) 对话时&#xff0c;如果每次都等 LLM 处理完毕再返回给客户端&#xff0c;会显得比较卡顿&#xff0c;不友好。如何能够像主流的AI平台那样&#xff1a;可以一点一点吐出字符呢&#xff1f; 本文将模仿后端流式输出文字&#xff0c;前端一块一块的显示文字…...

MySQL数据库上篇

#作者&#xff1a;允砸儿 #日期&#xff1a;乙巳青蛇年 四月初五 笔者好久没有更新。今天来写一下MySQL数据库的内容还是老样子分为上中下三篇来写&#xff0c;话不多说咱们直接进入正题。 什么是数据库 数据库是统一管理的、长期储存在计算机内非仍、有组织的相关数据集合…...

Webug4.0靶场通关笔记13- 第22关越权修改密码

目录 第22关 越权修改密码 1.打开靶场 2.源码分析 3.越权修改密码 &#xff08;1&#xff09;获取渗透账号 &#xff08;2&#xff09;越权修改aaaaa账号的密码 &#xff08;3&#xff09;修改aaaaa用户密码渗透成功 &#xff08;4&#xff09;水平越权修改mooyuan账号…...