Pytorch|YOLO
- 🍨 本文为🔗365天深度学习训练营中的学习记录博客
- 🍖 原作者:K同学啊
一、 前期准备
1. 设置GPU
如果设备上支持GPU就使用GPU,否则使用CPU
import torch
import torch.nn as nn
import torchvision.transforms as transforms
import torchvision
from torchvision import transforms, datasets
import os,PIL,pathlib,warningswarnings.filterwarnings("ignore") #忽略警告信息device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
device
device(type='cuda')
2. 导入数据
import pathlibdata_dir = "./data/weather_photos/"
data_dir = pathlib.Path(data_dir)# 获取所有子目录路径
data_paths = list(data_dir.glob('*'))# 使用 path.parts 获取正确的目录名称
classeNames = [path.parts[-1] for path in data_paths]
print(classeNames)
['cloudy', 'rain', 'shine', 'sunrise']
# 关于transforms.Compose的更多介绍可以参考:https://blog.csdn.net/qq_38251616/article/details/124878863
train_transforms = transforms.Compose([transforms.Resize([224, 224]), # 将输入图片resize成统一尺寸# transforms.RandomHorizontalFlip(), # 随机水平翻转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] 从数据集中随机抽样计算得到的。
])test_transform = 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("./data/weather_photos/",transform=train_transforms)
total_data
Dataset ImageFolderNumber of datapoints: 1125Root location: ./data/weather_photos/StandardTransform Transform: Compose(Resize(size=[224, 224], interpolation=bilinear, max_size=None, antialias=True)ToTensor()Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]))
total_data.class_to_idx
{'cloudy': 0, 'rain': 1, 'shine': 2, 'sunrise': 3}
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])
train_dataset, test_dataset
(<torch.utils.data.dataset.Subset at 0x19600429450>,
<torch.utils.data.dataset.Subset at 0x196004297e0>)
batch_size = 4train_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)
for X, y in test_dl:print("Shape of X [N, C, H, W]: ", X.shape)print("Shape of y: ", y.shape, y.dtype)break
Shape of X [N, C, H, W]: torch.Size([4, 3, 224, 224])
Shape of y: torch.Size([4]) torch.int64
二、搭建包含C3模块的模型
📌K同学啊提示:是否可以尝试通过增加/调整C3模块与Conv模块来提高准确率?
1. 搭建模型
import torch.nn.functional as Fdef autopad(k, p=None): # kernel, padding# Pad to 'same'if p is None:p = k // 2 if isinstance(k, int) else [x // 2 for x in k] # auto-padreturn pclass Conv(nn.Module):# Standard convolutiondef __init__(self, c1, c2, k=1, s=1, p=None, g=1, act=True): # ch_in, ch_out, kernel, stride, padding, groupssuper().__init__()self.conv = nn.Conv2d(c1, c2, k, s, autopad(k, p), groups=g, bias=False)self.bn = nn.BatchNorm2d(c2)self.act = nn.SiLU() if act is True else (act if isinstance(act, nn.Module) else nn.Identity())def forward(self, x):return self.act(self.bn(self.conv(x)))class Bottleneck(nn.Module):# Standard bottleneckdef __init__(self, c1, c2, shortcut=True, g=1, e=0.5): # ch_in, ch_out, shortcut, groups, expansionsuper().__init__()c_ = int(c2 * e) # hidden channelsself.cv1 = Conv(c1, c_, 1, 1)self.cv2 = Conv(c_, c2, 3, 1, g=g)self.add = shortcut and c1 == c2def forward(self, x):return x + self.cv2(self.cv1(x)) if self.add else self.cv2(self.cv1(x))class C3(nn.Module):# CSP Bottleneck with 3 convolutionsdef __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5): # ch_in, ch_out, number, shortcut, groups, expansionsuper().__init__()c_ = int(c2 * e) # hidden channelsself.cv1 = Conv(c1, c_, 1, 1)self.cv2 = Conv(c1, c_, 1, 1)self.cv3 = Conv(2 * c_, c2, 1) # act=FReLU(c2)self.m = nn.Sequential(*(Bottleneck(c_, c_, shortcut, g, e=1.0) for _ in range(n)))def forward(self, x):return self.cv3(torch.cat((self.m(self.cv1(x)), self.cv2(x)), dim=1))class model_K(nn.Module):def __init__(self):super(model_K, self).__init__()# 卷积模块self.Conv = Conv(3, 32, 3, 2) # C3模块1self.C3_1 = C3(32, 64, 3, 2)# 全连接网络层,用于分类self.classifier = nn.Sequential(nn.Linear(in_features=802816, out_features=100),nn.ReLU(),nn.Linear(in_features=100, out_features=4))def forward(self, x):x = self.Conv(x)x = self.C3_1(x)x = torch.flatten(x, start_dim=1)x = self.classifier(x)return xdevice = "cuda" if torch.cuda.is_available() else "cpu"
print("Using {} device".format(device))model = model_K().to(device)
model
Using cuda device
model_K(
(Conv): Conv(
(conv): Conv2d(3, 32, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
(bn): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act): SiLU()
)
(C3_1): C3(
(cv1): Conv(
(conv): Conv2d(32, 32, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act): SiLU()
)
(cv2): Conv(
(conv): Conv2d(32, 32, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act): SiLU()
)
(cv3): Conv(
(conv): Conv2d(64, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act): SiLU()
)
(m): Sequential(
(0): Bottleneck(
(cv1): Conv(
(conv): Conv2d(32, 32, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act): SiLU()
)
(cv2): Conv(
(conv): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act): SiLU()
)
)
(1): Bottleneck(
(cv1): Conv(
(conv): Conv2d(32, 32, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act): SiLU()
)
(cv2): Conv(
(conv): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act): SiLU()
)
)
(2): Bottleneck(
(cv1): Conv(
(conv): Conv2d(32, 32, kernel_size=(1, 1), stride=(1, 1), bias=False)
(bn): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act): SiLU()
)
(cv2): Conv(
(conv): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(act): SiLU()
)
)
)
)
(classifier): Sequential(
(0): Linear(in_features=802816, out_features=100, bias=True)
(1): ReLU()
(2): Linear(in_features=100, out_features=4, bias=True)
)
)
2. 查看模型详情
# 统计模型参数量以及其他指标
import torchsummary as summary
summary.summary(model, (3, 224, 224))
----------------------------------------------------------------Layer (type) Output Shape Param #
================================================================Conv2d-1 [-1, 32, 112, 112] 864BatchNorm2d-2 [-1, 32, 112, 112] 64SiLU-3 [-1, 32, 112, 112] 0Conv-4 [-1, 32, 112, 112] 0Conv2d-5 [-1, 32, 112, 112] 1,024BatchNorm2d-6 [-1, 32, 112, 112] 64SiLU-7 [-1, 32, 112, 112] 0Conv-8 [-1, 32, 112, 112] 0Conv2d-9 [-1, 32, 112, 112] 1,024BatchNorm2d-10 [-1, 32, 112, 112] 64SiLU-11 [-1, 32, 112, 112] 0Conv-12 [-1, 32, 112, 112] 0Conv2d-13 [-1, 32, 112, 112] 9,216BatchNorm2d-14 [-1, 32, 112, 112] 64SiLU-15 [-1, 32, 112, 112] 0Conv-16 [-1, 32, 112, 112] 0Bottleneck-17 [-1, 32, 112, 112] 0Conv2d-18 [-1, 32, 112, 112] 1,024BatchNorm2d-19 [-1, 32, 112, 112] 64SiLU-20 [-1, 32, 112, 112] 0Conv-21 [-1, 32, 112, 112] 0Conv2d-22 [-1, 32, 112, 112] 9,216BatchNorm2d-23 [-1, 32, 112, 112] 64SiLU-24 [-1, 32, 112, 112] 0Conv-25 [-1, 32, 112, 112] 0Bottleneck-26 [-1, 32, 112, 112] 0Conv2d-27 [-1, 32, 112, 112] 1,024BatchNorm2d-28 [-1, 32, 112, 112] 64SiLU-29 [-1, 32, 112, 112] 0Conv-30 [-1, 32, 112, 112] 0Conv2d-31 [-1, 32, 112, 112] 9,216BatchNorm2d-32 [-1, 32, 112, 112] 64SiLU-33 [-1, 32, 112, 112] 0Conv-34 [-1, 32, 112, 112] 0Bottleneck-35 [-1, 32, 112, 112] 0Conv2d-36 [-1, 32, 112, 112] 1,024BatchNorm2d-37 [-1, 32, 112, 112] 64SiLU-38 [-1, 32, 112, 112] 0Conv-39 [-1, 32, 112, 112] 0Conv2d-40 [-1, 64, 112, 112] 4,096BatchNorm2d-41 [-1, 64, 112, 112] 128SiLU-42 [-1, 64, 112, 112] 0Conv-43 [-1, 64, 112, 112] 0C3-44 [-1, 64, 112, 112] 0Linear-45 [-1, 100] 80,281,700ReLU-46 [-1, 100] 0Linear-47 [-1, 4] 404
================================================================
Total params: 80,320,536
Trainable params: 80,320,536
Non-trainable params: 0
----------------------------------------------------------------
Input size (MB): 0.57
Forward/backward pass size (MB): 150.06
Params size (MB): 306.40
Estimated Total Size (MB): 457.04
----------------------------------------------------------------
三、 训练模型
1. 编写训练函数
# 训练循环
def train(dataloader, model, loss_fn, optimizer):size = len(dataloader.dataset) # 训练集的大小num_batches = len(dataloader) # 批次数目, (size/batch_size,向上取整)train_loss, train_acc = 0, 0 # 初始化训练损失和正确率for X, y in dataloader: # 获取图片及其标签X, y = X.to(device), y.to(device)# 计算预测误差pred = model(X) # 网络输出loss = loss_fn(pred, y) # 计算网络输出和真实值之间的差距,targets为真实值,计算二者差值即为损失# 反向传播optimizer.zero_grad() # grad属性归零loss.backward() # 反向传播optimizer.step() # 每一步自动更新# 记录acc与losstrain_acc += (pred.argmax(1) == y).type(torch.float).sum().item()train_loss += loss.item()train_acc /= sizetrain_loss /= num_batchesreturn train_acc, train_loss
2. 编写测试函数
测试函数和训练函数大致相同,但是由于不进行梯度下降对网络权重进行更新,所以不需要传入优化器
def test (dataloader, model, loss_fn):size = len(dataloader.dataset) # 测试集的大小num_batches = len(dataloader) # 批次数目, (size/batch_size,向上取整)test_loss, test_acc = 0, 0# 当不进行训练时,停止梯度更新,节省计算内存消耗with torch.no_grad():for imgs, target in dataloader:imgs, target = imgs.to(device), target.to(device)# 计算losstarget_pred = model(imgs)loss = loss_fn(target_pred, target)test_loss += loss.item()test_acc += (target_pred.argmax(1) == target).type(torch.float).sum().item()test_acc /= sizetest_loss /= num_batchesreturn test_acc, test_loss
3. 正式训练
model.train()
、model.eval()
训练营往期文章中有详细的介绍。
📌如果将优化器换成 SGD 会发生什么呢?请自行探索接下来发生的诡异事件的原因
import copyoptimizer = torch.optim.Adam(model.parameters(), lr= 1e-4)
loss_fn = nn.CrossEntropyLoss() # 创建损失函数epochs = 20train_loss = []
train_acc = []
test_loss = []
test_acc = []best_acc = 0 # 设置一个最佳准确率,作为最佳模型的判别指标for epoch in range(epochs):model.train()epoch_train_acc, epoch_train_loss = train(train_dl, model, loss_fn, optimizer)model.eval()epoch_test_acc, epoch_test_loss = test(test_dl, model, loss_fn)# 保存最佳模型到 best_modelif epoch_test_acc > best_acc:best_acc = epoch_test_accbest_model = copy.deepcopy(model)train_acc.append(epoch_train_acc)train_loss.append(epoch_train_loss)test_acc.append(epoch_test_acc)test_loss.append(epoch_test_loss)# 获取当前的学习率lr = optimizer.state_dict()['param_groups'][0]['lr']template = ('Epoch:{:2d}, Train_acc:{:.1f}%, Train_loss:{:.3f}, Test_acc:{:.1f}%, Test_loss:{:.3f}, Lr:{:.2E}')print(template.format(epoch+1, epoch_train_acc*100, epoch_train_loss, epoch_test_acc*100, epoch_test_loss, lr))# 保存最佳模型到文件中
PATH = './best_model.pth' # 保存的参数文件名
torch.save(model.state_dict(), PATH)print('Done')
四、 结果可视化
1. Loss与Accuracy图
import matplotlib.pyplot as plt
#隐藏警告
import warnings
warnings.filterwarnings("ignore") #忽略警告信息
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
plt.rcParams['figure.dpi'] = 100 #分辨率epochs_range = range(epochs)plt.figure(figsize=(12, 3))
plt.subplot(1, 2, 1)plt.plot(epochs_range, train_acc, label='Training Accuracy')
plt.plot(epochs_range, test_acc, label='Test Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')plt.subplot(1, 2, 2)
plt.plot(epochs_range, train_loss, label='Training Loss')
plt.plot(epochs_range, test_loss, label='Test Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()
best_model.eval()
epoch_test_acc, epoch_test_loss = test(test_dl, best_model, loss_fn)
epoch_test_acc, epoch_test_loss
(0.9333333333333333, 0.31915266352798577)
- 前期准备:首先设置 GPU,如果设备支持则使用 GPU,否则使用 CPU。然后导入数据,对数据进行预处理,包括数据增强和归一化等操作。最后划分数据集,将数据集分为训练集和测试集,并创建数据加载器。
- 搭建模型:搭建了一个包含 C3 模块的自定义模型,模型由卷积层、C3 模块和全连接层组成。其中 C3 模块由多个瓶颈层组成,可以提高模型的准确率。
- 训练模型:编写了训练函数和测试函数,分别用于训练和测试模型。在训练过程中,使用 Adam 优化器和交叉熵损失函数,对模型进行了 20 个 epoch 的训练,并保存了最佳模型。
- 结果可视化:对训练和测试结果进行了可视化,包括准确率和损失函数的变化曲线。最后,使用最佳模型对测试集进行测试,得到了最终的准确率和损失函数值
相关文章:

Pytorch|YOLO
🍨 本文为🔗365天深度学习训练营中的学习记录博客🍖 原作者:K同学啊 一、 前期准备 1. 设置GPU 如果设备上支持GPU就使用GPU,否则使用CPU import torch import torch.nn as nn import torchvision.transforms as transforms im…...
云计算与物联网技术的融合应用(在工业、农业、家居、医疗、环境、城市等整理较全)
摘要 为生产领域带来更加全面和深入的变革。通过云计算平台对物联网数据进行处理和分析,企业可以实现对生产过程的更加精细化的管理和控制。 1. 智能生产调度 通过云计算和物联网技术的融合应用,企业可以实现对生产线上各个环节的实时监控和数据分析。…...

基于python+Django+mysql鲜花水果销售商城网站系统设计与实现
博主介绍:黄菊华老师《Vue.js入门与商城开发实战》《微信小程序商城开发》图书作者,CSDN博客专家,在线教育专家,CSDN钻石讲师;专注大学生毕业设计教育、辅导。 所有项目都配有从入门到精通的基础知识视频课程ÿ…...
Golang:报错no required module provides package github.com/xx的解决方法
报错 问题重现可能的原因及解决方法1. 未初始化 Go 模块解决方法: 2. 没有添加依赖解决方法: 3. 网络问题解决方法: 4. 依赖版本问题解决方法: 5. 包未发布或路径拼写错误解决方法: 6. go mod tidy 未运行解决方法&…...

数据结构与算法(2):顺序表与链表
1.前言 哈喽大家好喔,今天博主继续进行数据结构的分享与学习,今天的主要内容是顺序表与链表,是最简单但又相当重要的数据结构,为以后的学习有重要的铺垫,希望大家一起交流学习,互相进步,让我们…...
华为OD机试E卷 --过滤组合字符串--24年OD统一考试(Java JS Python C C++)
文章目录 题目描述输入描述输出描述用例题目解析JS算法源码Java算法源码python算法源码c算法源码c++算法源码题目描述 数字 0、1、2、3、4、5、6、7、8、9 分别关联 a~z 26 个英文字母。 0 关联“a”"b”"c1 关联“d”"e”"f2 关联“g"“h”“i”3 关…...

QT跨平台应用程序开发框架(3)—— 信号和槽
目录 一,基本概念 二,connect函数使用 2.1 connect 2.2 Qt内置信号和槽 2.3 一些细节 三,自定义信号和槽 3.1 自定义槽函数 3.2 自定义信号 3.3 带参数的信号槽 四,信号和槽的意义 五,信号和槽断开连接 六&…...

从 0 开始实现一个 SpringBoot + Vue 项目
从 0 开始实现一个 SpringBoot Vue 项目 从 0 开始实现一个 SpringBoot Vue 项目 软件和工具创建 SpringBoot 后端项目创建 MySQL 数据库配置文件实现增删改查接口 Model 层mapper 层service 层controller 层测试 实现项目功能接口 代码测试 创建 Vue 前端 安装 Node.js配置…...

【无标题】微调是迁移学习吗?
是的,微调(Fine-Tuning)可以被视为一种迁移学习(Transfer Learning)的形式。迁移学习是一种机器学习方法,其核心思想是利用在一个任务上学到的知识来改进另一个相关任务的性能。微调正是通过在预训练模型的…...

虚幻基础1:hello world
能帮到你的话,就给个赞吧 😘 文章目录 hello world创建项目创建关卡创建蓝图将蓝图插入关卡中运行 hello world 本文引擎为5.5.1 创建项目 如图 创建后如图。 创建关卡 如图 创建蓝图 如图 选择actor 双击进入蓝图节点 选择事件图表 创…...
C链表的一些基础知识
一、链表的基本概念 链表是一种常见的线性数据结构,它由一系列节点组成,每个节点包含数据部分和指向下一个节点的指针(单链表情况)。通过指针将各个节点连接起来,与数组不同,链表在内存中的存储不是连续的…...

JDK长期支持版本(LTS)
https://blogs.oracle.com/java/post/the-arrival-of-java-23 jdk长期支持版本(LTS):JDK 8、11、17、21:...
【超详细】Python datetime(当前日期、时间戳转换、前一天日期等)【附:时区原理详解】
文章目录 相关文献当前时间前一天日期、后一天日期东八区(北京)时间时间戳转换datetime -> strstr -> datetimedatetime -> timestamp(时间戳)timestamp -> datetime 获取日期中的年、季度、月、周、日、小时、分、秒等时区原理时区问题复杂…...

【Excel】【VBA】双列排序:坐标从Y从大到小排列之后相同Y坐标的行再对X从小到大排列
Excel VBA 双列排序 功能概述 这段VBA代码实现了Excel中的双列排序功能,具体是: 跳过前3行表头先按C列数据从大到小排序在C列值相同的情况下,按B列从大到小排序排序时保持整行数据的完整性 流程图 #mermaid-svg-XJERemQluZlM4K8l {font-fa…...

为什么相关性不是因果关系?人工智能中的因果推理探秘
目录 一、背景 (一)聚焦当下人工智能 (二)基于关联框架的人工智能 (三)基于因果框架的人工智能 二、因果推理的基本理论 (一)因果推理基本范式:因果模型࿰…...
Nginx调优
Nginx 是一个高性能的反向代理服务器和负载均衡器,在处理大量并发请求时表现出色。但是,随着系统负载的增加,Nginx 的性能可能受到多方面的影响,因此进行适当的调优至关重要。以下是 Nginx 调优的几个方向和关键点: 1…...
联德胜w801开发板(四)实现腾讯云mqtt的订阅和发布
一、开发准备 在设备开发这里我们就能看到物模型的topic,跟之前用stm32esp8266一样 附上之前的链接: STM32ESP8266连接腾讯IOT上传数据(四)_stm32通过esp8266上传数据到云平台-CSDN博客https://blog.csdn.net/Try1harder/article/details/134914027?…...

LLM框架对比选择:MaxKB、Dify、FastGPT、RagFlow【RAG+AI工作流+Agent]
1.MaxKB MaxKB Max Knowledge Base,是一款基于 LLM 大语言模型的开源知识库问答系统,旨在成为企业的最强大脑。它能够帮助企业高效地管理知识,并提供智能问答功能。想象一下,你有一个虚拟助手,可以回答各种关于公司内…...

