PyTorch图像建模(图像识别、分割和分类案例)
文章目录
- 图像分类技术:改变生活的智能之眼
- 图形识别技术
- 图像识别过程
- 图像预处理
- 图像特征提取
- 图像分割技术
- 练习案例:图像分类
- 项目源码地址
- 实现代码(简化版)
- 训练结果(简化版)
- 实现代码(优化版)
- 训练结果(优化版)
- 存在的问题
图像分类技术:改变生活的智能之眼
-
图像分类技术已经深入我们的日常生活,应用场景越来越广泛。比如,手机相册能自动识别人物照片,社交平台可以精准识别照片中的好友和物体,自动驾驶汽车能实时检测道路状况……这些应用都表明,图像分类技术正成为我们生活中不可或缺的一部分。
-
传统方法的局限:早期的图像分类技术主要依赖数字图像处理和机器学习方法。研究人员需要手动提取图像特征(如颜色、纹理等),再根据这些特征对图像进行分类。但这种方法有个明显缺点:适应性差。如果图像受到噪声干扰或部分残缺,分类效果就会大打折扣。
-
进入大数据时代后,数据量爆炸式增长,传统算法的计算压力越来越大。这时,人工神经网络(ANN)成为了一种解决方案。然而,传统ANN也存在问题: 计算成本高:采用全连接结构,参数数量庞大,扩展性差; 忽略空间信息:未考虑像素之间的位置关系,而这对图像分析至关重要;层数限制:网络层数越多,表达能力越强,但误差反向传播难以超过3层,限制了性能提升。
-
卷积神经网络(CNN)的突破:CNN的提出完美解决了上述问题,迅速成为计算机视觉的核心技术。它的设计灵感来自图像的特性:相邻像素之间具有强相关性。CNN通过局部连接和权值共享,大幅减少了无效计算,同时充分利用了像素的空间关系和梯度信息。
- 简单来说,CNN就像一位“智能画家”,不仅能捕捉图像的细节,还能理解这些细节之间的联系,从而让图像分类更高效、更准确。正是这种优势,让它成为当今人工智能领域的重要基石。
图形识别技术
- 图像识别指利用信息处理与计算机技术,采用数学方法,对图像进行处理、分析和理解的过程。图像识别技术的使用领域广泛,如指纹识别、虹膜识别、手写汉字识别、交通标志识别、手势识别、人脸识别、机器人视觉等,分类识别的事物种类丰富,被识别对象的内容复杂。例如,在交通管理系统中,通过使用车牌的自动识别来记录车辆的违章行为;在医学图像中,根据细胞的形状和颜色等分析是否发生病变;通过植物的颜色和形态长势判断何时需要浇水、施肥;通过气象观测的数据或利用卫星照片来进行天气预报等。
图像识别过程
- 图像识别过程大致分为两个阶段:样本训练阶段和图像识别阶段。
- 样本训练阶段:对大量样本进行预处理、提取图像特征、进行模式分类,获取一个样本图像特征库。
- 图像识别阶段:对输入图形进行预处理、图像分析、图形分割、提取关注部分的图像特征、利用模式识别方法对特征和图像特征库中的特征进行相关处理。当图像匹配失败时,将其特征作为新的模式分类并入图像特征库。
图像预处理
- 图像预处理服务于后续的图像识别服务。预处理过程包括灰度处理、归一化处理、低通滤波处理、均值滤波处理和中值滤波处理、高通滤波处理、边缘检测、边界检测、区域连接和门限等技术。
- 彩色图像的灰度处理:方便分析图形内容。
- 直方图归一化、低通滤波、均值滤波和中值滤波处理:可以减少图像在成像过程中收到的噪声污染。
- 高通滤波处理:突出图像的细节特征。
- 边缘检测、边界检测、区域连接和门限等技术:方便能够快速找到关注的图像部分。
图像特征提取
- 图像特征提取能保证图像的大小、位移及旋转的不变性,以提取到唯一标识图像特性的特征来为图像识别服务。
- 图像特征提取实际上是图像表示问题,它的目的是减轻图像在识别过程中的负担。因为原始图像的数据维数非常高,通过特征提取给数据降维,从而提高识别效率和识别率,为节省资源、构造和设计特征分类器带来益处。
图像分割技术
- 图像分类就是将图像分成若干个特定的、具有独特性质的区域并提取感兴趣的目标的技术和过程。主要的图形分割技术主要分为以下几类:基于阈值的分割方法、基于区域的分割方法、基于边缘的分割方法以及基于特定理论的分割方法等。
- 基于阈值的图像分割技术:最常用的并行分割技术,基于阈值的分割方法进行输入图像到输出图像的变换。关键点是确定阈值,确定阈值后将阈值与像素点的灰度值并行地逐个进行比较,分割的结果直接给出图像区域。
- 基于区域的分割技术:典型的串行区域分割技术,主要包括区域生长和分割合并两种方法。区域生长是从某个或者某些像素点出发,最后得到整个区域,进行实现目标提取;分割合并差不多是区域生长的逆过程,从整个图像出发,不断分割得到各个子区域,然后把前景区域合并,实现目标提取。
- 基于边缘的分割技术:检测灰度级或者结果有突变的地方,表明一个区域的终结(另一个区域的开始)。不同图像的灰度不同,边界处一般有明显的边缘,利用此特征可以分割图像。
- 基于特定理论的分割技术:如模糊集理论具有描述试图不确定性的能力,适合用于图像分割问题。模糊分割技术在图像分割方面的应用,一个显著特点就是它能和现有的许多图像分割方法结合,形成一系列的集成模糊分割技术,如模糊聚、模糊阈值、模糊边缘检测技术。
练习案例:图像分类
- 数据集使用CIFAR10,数据集一共包含10个类别的RGB彩色图片,10个分类分别为飞机、汽车、鸟、猫、鹿、狗、蛙、马、船、卡车。图片尺寸为32×32,数据集中一共有50000正训练图片和10000张测试图片。
项目源码地址
- image_classification_and_recognition
实现代码(简化版)
import matplotlib.pyplot as plt
import numpy as np
import torch
import torch.nn.functional as f
import torchvision
from torchvision.transforms import transforms# 0 torchvision的数据集是基于PILImage,数值范围[0,1]需要转化范围为[-1,1]的张量
transform = transforms.Compose([transforms.ToTensor(), # 将数据转化为张量# 归一化处理 均值0.5 标准差0.5transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
])
# 1 导入训练集和测试数据集 并设置数据加载参数 定义数据集中的类别名称
"""
torchvision.datasets.CIFAR10 定义CIFAR-10数据集
root='./data' 指定数据集的根目录
train=True 创建训练集
download=True 自动下载数据集 如果数据集不存在报错
transform=transform 应用数据预处理变换
"""
train_dataset = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=transform)
"""
torch.utils.data.DataLoader 定义数据加载器 加载训练数据
train_dataset 加载的数据集对象 训练数据集
batch_size=4 每个批次包含的样本数量
shuffle=False 不在每个 epoch 开始时打乱数据顺序
num_workers=4 使用 4 个子进程加载数据(加快数据读取速度)
"""
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=4, shuffle=False, num_workers=4)"""
torchvision.datasets.CIFAR10 定义CIFAR-10数据集
root='./data' 指定数据集的根目录
train=False 创建测试集
download=True 自动下载数据集 如果数据集不存在报错
transform=transform 应用数据预处理变换
"""
test_dataset = torchvision.datasets.CIFAR10(root='./data', train=False, download=True, transform=transform)
"""
torch.utils.data.DataLoader 定义数据加载器 加载测试数据
train_dataset 加载的数据集对象 训练数据集
batch_size=4 每个批次包含的样本数量
shuffle=True 不在每个 epoch 开始时打乱数据顺序
num_workers=4 使用 4 个子进程加载数据(加快数据读取速度)
"""
test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=4, shuffle=True, num_workers=4)
# 定义类别名
classes = ('plane', 'car', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck')# 2 搭建网络模型
class Net(torch.nn.Module):def __init__(self):super(Net, self).__init__()# 定义卷积层self.conv1 = torch.nn.Conv2d(3, 6, 5)self.pool = torch.nn.MaxPool2d(2, 2)self.conv2 = torch.nn.Conv2d(6, 16, 5)# 定义全连接层self.fc1 = torch.nn.Linear(16 * 5 * 5, 120)self.fc2 = torch.nn.Linear(120, 84)self.fc3 = torch.nn.Linear(84, 10)def forward(self, x):x = self.pool(f.relu(self.conv1(x)))x = self.pool(f.relu(self.conv2(x)))x = x.view(-1, 16 * 5 * 5)x = f.relu(self.fc1(x))x = f.relu(self.fc2(x))x = self.fc3(x)return x"""
An attempt has been made to start a new process before thecurrent process has finished its bootstrapping phase.This probably means that you are not using fork to start yourchild processes and you have forgotten to use the proper idiomin the main module:if __name__ == '__main__':freeze_support()...The "freeze_support()" line can be omitted if the programis not going to be frozen to produce an executable.
""""""
image_show 显示图片
img: 接受一个图像张量img
进行归一化处理,将其转化为Numpy数组,然后使用plt.imshow显示图像
"""def image_show(img):"""显示图片:param img: 要显示的图像:return: 无"""# 对图像归一化操作img = img / 2 + 0.5# 转化为张量img_np = img.numpy()# 以正常通道顺序显示图片plt.imshow(np.transpose(img_np, (1, 2, 0)))if __name__ == '__main__':# 创建Net实例net = Net()# 定义设备device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")net.to(device) # 👈 添加这一行!# 3 训练网络模型# 定义交叉熵损失函数和随机梯度下降优化器(学习率为0.01 动量为0.9)criterion = torch.nn.CrossEntropyLoss()optimizer = torch.optim.SGD(net.parameters(), lr=0.001, momentum=0.9)# 循环训练nums_epoch = 2for epoch in range(nums_epoch):running_loss = 0.0# 一次循环 50000/4=12500次for i, (inputs, labels) in enumerate(train_loader, 0):inputs, labels = inputs.to(device), labels.to(device)optimizer.zero_grad()# RuntimeError: Input type (torch.cuda.FloatTensor) and weight type (torch.FloatTensor) should be the same 添加 net.to(device) # 👈 添加 保证两个数据不在同一个设备上outputs = net(inputs)loss = criterion(outputs, labels)loss.backward()optimizer.step()running_loss += loss.item()if i % 3000 == 2999:print('[%d, %5d] loss: %.3f' % (epoch + 1, i + 1, running_loss / 3000))running_loss = 0.0print("训练结束")# 应用网络模型# 迭代测试集加速器 抽取测试集中的4张图片 每个批次包含 4 张图像(因为 batch_size=4)data_iter = iter(test_loader)# 使用 next(data_iter) 获取第一个批次的数据,其中包含 4 张图像和对应的标签。images, labels = next(data_iter)# torchvision.utils.make_grid(images) 将这 4 张图像拼接成一个网格形式,便于显示image_show(torchvision.utils.make_grid(images))# 打印图片真实分类print('图像真实分类:', ' '.join('%5s' % classes[labels[j]] for j in range(4)))# 将图像images输入到模型net,得到模型输出outputs = net(images.to(device))# 获取模型预测结果 在输出的第一维(每个图像)上找到最大的值和索引 1表示在第一维上进行最大值搜索_, predicted = torch.max(outputs, 1)print('图像预测分类:', ' '.join('%5s' % classes[predicted[j]] for j in range(4)))# 定义预测数量和总预测值初始化为0correct, total = 0, 0# 禁用梯度计算 进行测试with torch.no_grad():# 遍历测试集的数据和对应的标签for images, labels in test_loader:# 将图像输入到模型net,得到模型输出outputs = net(images.to(device))# 在输出的第一维(每个图像)上找到最大的值和索引 得到预测的类别predicted_, predicted = torch.max(outputs.data, 1)# 累计总预测数量total 通过labels.size(0) 获取标签数量total += labels.size(0)# 累计预测正确的数量correct 通过判断预测的类别predicted 是否等于标签labels .sum().item将张量转化为整数correct += (predicted == labels.to(device)).sum().item()# 打印测试集的准确率print('预测准确率: %d %%' % (100 * correct / total))
训练结果(简化版)
[1, 3000] loss: 2.146
[1, 6000] loss: 1.778
[1, 9000] loss: 1.606
[1, 12000] loss: 1.511
[2, 3000] loss: 1.423
[2, 6000] loss: 1.374
[2, 9000] loss: 1.327
[2, 12000] loss: 1.288
训练结束
图像真实分类: cat deer deerplane
图像预测分类: bird deerhorse ship
预测准确率: 55 %
实现代码(优化版)
- 优化点1:使用ResNet18预训练模型
- 优化点2:增大
batch_size = 256
- 优化点3:预先加载数据
prefetch_factor=2
- 优化点4:使用更合适的优化器(如 Adam)并调整学习率。
- 优化点5:使用混合精度
scaler = torch.amp.GradScaler('cuda')
- 优化点6:
import os
import matplotlib.pyplot as plt
import numpy as np
import torch
import torchvision
from torch.amp import autocast
from torchvision.transforms import transforms
import torchvision.models as models# 0 torchvision的数据集是基于PILImage,数值范围[0,1]需要转化范围为[-1,1]的张量
transform = transforms.Compose([# 优化4 在数据预处理阶段添加数据增强操作,提高模型泛化能力。transforms.RandomHorizontalFlip(), # 随机水平翻转transforms.RandomRotation(10), # 随机旋转transforms.ToTensor(), # 将数据转化为张量# 归一化处理 均值0.5 标准差0.5transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
])
batch_size = 256
# 1 导入训练集和测试数据集 并设置数据加载参数 定义数据集中的类别名称
"""
torchvision.datasets.CIFAR10 定义CIFAR-10数据集
root='./data' 指定数据集的根目录
train=True 创建训练集
download=True 自动下载数据集 如果数据集不存在报错
transform=transform 应用数据预处理变换
"""
train_dataset = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=transform)
"""
torch.utils.data.DataLoader 定义数据加载器 加载训练数据
train_dataset 加载的数据集对象 训练数据集
batch_size=4 每个批次包含的样本数量
shuffle=True 在每个 epoch 开始时打乱数据顺序
num_workers=4 使用 4 个子进程加载数据(加快数据读取速度)
"""
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=batch_size, shuffle=True, num_workers=4,pin_memory=True,prefetch_factor=2)"""
torchvision.datasets.CIFAR10 定义CIFAR-10数据集
root='./data' 指定数据集的根目录
train=False 创建测试集
download=True 自动下载数据集 如果数据集不存在报错
transform=transform 应用数据预处理变换
prefetch_factor=2 提前加载2个batch_size
"""
test_dataset = torchvision.datasets.CIFAR10(root='./data', train=False, download=True, transform=transform)
"""
torch.utils.data.DataLoader 定义数据加载器 加载测试数据
train_dataset 加载的数据集对象 训练数据集
batch_size=4 每个批次包含的样本数量
shuffle=False 不在每个 epoch 开始时打乱数据顺序
num_workers=4 使用 4 个子进程加载数据(加快数据读取速度)
prefetch_factor=2 提前加载2个batch_size
"""
test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=batch_size, shuffle=False, num_workers=4,pin_memory=True,prefetch_factor=2)
# 定义类别名
classes = ('plane', 'car', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck')"""
image_show 显示图片
img: 接受一个图像张量img
进行归一化处理,将其转化为Numpy数组,然后使用plt.imshow显示图像
"""
def image_show(img):"""显示图片:param img: 要显示的图像:return: 无"""# 对图像归一化操作img = img / 2 + 0.5# 转化为张量img_np = img.numpy()# 以正常通道顺序显示图片plt.imshow(np.transpose(img_np, (1, 2, 0)))if __name__ == '__main__':# 设置模型保存路径model_dir = "./data"os.makedirs(model_dir, exist_ok=True)# 指定模型文件路径model_path = os.path.join(model_dir, "resnet18-f37072fd.pth")# 如果模型不存在,则自动下载到指定路径if not os.path.exists(model_path):# 下载模型权重到指定路径resnet18_url = "https://download.pytorch.org/models/resnet18-f37072fd.pth"torch.hub.load_state_dict_from_url(resnet18_url, model_dir=model_dir, progress=True,file_name="resnet18-f37072fd.pth")# 加载 ResNet18 并指定本地权重路径state_dict = torch.load(model_path)net = models.resnet18(weights="IMAGENET1K_V1")net.load_state_dict(state_dict)# 使用 ImageNet 预训练的 ResNet18 并修改输出类别数net.fc = torch.nn.Linear(net.fc.in_features, 10) # 修改最后的全连接层# 定义设备device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")print("使用设备:", device)# 保证两个数据不在同一个设备上net.to(device)# 3 训练网络模型# 优化3 使用更合适的优化器(如 Adam)并调整学习率。criterion = torch.nn.CrossEntropyLoss()optimizer = torch.optim.Adam(net.parameters(), lr=0.001)# 混合精度 scalerscaler = torch.amp.GradScaler('cuda')# 循环训练nums_epoch = 10 # 优化2:增加训练轮数for epoch in range(nums_epoch):net.train()running_loss = 0.0# 一次循环 50000/128=390次for i, (inputs, labels) in enumerate(train_loader, 0):inputs, labels = inputs.to(device), labels.to(device)optimizer.zero_grad()with autocast(device_type="cuda"):outputs = net(inputs)loss = criterion(outputs, labels)scaler.scale(loss).backward()scaler.step(optimizer)scaler.update()running_loss += loss.item()if i % 50 == 0:print('[%d, %5d] loss: %.3f' % (epoch, i, running_loss / 100))running_loss = 0.0print("训练结束")# 应用网络模型# 迭代测试集加速器 抽取测试集中的4张图片 每个批次包含 36 张图像(因为 batch_size=4)data_iter = iter(test_loader)# 使用 next(data_iter) 获取第一个批次的数据,其中包含 36 张图像和对应的标签。images, labels = next(data_iter)# torchvision.utils.make_grid(images) 将这 36 张图像拼接成一个网格形式,便于显示image_show(torchvision.utils.make_grid(images))# 打印图片真实分类print('图像真实分类:', ' '.join('%5s' % classes[labels[j]] for j in range(batch_size)))# 将图像images输入到模型net,得到模型输出outputs = net(images.to(device))# 获取模型预测结果 在输出的第一维(每个图像)上找到最大的值和索引 1表示在第一维上进行最大值搜索_, predicted = torch.max(outputs, 1)print('图像预测分类:', ' '.join('%5s' % classes[predicted[j]] for j in range(batch_size)))# 定义预测数量和总预测值初始化为0correct, total = 0, 0# 开启模型评估模式,关闭 BatchNorm 和 Dropoutnet.eval()# 禁用梯度计算 进行测试with torch.no_grad():# 遍历测试集的数据和对应的标签for images, labels in test_loader:# 将图像输入到模型net,得到模型输出images, labels = images.to(device), labels.to(device)outputs = net(images)# 在输出的第一维(每个图像)上找到最大的值和索引 得到预测的类别predicted_, predicted = torch.max(outputs.data, 1)# 累计总预测数量total 通过labels.size(0) 获取标签数量total += labels.size(0)# 累计预测正确的数量correct 通过判断预测的类别predicted 是否等于标签labels .sum().item将张量转化为整数correct += (predicted == labels).sum().item()# 打印测试集的准确率print('预测准确率: %d %%' % (100 * correct / total))# 保存模型torch.save(net.state_dict(), 'resnet18_cifar10.pth')
训练结果(优化版)
...
[8, 0] loss: 0.003
[8, 50] loss: 0.161
[8, 100] loss: 0.163
[8, 150] loss: 0.179
[9, 0] loss: 0.003
[9, 50] loss: 0.141
[9, 100] loss: 0.156
[9, 150] loss: 0.155
预测准确率: 81 %
存在的问题
- 训练时gpu占用显存较小,不到2GB
- 训练时间较长,大部分时间可能用于数据传输,GPU高负载时间较短
- window平台无法使用 Triton加速
相关文章:
PyTorch图像建模(图像识别、分割和分类案例)
文章目录 图像分类技术:改变生活的智能之眼图形识别技术图像识别过程图像预处理图像特征提取 图像分割技术练习案例:图像分类项目源码地址实现代码(简化版)训练结果(简化版)实现代码(优化版&…...
系统安全应用
文章目录 一.账号安全控制1.基本安全措施①系统账号清理②密码安全控制 2.用户切换与提权①su命令用法②PAM认证 3.sudo命令-提升执行权限①在配置文件/etc/sudoers中添加授权 二.系统引导和登录控制1.开关机安全控制①调整bios引导设置②限制更改grub引导参数 三.弱口令检测.端…...
day53—二分法—搜索旋转排序数组(LeetCode-81)
题目描述 已知存在一个按非降序排列的整数数组 nums ,数组中的值不必互不相同。 在传递给函数之前,nums 在预先未知的某个下标 k(0 < k < nums.length)上进行了 旋转 ,使数组变为 [nums[k], nums[k1], ..., nu…...
力扣面试150题--从前序与中序遍历序列构造二叉树
Day 43 题目描述 思路(这题第一次没做出来,看了题解后理解) 做法:哈希表递归 首先复习一下前序遍历和中序遍历, 前序遍历:中左右,这个不仅是遍历树的路线,同时对一个对于一个前序遍…...
win10 上删除文件夹失败的一个原因:sqlYog 备份/导出关联了该文件夹
在尝试删除路径为.../bak/sql的文件时,系统提示无权限操作。然而,关闭SQLyog后,删除操作成功完成。这表明SQLyog可能正在占用该文件,导致删除权限受限。关闭SQLyog后,文件被释放,删除操作得以顺利进行。建议…...
卷java、基础2
内部类 了解 1. 成员内部类(了解) 2. 静态内部类(了解) 实例化的写法 局部内部类(看看就好) 局部内部类是定义在在方法中、代码块中、构造器等执行体中。 匿名内部类(重要) 1.先…...
从 “龟速” 到流畅,英国 - 中国 SD-WAN 专线让分公司直连总部系统
对于在英国设立总部、国内开设分公司的企业而言,分公司访问总部内网系统常面临网络延迟高、连接不稳定等问题。传统网络方案难以满足跨国数据传输需求,而英国 - 中国 SD-WAN 国际组网专线凭借创新技术,为企业搭建起高效稳定的网络桥梁。 SD-W…...
C++--综合应用-演讲比赛项目
需求 分析 1、初始化,生成演讲学生数组,打乱数组以便随机分组 2、每轮比赛后需要统计每个学生的胜场,以便决定进入下一轮和最终胜利的学生 代码实现 #pragma once#include<iostream> #include<string> #include<algorithm…...
简单实现网页加载进度条
一、监听静态资源加载情况 可以通过window.performance 对象来监听⻚⾯资源加载进度。该对象提供了各种⽅法来获取资源加载的详细信息。 可以使⽤performance.getEntries() ⽅法获取⻚⾯上所有的资源加载信息。可以使⽤该⽅法来监测每个资源的加载状态,计算加载时间…...
C语言——深入理解指针(一)
C语言——指针(一) 进入指针后,C语言就有了一定的难度,我们需要认真理解 指针(一) 1 .内存和地址 内存:程序运行起来后,要加载到内存中,数据的存储也是在内存中。 我…...
计算机组织原理第一章
1、 2、 3、 4、 5、 从源程序到可执行文件: 6、 7、 8、 8、...
upload-labs通关笔记-第12关 文件上传之白名单GET法
目录 一、白名单过滤 二、%00截断 1、%00截断原理 2、空字符 3、截断条件 (1)PHP版本 < 5.3.4 (2)magic_quotes_gpc配置为Off (3)代码逻辑存在缺陷 三、源码分析 1、代码审计 (1&…...
网络学习-epoll(四)
一、为什么使用epoll? 1、poll实质是对select的优化,解决了其参数限制的问题,但是其本质还是一个轮询机制。 2、poll是系统调用,当客户端连接数量较多时,会将大量的pollfd从用户态拷贝到内核态,开销较大。…...
uWSGI、IIS、Tomcat有啥区别?
uWSGI、IIS 和 Tomcat对比 以下是 uWSGI、IIS 和 Tomcat 的对比分析,包括它们的核心特性、适用场景和典型用例: 1. uWSGI 核心特性 • 定位:专为 Python 应用设计的应用服务器(支持 WSGI/ASGI 协议)。 • 协议支持&a…...
AI本地化服务的战略机遇与发展路径
一、市场机遇:线下商业的AI赋能真空 1. 需求侧痛点明确 实体商家面临线上平台25%-30%的高额抽成挤压利润,传统地推转化率不足5%,而AI驱动的精准营销可将获客成本降低60%以上。区域性服务商凭借对本地消费习惯的深度理解,能构建更精…...
游戏盾的功有哪些?
游戏盾的功能主要包括以下几方面: 一、网络攻击防护 DDoS攻击防护: T级防御能力:游戏盾提供分布式云节点防御集群,可跨地区、跨机房动态扩展防御能力和负载容量,轻松达到T级别防御,有效抵御SYN Flood、UD…...
C++开源库argh使用教程
概述 argh 是一个轻量级的 C 命令行参数解析库,只需要包含一个头文件即可使用。 github页面: https://github.com/adishavit/argh 基本用法 #include "argh.h" 创建argh::parser对象 使用parse方法解析命令行 argh::parser重载了括号运…...
万用表如何区分零线、火线、地线
普通验电笔只能区分火线,零线和地线是区分不出来的,那么,我们就需要使用万用表来进行区分!轻松搞定! 万用表操作步骤: 1、黑表笔插Com,红表笔接电压和电阻档,万用表打到交流电压750V档。 2、黑表…...
java配置webSocket、前端使用uniapp连接
一、这个管理系统是基于若依框架,配置webSocKet的maven依赖 <!--websocket--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency> 二、配…...
01、java方法
前面与c都很相似,于是我决定从这一章开始复盘java的学习 一、方法 方法的好处主要体现在使用方便,可以在多处调用,不必反复造轮子 1、方法的使用 这就是一个简单的方法创建: public class java0517 {public static int ret(int …...
springboot实现幂等性
一 增加注解 import java.lang.annotation.*;Retention(RetentionPolicy.RUNTIME) Target({ElementType.METHOD}) Documented public interface ApiIdempotent { } 二 aop实现切面 import cn.hutool.extra.spring.SpringUtil; import com.alibaba.fastjson.JSONObject; import…...
Flink 快速入门
本文涉及到大量的底层原理知识,包括运行机制图解都非常详细,还有一些实战案例,所以导致本篇文章会比较长,内容比较多,由于内容太多,很多目录可能展示不出来,需要去细心的查看,非常适…...
MySQL 8.0 OCP 英文题库解析(五)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题31~40 试题31:…...
lovart design 设计类agent的系统提示词解读
文章目录 lovart 设计agent介绍角色定义工作规范工具调用任务复杂度指南任务移交指南其他ref lovart 设计agent介绍 lovart作为设计agent,产品功能包括: 全链路设计能力:可以快速生成完整的品牌视觉方案,包括标志、配色、品牌规范…...
C++11特性
一.C的发展历史 C11是C的第二个主要版本,从C98起的重要更新,引入了大量更改,从C11起C规律的进行每3年更新一次。 二.列表初始化 2.1 C98和C11中的 { } 传统的C98中使用 { } 来进行列表初始化,结构体函数体都使用此类方法&…...
鸿蒙PC操作系统:从Linux到自研微内核的蜕变
鸿蒙PC操作系统是否基于Linux内核,需要结合其技术架构、发展阶段和官方声明综合分析。以下从多个角度展开论述: 一、鸿蒙操作系统的多内核架构设计 多内核混合架构 根据资料,鸿蒙操作系统(HarmonyOS)采用分层多内核架构,内核层包含Linux内核、LiteOS-m内核、LiteOS-a内核…...
用 RefCounted + WeakPtr 构建线程安全的异步模块
在 Chromium 的多线程异步编程中,合理管理对象生命周期非常关键。本文深入介绍 base::RefCountedThreadSafe 和 base::WeakPtr 的组合使用方法,并通过示例分析其使用要点及易踩的坑。 🌱 基础概念回顾 1. RefCountedThreadSafe<T> 是 …...
ElasticSearch 8.x 快速上手并了解核心概念
目录 核心概念概念总结 常见操作索引的常见操作常见的数据类型指定索引库字段类型mapping查看索引库的字段类型最高频使用的数据类型 核心概念 在新版Elasticsearch中,文档document就是一行记录(json),而这些记录存在于索引库(index)中, 索引名称必须是…...
2025.5.19总结
工作:今天回归了3个问题单,测需求提交两个问题。然后再工作中慢慢有了自己的一些成就感,觉得工作越来越有干劲,因为感觉自己在工作上能做得越来越好,无论是在沟通方面,还是与同事的关系上,感觉都…...
C++(25): 标准库 <deque>
目录 1、 核心概念 2. 基本语法 3. 特点 4. 特有成员函数 5. 内存与性能 6. 示例代码 7. 成员函数列表 8. 使用场景 9. 注意事项 1、 核心概念 双端队列(Double-Ended Queue,deque) 是一种允许在队列头部和尾部高效插入和删除元素的线性数据结构,同时支持随机访问。…...
[ 计算机网络 ] | 宏观谈谈计算机网络
(目录占位) 网络间通信,本质是不同的两个用户通信;本质是两个不同主机上的两个进程间通信。 因为物理距离的提升,就衍生出了很多问题。TCP/IP协议栈 / OSI七层模型,将协议分层,每一层都是为了…...
会议动态|第十五届亚太燃烧学术年会精彩探析
ASPACC 2025第十五届亚太燃烧学术年会5月19日在新加坡隆重召开,本届盛会,以“构建零碳和可持续未来”为主题,汇聚了来自亚太的2000余位专家学者进行学术交流。会议聚焦燃烧反应动力学、火焰传播、燃烧效率等方向。 千眼狼在会议上展示了高速摄…...
Dify-3:系统架构
系统架构 概述了 Dify 的系统架构,解释主要组件如何协同工作以提供大语言模型(LLM)应用开发平台。内容涵盖高层架构、部署选项、核心子系统和外部集成。 1. 整体架构 Dify 采用基于微服务的架构,将前端 Web 应用与后端 API 服务…...
使用 docker-volume-backup 备份 Docker 卷
docker-volume-backup 是一个用于备份 Docker 卷的工具,在 Windows 10 上使用它,你可以按照以下步骤操作: 1. 确保 Docker 环境已安装并正常运行 在 Windows 10 上,你需要安装 Docker Desktop for Windows。可以从 Docker 官方网…...
分布式与集群:概念、区别与协同
分布式与集群:概念、区别与协同 在分布式系统与云计算领域,分布式(Distributed)和集群(Cluster)是两个高频出现的核心概念。它们常被混淆,但本质上属于不同维度的设计思想。本文将从定义、分类、实际应用及协同关系四个层面,结合 Dubbo、Git、Hadoop 等典型案例,系统…...
Matlab简单优化模型应用
一、目的 掌握优化模型的建立方法,能够借助Matlab工具对建立的优化模型进行求解。 二、内容与设计思想 1、分析:某石油设备制造厂每月需要100套压缩机用于维护和运营石油开采设备。这些零件由工厂内部生产,每月生产500套,每批压缩机的生产…...
板凳-------Mysql cookbook学习 (四)
综合对比与选择建议 维度 PHP Java Python Ruby Perl 学习门槛 低(适合新手) 高(语法复杂) 低(语法简洁) 中(需理解 Rails 理念) 中(特殊语法…...
C语言学习笔记之条件编译
编译器根据条件的真假决定是否编译相关的代码 常见的条件编译有两种方法: 一、根据宏是否定义,其语法如下: #ifdef <macro> …… #else …… #endif例子: #include <stdio.h>//def _DEBUG_ //定义_DEBUG_ int main(…...
网络安全-等级保护(等保) 2-7 GB/T 25058—2019 《信息安全技术 网络安全等级保护实施指南》-2019-08-30发布【现行】
################################################################################ GB/T 22239-2019 《信息安全技术 网络安全等级保护基础要求》包含安全物理环境、安全通信网络、安全区域边界、安全计算环境、安全管理中心、安全管理制度、安全管理机构、安全管理人员、安…...
Android设备 显示充电速度流程
整体逻辑:设备充电速度的判断 系统通过读取充电器的最大电流(Current)与最大电压(Voltage),计算最大充电功率(Wattage),以此判断当前是慢充、普通充还是快充:…...
megatron——EP并行
1、专家并行(Expert Parallelism, EP)适用场景 定义: 专家并行是指在混合专家模型(Mixture of Experts, MoE)中,将不同的专家(即子模型)分配到不同的设备上,每个设备只负…...
如何轻松删除电脑上的文件(无法恢复文件)
如果您想清理电脑上的存储空间,您可能需要轻松删除电脑上的文件以释放空间。此外,如果您打算出售或捐赠您的旧电脑,永久删除您的文件至关重要,这可以保护您的隐私。无论如何,您需要一种有效且可靠的方法来从计算机中删…...
搭建一个永久免费的博客
搭建永久免费的博客(1)基本介绍 HugoStackGitHub GitHub GitHub GitHub Build and ship software on a single, collaborative platform GitHub 下载安装git Git - Downloads Edge插件authenticator 2fa client Settings->Password and auth…...
计算机底层的多级缓存以及缓存带来的数据覆盖问题
没有多级缓存的情况 有多级缓存的情况 缓存带来的操作覆盖问题 锁总线带来的消耗太大了。...
ICRA 2024 PROGrasp——实用的人机交互物体抓取系统
在机器人抓取任务中,自然语言理解能够显著改善人机交互体验,尤其是在需要机器人根据人类指令进行环境交互的场景中。然而,现有的抓取系统往往要求用户明确指定目标对象的类别,限制了交互的自然性和灵活性。为了解决这一问题&#…...
【Vue篇】潮汐中的生命周期观测站
目录 引言 一、Vue生命周期 二、Vue生命周期钩子 三、、生命周期钩子实战 1.在created中发送数据 2.在mounted中获取焦点 四、综合案例-小黑记账清单 1.需求图示: 2.需求分析 3.思路分析 4.代码 5. 总结 引言 💬 欢迎讨论:如果…...
【OpenCV基础2】图像运算、水印、加密、摄像头
目录 一、图像运算 1、利用“” 2、cv2.add() 3、掩膜异或 二、摄像头 1、读取、视频流保存 2、人脸识别 三、数字水印 1、水印嵌入 2、水印提取 四、图像加密 一、图像运算 1、利用“” import cv2 利用""方法将两幅图像相加img1 cv2.imread(project…...
第 25 届中国全电展即将启幕,构建闭环能源生态系统推动全球能源转型
由 AI 算力爆发引发的能源消耗剧增,与碳中和目标、能源安全需求及电网转型压力形成叠加效应,使全球能源体系面临前所未有的挑战。在此背景下,第 25 届中国全电展(EPOWER EXPO)将于 2025 年 6 月 11 日至 13 日在上海新…...
vue3:十三、分类管理-表格--编辑、新增、详情、刷新
一、效果 实现封装表格的新增、编辑、详情查看,表格刷新功能 实现表格组件中表单的封装 1、新增 如下图,新增页面显示空白的下拉,文本框,文本域,并实现提交功能 2、编辑 如下图,点击行数据,可将行数据展示到编辑弹窗,并实现提交功能 3、详情 如下图,点击行数据,…...
一周快讯 | 银发文娱旅游一周新鲜事
银发文娱旅游一周新鲜事 一周银发文娱旅游产业资讯速览 星期一 5月19日 1 企业动态 同方全球人寿等共建一站式康养服务生态 东秀星健康养老产业等合作赋能康养产业,开发“旅居养老”项目 欧莱雅等合作将推出银发族形象管理课程 2 行业风向 总投资10亿&a…...