C语言内存之旅:从静态到动态的跨越
大家好,这里是小编的博客频道 小编的博客:就爱学编程 很高兴在CSDN这个大家庭与大家相识,希望能在这里与大家共同进步,共同收获更好的自己!!! 本文目录 引言正文一 动态内存管理的必要性二 动态…...
研1如何准备才能找到大厂实习?
研1如何准备才能找到大厂实习? 写在前面 2024已经走向尾声,迎来了我的2025,这一年我有许多难忘的回忆和经验想要分享给大家,希望对您能有所帮助和启发,希望准备找工作的同学可以少走一些弯路。 我深知目前就业压力大…...

PicSharp(图片压缩工具) v1.1.6
PicSharp 一个简单、高效、灵活的跨平台桌面图像压缩应用程序。软件基于Rust实现,高性能低资源,能快速扫描文件或目录,批处理图像。软件还具备组合压缩策略,TinyPNG提供最佳压缩比,但需要互联网连接,对大量…...
LangChain面试内容整理-知识点1:LangChain架构与核心理念
LangChain 是一个用于构建基于大型语言模型(LLM)的应用的框架,其架构采用模块化设计,核心理念是将语言模型与外部工具、数据源相结合,以实现复杂任务的分解与执行medium.com。整个框架可以理解为一系列可组合的组件,包括链(Chain)、智能体(Agent)、工具(Tool)和LLM…...

华为手机开机卡在Huawei界面不动怎么办?
遇到华为手机卡在启动界面(如HUAWEI Logo界面)的情况,可依次尝试以下解决方案,按操作复杂度和风险由低到高排序: 🔧 一、强制重启(优先尝试) 1.通用方法 长按 电源键 音量下键…...

SpringAI(GA):Nacos2下的分布式MCP
原文链接地址:SpringAI(GA):Nacos2下的分布式MCP 教程说明 说明:本教程将采用2025年5月20日正式的GA版,给出如下内容 核心功能模块的快速上手教程核心功能模块的源码级解读Spring ai alibaba增强的快速上手教程 源码级解读 版…...
kubeadm安装k8s
1、环境准备 1.1、升级系统内核 参考另一篇文章:https://blog.csdn.net/u012533920/article/details/148457715?spm1011.2415.3001.5331 1.2、设置Hostname cat <<EOF > /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhos…...

鸿蒙PC,有什么缺点?
点击上方关注 “终端研发部” 设为“星标”,和你一起掌握更多数据库知识 价格太高,二是部分管理员权限首先,三对于开发者不太友好举个例子:VSCode的兼容性对程序员至关重要。若能支持VSCode,这台电脑将成为大多数开发者…...

C# 中替换多层级数据的 Id 和 ParentId,保持主从或父子关系不变
在C#中替换多层级数据的Id和ParentId,同时保持父子关系不变,可以通过以下步骤实现: 创建旧Id到新Id的映射:遍历所有节点,为每个旧Id生成唯一的新Id,并存储在字典中。 替换节点的Id和ParentId:…...

使用矩阵乘法+线段树解决区间历史和问题的一种通用解法
文章目录 前言P8868 [NOIP2022] 比赛CF1824DP9990/2020 ICPC EcFinal G 前言 一般解决普通的区间历史和,只需要定义辅助 c h s − t ⋅ a chs-t\cdot a chs−t⋅a, h s hs hs是历史和, a a a是区间和, t t t是时间戳,…...
AI推理服务的高可用架构设计
AI推理服务的高可用架构设计 在传统业务系统中,高可用架构主要关注服务冗余、数据库容灾、限流熔断等通用能力。而在AI系统中,尤其是大模型推理服务场景下,高可用架构面临更加复杂的挑战,如推理延迟敏感性、GPU资源稀缺性、模型版本切换频繁等问题。本节将专门探讨如何构建…...

HA: Wordy靶场
HA: Wordy 来自 <HA: Wordy ~ VulnHub> 1,将两台虚拟机网络连接都改为NAT模式 2,攻击机上做namp局域网扫描发现靶机 nmap -sn 192.168.23.0/24 那么攻击机IP为192.168.23.128,靶场IP192.168.23.130 3,对靶机进行端口服务探…...