香橙派 AIpro 昇腾 Ascend C++ 分类模型适配
香橙派 AIpro 昇腾 Ascend C++ 分类模型适配
flyfish
文章目录
- 香橙派 AIpro 昇腾 Ascend C++ 分类模型适配
- 前言
- 一、PyTorch官网resnet模型处理方式
- 1、PyTorch模型 导出 onnx格式
- 2、完整测试 输出top1结果
- 3、完整测试 输出top5结果
- 二、YOLOv8官网resnet模型Python处理方式
- 三、昇腾resnet原始的C++预处理方式
- 四、香橙派 AIpro 分类模型 自带Python示例的预处理方式
- 五、对比不同
- 1、Normalize
- 2、CenterCrop
- 六、香橙派 AIpro 分类模型resnet C++ 适配
- 方式1 代码如下
- 方式2 代码如下
- 七、可以这样处理的原因
模型可以从多个地方获取,这里说明两个地方
从PyTorch官网获取到的resnet模型
从YOLOv8官网获取到的resnet模型
前言
模型的处理
查看香橙派 AIpro SoC版本
根据上面查看到SoC版本是 310B4,在转换模型时选择Ascend310B4
在硬件上可以加装一块固态盘,装上之后开机自动识别
一、PyTorch官网resnet模型处理方式
1、PyTorch模型 导出 onnx格式
从PyTorch官网获取到的resnet模型
# -*- coding: utf-8 -*-
import torch
import torchvision
import onnx
import onnxruntime
import torch.nn as nn
# 创建 PyTorch ResNet50 模型实例#在线下载
#model = torchvision.models.resnet50(pretrained=True)#本地加载
checkpoint_path ="/home/model/resnet50-19c8e357.pth"
model = torchvision.models.resnet50().to("cpu")
checkpoint = torch.load(checkpoint_path,map_location=torch.device('cpu'))model.load_state_dict(checkpoint)
model.eval()batch_size = 1
input_shape = (batch_size, 3, 224, 224)
input_data = torch.randn(input_shape)# 将模型转换为 ONNX 格式
output_path_static = "resnet_static.onnx"
output_path_dynamic = "resnet_dynamic.onnx"# dynamic
torch.onnx.export(model, input_data, output_path_dynamic,input_names=["input"], output_names=["output"],dynamic_axes={"input": {0: "batch_size"}, "output": {0: "batch_size"}})#static
torch.onnx.export(model, input_data, output_path_static,input_names=["input"], output_names=["output"])# 简单测试
session = onnxruntime.InferenceSession(output_path_dynamic)
new_batch_size = 2
new_input_shape = (new_batch_size, 3, 224, 224)
new_input_data = torch.randn(new_input_shape)
outputs = session.run(["output"], {"input": new_input_data.numpy()})
print(outputs)
2、完整测试 输出top1结果
# -*- coding: utf-8 -*-
import onnxruntime
import numpy as np
from torchvision import datasets, models, transforms
from PIL import Image
import torch.nn as nn
import torchdef postprocess(outputs):res = list()outputs_exp = np.exp(outputs)outputs = outputs_exp / np.sum(outputs_exp, axis=1)[:,None]predictions = np.argmax(outputs, axis = 1)for pred, output in zip(predictions, outputs):score = output[pred]res.append((pred.tolist(),float(score)))return resonnx_model_path = "/home/model/resnet50_static.onnx"ort_session = onnxruntime.InferenceSession(onnx_model_path)transform = transforms.Compose([transforms.Resize(256),transforms.CenterCrop(224),transforms.ToTensor(),transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])image = Image.open("/home/dog1_1024_683.jpg")
image = transform(image).unsqueeze(0) # 增加批处理维度input_data = image.detach().numpy()outputs_np = ort_session.run(None, {'input': input_data})
outputs = outputs_np[0]res = postprocess(outputs)
print(res)
[(162, 0.9634788632392883)]
3、完整测试 输出top5结果
先把标签文件imagenet_classes.txt下载下来
curl -o imagenet_classes.txt https://raw.githubusercontent.com/pytorch/hub/master/imagenet_classes.txt
# -*- coding: utf-8 -*-
import onnxruntime
import numpy as np
from torchvision import datasets, models, transforms
from PIL import Image
import torch.nn as nn
import torch
from onnx import numpy_helper
import timewith open("imagenet_classes.txt", "r") as f:categories = [s.strip() for s in f.readlines()]def softmax(x):e_x = np.exp(x - np.max(x))return e_x / e_x.sum()onnx_model_path = "/home/model/resnet50_static.onnx"ort_session = onnxruntime.InferenceSession(onnx_model_path)transform = transforms.Compose([transforms.Resize(256),transforms.CenterCrop(224),transforms.ToTensor(),transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])image = Image.open("/home/dog1_1024_683.jpg")
image = transform(image).unsqueeze(0) # 增加批处理维度session = onnxruntime.InferenceSession(onnx_model_path, providers=['CPUExecutionProvider'])latency = []start = time.time()
input_arr = image.detach().numpy()output = session.run([], {'input':input_arr})[0]
latency.append(time.time() - start)
output = output.flatten()output = softmax(output)
top5_catid = np.argsort(-output)[:5]
for catid in top5_catid:print(catid, categories[catid], output[catid])print("ONNX Runtime CPU Inference time = {} ms".format(format(sum(latency) * 1000 / len(latency), '.2f')))
162 beagle 0.963479
167 English foxhound 0.020814817
166 Walker hound 0.011742038
161 basset 0.0024754668
164 bluetick 0.0004774033
ONNX Runtime CPU Inference time = 20.01 ms
预处理方式
在计算机视觉领域,很多预训练模型(例如ResNet、VGG等)都是基于ImageNet数据集训练的。因此,使用相同的均值和标准差对数据进行标准化处理,可以确保输入数据与预训练模型的输入分布一致,有助于充分利用预训练模型的优势。
transforms.Normalize函数通过减去均值并除以标准差,将输入图像的每个通道进行标准化处理。
ImageNet数据集的结构
训练集:包含超过120万张图像,用于训练模型。
验证集:包含50,000张图像,用于模型验证和调整超参数。
测试集:包含100,000张图像,用于评估模型的最终性能。
使用ImageNet数据集的注意事项
预处理:在使用ImageNet数据集进行训练时,通常需要对图像进行标准化处理,常用的均值和标准差为:
均值:0.485,0.456,0.406
标准差:0.229,0.224,0.225
数据增强:为了提升模型的泛化能力,通常会对训练图像进行数据增强处理,例如随机裁剪、水平翻转等
transforms.Resize 处理方式不同,有的地方是256,有的地方用的是224,
二、YOLOv8官网resnet模型Python处理方式
从YOLOv8官网获取到的resnet模型
YOLOv8由Ultralytics 提供,YOLOv8 支持全方位的视觉 AI 任务,包括检测、分割、姿态估计、跟踪和分类。
yolov8-cls-resnet50配置
# Parameters
nc: 1000 # number of classes
scales: # model compound scaling constants, i.e. 'model=yolov8n-cls.yaml' will call yolov8-cls.yaml with scale 'n'# [depth, width, max_channels]n: [0.33, 0.25, 1024]s: [0.33, 0.50, 1024]m: [0.67, 0.75, 1024]l: [1.00, 1.00, 1024]x: [1.00, 1.25, 1024]# YOLOv8.0n backbone
backbone:# [from, repeats, module, args]- [-1, 1, ResNetLayer, [3, 64, 1, True, 1]] # 0-P1/2- [-1, 1, ResNetLayer, [64, 64, 1, False, 3]] # 1-P2/4- [-1, 1, ResNetLayer, [256, 128, 2, False, 4]] # 2-P3/8- [-1, 1, ResNetLayer, [512, 256, 2, False, 6]] # 3-P4/16- [-1, 1, ResNetLayer, [1024, 512, 2, False, 3]] # 4-P5/32# YOLOv8.0n head
head:- [-1, 1, Classify, [nc]] # Classify
该分类模型的预处理方式如下
IMAGENET_MEAN = 0.485, 0.456, 0.406 # RGB mean
IMAGENET_STD = 0.229, 0.224, 0.225 # RGB standard deviation
def classify_transforms(size=224,mean=DEFAULT_MEAN,std=DEFAULT_STD,interpolation=Image.BILINEAR,crop_fraction: float = DEFAULT_CROP_FRACTION,
):"""Classification transforms for evaluation/inference. Inspired by timm/data/transforms_factory.py.Args:size (int): image sizemean (tuple): mean values of RGB channelsstd (tuple): std values of RGB channelsinterpolation (T.InterpolationMode): interpolation mode. default is T.InterpolationMode.BILINEAR.crop_fraction (float): fraction of image to crop. default is 1.0.Returns:(T.Compose): torchvision transforms"""import torchvision.transforms as T # scope for faster 'import ultralytics'if isinstance(size, (tuple, list)):assert len(size) == 2scale_size = tuple(math.floor(x / crop_fraction) for x in size)else:scale_size = math.floor(size / crop_fraction)scale_size = (scale_size, scale_size)# Aspect ratio is preserved, crops center within image, no borders are added, image is lostif scale_size[0] == scale_size[1]:# Simple case, use torchvision built-in Resize with the shortest edge mode (scalar size arg)tfl = [T.Resize(scale_size[0], interpolation=interpolation)]else:# Resize the shortest edge to matching target dim for non-square targettfl = [T.Resize(scale_size)]tfl += [T.CenterCrop(size)]tfl += [T.ToTensor(),T.Normalize(mean=torch.tensor(mean),std=torch.tensor(std),),]return T.Compose(tfl)
标准化数据分布:深度学习模型通常在训练过程中受益于输入数据的标准化,即将输入数据的分布调整为零均值和单位方差。这样可以确保所有特征具有相似的尺度,从而提高学习效率。对于图像数据而言,这意味着将像素值从原始范围(通常是0-255)转换到一个更统一的范围。
加速收敛:通过减去平均值并除以标准差,可以使梯度下降等优化算法在训练初期更快地收敛。这是因为这样的预处理减少了输入数据的方差,使得学习过程更加稳定和高效。
网络权重初始化的匹配:很多预训练模型(尤其是基于ImageNet训练的模型)在设计和训练时就假设了输入数据经过了这样的标准化处理。因此,在微调这些模型或使用它们作为特征提取器时,继续使用相同的预处理步骤能保证数据分布与模型预期的一致性,有助于保持模型性能。
泛化能力:ImageNet是一个大规模、多样化的图像数据集,其统计特性(如颜色分布)在很大程度上代表了自然图像的普遍特征。因此,使用ImageNet的统计量进行归一化有助于模型学习到更广泛适用的特征,增强模型在新数据上的泛化能力。
如果任务或数据集与ImageNet有显著不同,直接使用ImageNet的均值和标准差可能不是最佳选择。在这种情况下,根据自己数据集的统计特性来计算并使用均值和标准差进行归一化可能会得到更好的效果。
原始代码
三、昇腾resnet原始的C++预处理方式
namespace {const float min_chn_0 = 123.675;const float min_chn_1 = 116.28;const float min_chn_2 = 103.53;const float var_reci_chn_0 = 0.0171247538316637;const float var_reci_chn_1 = 0.0175070028011204;const float var_reci_chn_2 = 0.0174291938997821;
}Result SampleResnetQuickStart::ProcessInput(const string testImgPath)
{// read image from file by cvimagePath = testImgPath;srcImage = imread(testImgPath);Mat resizedImage;// zoom image to modelWidth_ * modelHeight_resize(srcImage, resizedImage, Size(modelWidth_, modelHeight_));// get properties of imageint32_t channel = resizedImage.channels();int32_t resizeHeight = resizedImage.rows;int32_t resizeWeight = resizedImage.cols;// data standardizationfloat meanRgb[3] = {min_chn_2, min_chn_1, min_chn_0};float stdRgb[3] = {var_reci_chn_2, var_reci_chn_1, var_reci_chn_0};// create malloc of image, which is shape with NCHWimageBytes = (float*)malloc(channel * resizeHeight * resizeWeight * sizeof(float));memset(imageBytes, 0, channel * resizeHeight * resizeWeight * sizeof(float));uint8_t bgrToRgb=2;// image to bytes with shape HWC to CHW, and switch channel BGR to RGBfor (int c = 0; c < channel; ++c){for (int h = 0; h < resizeHeight; ++h){for (int w = 0; w < resizeWeight; ++w){int dstIdx = (bgrToRgb - c) * resizeHeight * resizeWeight + h * resizeWeight + w;imageBytes[dstIdx] = static_cast<float>((resizedImage.at<cv::Vec3b>(h, w)[c] -1.0f*meanRgb[c]) * 1.0f*stdRgb[c] );}}}return SUCCESS;
}
四、香橙派 AIpro 分类模型 自带Python示例的预处理方式
img_origin = Image.open(pic_path).convert('RGB')
from torchvision import transforms
normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
trans_list = transforms.Compose([transforms.Resize(256),transforms.CenterCrop(224),transforms.ToTensor(),normalize])
img = trans_list(img_origin)
运行
(base) HwHiAiUser@orangepiaipro:~/samples/model-adapter-models/cls/edge_infer$ ./run.sh
set env successfully!!
start exec atc
[Sample] init resource stage:
Init resource success
load model mobilenetv3_100_bs1.om
Init model resource
[Model] create model output dataset:
[Model] create model output dataset success
[Model] class Model init resource stage success
acl.mdl.execute exhaust 0:00:00.004750
class result : cat
pic name: cat
pre cost:7050.8ms
forward cost:6.8ms
post cost:0.0ms
total cost:7057.6ms
FPS:0.1
image name :./data/cat/cat.23.jpg, infer result: cat
acl.mdl.execute exhaust 0:00:00.004660
class result : cat
pic name: cat
pre cost:14.0ms
forward cost:5.2ms
post cost:0.0ms
total cost:19.2ms
FPS:52.2
image name :./data/cat/cat.76.jpg, infer result: cat
五、对比不同
经过比对有以下不同处
1、Normalize
Normalize 数值的不同,YOLOv8和PyTorch 是IMAGENET_MEAN 和 IMAGENET_STD
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
昇腾的是
namespace {const float min_chn_0 = 123.675;const float min_chn_1 = 116.28;const float min_chn_2 = 103.53;const float var_reci_chn_0 = 0.0171247538316637;const float var_reci_chn_1 = 0.0175070028011204;const float var_reci_chn_2 = 0.0174291938997821;
}
2、CenterCrop
YOLOv8和PyTorch都有 CenterCrop 中心剪裁处理
六、香橙派 AIpro 分类模型resnet C++ 适配
根据对比的结果所以我们只要处理IMAGENET_MEAN 和 IMAGENET_STD ,在加上CenterCrop 中心剪裁处理
所以我们可以增加centercrop_and_resize函数,然后在ProcessInput调用即可。
方式1 代码如下
static const float IMAGENET_MEAN[3] = { 0.485, 0.456, 0.406 };
static const float IMAGENET_STD[3] = { 0.229, 0.224, 0.225 };void centercrop_and_resize(const cv::Mat& src_img, cv::Mat& dst_img,int target_size)
{int height = src_img.rows;int width = src_img.cols;if(height >= width)// hw{cv::resize(src_img, dst_img, cv::Size(target_size,target_size * height / width), 0, 0, cv::INTER_AREA);}else{cv::resize(src_img, dst_img, cv::Size(target_size * width / height,target_size), 0, 0, cv::INTER_AREA);}height = dst_img.rows;width = dst_img.cols;cv::Point center(width/2, height/2);cv::Size size(target_size, target_size);cv::getRectSubPix(dst_img, size, center, dst_img);
}
Result SampleResnetQuickStart::ProcessInput(const string testImgPath)
{// read image from file by cvimagePath = testImgPath;srcImage = imread(testImgPath);cv::cvtColor(srcImage, srcImage, cv::COLOR_BGR2RGB);Mat resizedImage;centercrop_and_resize(srcImage,resizedImage,224);// get properties of imageint32_t channel = resizedImage.channels();int32_t resizeHeight = resizedImage.rows;int32_t resizeWeight = resizedImage.cols;std::vector<cv::Mat> rgbChannels(3);cv::split(resizedImage, rgbChannels);for (size_t i = 0; i < rgbChannels.size(); i++) // resizedImage = resizedImage / 255.0;{rgbChannels[i].convertTo(rgbChannels[i], CV_32FC1, 1.0 / ( 255.0* IMAGENET_STD[i]), (0.0 - IMAGENET_MEAN[i]) / IMAGENET_STD[i]);}int len = channel * resizeHeight * resizeWeight * sizeof(float);imageBytes = (float *)malloc(len);memset(imageBytes, 0, len);int index = 0;for (int c = 0; c <3; c++){ // R,G,Bfor (int h = 0; h < modelHeight_; ++h){for (int w = 0; w < modelWidth_; ++w){imageBytes[index] = rgbChannels[c].at<float>(h, w); // R->G->Bindex++;}}}return SUCCESS;
}
方式2 代码如下
CenterCrop类似如下的写法
char* centercrop_and_resize(cv::Mat& iImg, std::vector<int> iImgSize, cv::Mat& oImg)
{if (iImg.channels() == 3){oImg = iImg.clone();cv::cvtColor(oImg, oImg, cv::COLOR_BGR2RGB);}else{cv::cvtColor(iImg, oImg, cv::COLOR_GRAY2RGB);}int h = iImg.rows;int w = iImg.cols;int m = min(h, w);int top = (h - m) / 2;int left = (w - m) / 2;cv::resize(oImg(cv::Rect(left, top, m, m)), oImg, cv::Size(iImgSize.at(0), iImgSize.at(1)));return RET_OK;
}
使用方式
cv::Mat img = cv::imread(img_path);
std::vector<int> imgSize = { 640, 640 };
cv::Mat processedImg;
centercrop_and_resize(iImg, imgSize, processedImg);
processedImg
就是我们要得到的cv::Mat 。图像经过centercrop,最后大小是640, 640,通道顺序是RGB
七、可以这样处理的原因
不同的Normalize数值之间的转换关系
# namespace {
# const float min_chn_0 = 123.675;
# const float min_chn_1 = 116.28;
# const float min_chn_2 = 103.53;
# const float var_reci_chn_0 = 0.0171247538316637;
# const float var_reci_chn_1 = 0.0175070028011204;
# const float var_reci_chn_2 = 0.0174291938997821;
# }import numpy as np
mean = np.array([0.485, 0.456, 0.406])
std = np.array([0.229, 0.224, 0.225])print(mean * 255)# [123.675 116.28 103.53 ]
print(1/(std*255))#[0.01712475 0.017507 0.01742919]
两者是可以相互转换的
# 0.485 × 255 = 123.675
# 0.456 × 255 = 116.28
# 0.406 × 255 = 103.53# 0.229 × 255 = 58.395
# 0.224 × 255 = 57.12
# 0.225 × 255 = 57.375# 1 ÷ 58.395 = 0.017124754
# 1 ÷ 57.12 = 0.017507003
# 1 ÷ 57.375 = 0.017429194
原始整个流程如下
适配后的处理就在上面第3步ProcessInput
加上了 CenterCrop
链接地址
https://www.hiascend.com/zh/
https://gitee.com/ascend
华为原版的resnet图片分类,有C++版本和Python版本
https://gitee.com/ascend/samples/tree/master/inference/modelInference/sampleResnetQuickStart/
相关文章:

香橙派 AIpro 昇腾 Ascend C++ 分类模型适配
香橙派 AIpro 昇腾 Ascend C 分类模型适配 flyfish 文章目录 香橙派 AIpro 昇腾 Ascend C 分类模型适配前言一、PyTorch官网resnet模型处理方式1、PyTorch模型 导出 onnx格式2、完整测试 输出top1结果3、完整测试 输出top5结果 二、YOLOv8官网resnet模型Python处理方式三、昇腾…...

2024吉林省电赛(达盛杯)
1. 电赛F4系统板3D图 提起自制STM32F407VET6系统板 2. 电赛原理图 3. 电赛PCB图 4. 智能车实物图 下图是电赛的实物图,结构采用3D打印 5. 软件设计 下图是程序设计图 6. 仿真视频 (1) 变化高度 2024吉林省电赛仿真1 (2) 变化轮距 2024电赛仿真2 7. APP控制小车 …...

【算法题】520 钻石争霸赛 2024 全解析
都是自己写的代码,发现自己的问题是做题速度还是不够快 520-1 爱之恒久远 在 520 这个特殊的日子里,请你直接在屏幕上输出:Forever and always。 输入格式: 本题没有输入。 输出格式: 在一行中输出 Forever and always…...

Yii 结合MPDF 给PDF文件添加多行水印
首先确保安装了mpdf扩展 composer require mpdf/mpdf public function createWaterPdf($file_path,$water_text){date_default_timezone_set(PRC);ini_set(memory_limit, 6400M);ini_set(max_execution_time, 0);try{$mpdf new Mpdf();$pageCount $mpdf->SetSourceFile…...
你什么时候感觉学明白Java了?
学是学不明白Java的,要学明白Java,一定只能在工作以后。 1 在学习阶段,哪怕是借鉴别人的学习路线,其实依然会学很多不必要的技能,比如jsp,swing,或者多线程,或者设计模式。 2 或者…...

马斯克xAI融资60亿美元,宣布打造世界第一超算中心,10万张H100GPU
昨天,埃隆马斯克的xAI初创公司宣布获得60亿美元的巨额融资,主要用于打造一台巨大的超级计算机,马斯克称之为“超级计算工厂”。 从创立OpenAI到如今的xAI,技术和算力的发展历经了几个时代,但似乎马斯克的吸金能力一直…...

贪心算法[1]
首先用最最最经典的部分背包问题来引入贪心的思想。 由题意可知我们需要挑选出价值最大的物品放入背包,价值即单位价值。 我们需要计算出每一堆金币中单位价值。金币的属性涉及两个特征,重量和价值。 所以我们使用结构体。 上代码。 #include <i…...

卢文岩博士受邀参与中国科学院大学校友论坛 解码DPU核心价值
近日,第五届中国科学院大学校友创新论坛正式举行,本次论坛聚焦科技前沿领域,旨在搭建高端对话平台,促进产学研深度融合。在大算力时代——AI技术前沿沙龙上,中科驭数高级副总裁、CTO卢文岩博士受邀分享《DPU——连接算…...

2024年上半年软件设计师试题及答案(回忆版)
目录 基础知识选择题案例题1.缺陷识别的数据流图2.球队、球员、比赛记录的数据库题3.用户、老师、学生、课程用例图4.算法题5.程序设计题基础知识选择题 树的节点,度为4的有4个,度为3的有8个,度为2个有6个,度为1的有10个,问有几个叶子结点 二位数组,一个元素2个字节,A0…...

QGIS使用python代码导出给定坐标图片
代码基于https://blog.csdn.net/x572722344/article/details/108121230进行修改,代码在QGIS内部编译器运行 # -*- coding: utf-8 -*- from osgeo import ogr# 像素[高, 宽] px_geosize [2.645859085290482, 2.6458015267176016]# 待裁剪影像的坐标范围[min_x, min…...

看花眼,眼花缭乱的主食冻干到底应该怎么选?靠谱的主食冻干分享
随着科学养猫知识的普及,主食冻干喂养越来越受到养猫人的青睐。主食冻干不仅符合猫咪的饮食天性,还能提供均衡的营养,有助于维护猫咪的口腔和消化系统健康。许多猫主人认识到了主食冻干喂养的诸多益处,计划尝试这种喂养方式&#…...

开源VS闭源:谁更能推动AI技术的普及与发展?
一、引言 在人工智能(AI)技术的浪潮中,开源与闭源两种模式一直并存,并各自在推动AI技术普及与发展上发挥着重要作用。然而,关于哪种模式更能有效地推动AI技术的普及与发展,一直存在着激烈的讨论。本文将深…...

前端面试题日常练-day28 【面试题】
题目 希望这些选择题能够帮助您进行前端面试的准备,答案在文末。 1. 在Vue中,以下哪个选项用于监听组件生命周期钩子函数? a) watch b) computed c) lifecycle d) created 2. 在Vue中,以下哪个选项用于在列表渲染时为每个元素…...

好消息!DolphinScheduler官网集成LLM模型问答AI kapa.ai
不少小伙伴可能发现了,Apache DolphinScheduler官网最近默默上线了kapa.ai作为LLM的问答AI。 集成kapa.ai之后,社区用户可以点击Apache DolphinScheduler官网首页右下角的「Ask AI」模块,在接下来弹出的问答框输入自己的问题,即可…...

【软考】下篇 第19章 大数据架构设计理论与实践
目录 大数据处理系统架构特征Lambda架构Lambda架构介绍Lambda架构实现Lambda架构优缺点Lambda架构与其他架构模式对比 Kappa架构Kappa架构介绍Kappa架构实现Kappa架构优缺点 常见Kappa架构变形(Kappa、混合分析系统)Kappa架构混合分析系统的Kappa架构 La…...

创新指南|降低 TikTok CPA 的 9 项专家策略
企业在 TikTok 上投放广告,往往最想确保获得最佳的投资回报。然而,这往往说起来容易做起来难。您需要了解如何利用不同的营销工具、定位策略和创意执行来实现您的业务目标并提高成本效率。本文将分享 9 个行之有效的策略,助您有效降低 TikTok…...

jmeter服务器性能监控分析工具ServerAgent教程
ServerAgent介绍:支持监控CPU,memory,磁盘,网络等,和JMeter集成,在JMeter的图形界面中,可以实时看到监控的数据,但是,它只能监控硬件资源使用情况。 不能监控应用服务 S…...

工作纪实50-Idea下载项目乱码
下载了公司的一份项目代码,发现是gbk格式的,但是我的日常习惯又是utf-8,下载项目以后全是乱码,一脸懵 借用网友的一张图,如果是一个一个文件这么搞,真的是费劲,好几百个文件! 步骤…...

37. 解数独 - 力扣(LeetCode)
基础知识要求: Java: 方法、for循环、if else语句、数组 Python: 方法、for循环、if else语句、列表 题目: 编写一个程序,通过填充空格来解决数独问题。 数独的解法需 遵循如下规则: 数字 1-9 在每一行…...

使用uniapp编写的微信小程序进行分包
简介: 由于小程序发布的时候每个包最多只能放置2MB的东西,所以把所有的代码资源都放置在一个主包当中不显示,所以就需要进行合理分包,,但是分包后整个小程序最终不能超过20MB。 一般情况下,我习惯将tabba…...

设计模式19——观察者模式
写文章的初心主要是用来帮助自己快速的回忆这个模式该怎么用,主要是下面的UML图可以起到大作用,在你学习过一遍以后可能会遗忘,忘记了不要紧,只要看一眼UML图就能想起来了。同时也请大家多多指教。 观察者模式(Observ…...

C++算术运算和自增自减运算
一 引言 表示运算的符号称为运算符。 算术运算; 比较运算; 逻辑运算; 位运算; 1 算术运算 算术运算包括加、减、乘、除、乘方、指数、对数、三角函数、求余函数,这些都是算术运算。 C中用、-、*、/、%分别表示加、减…...

Python深度学习:【模型系列】一文搞懂Transformer架构的三种注意力机制
文章目录 1. 什么是注意力机制?2. Transformer 的注意力层2.1 注意力机制基础2.2 理解Q,K,V2.3 交叉注意力层2.4 全局自注意力层2.5 因果注意力层3. 位置编码4. 多头注意力机制5. 总结1. 什么是注意力机制? 注意力机制最初受到人类视觉注意力的启发,目的是让模型在处理大…...

微服务架构中Java的应用
在微服务架构中,Java是一种非常常用的编程语言。Java生态系统非常庞大,有许多框架和工具可以用来构建和管理微服务。 以下是一些在微服务架构中使用Java编写的应用程序的示例: Spring Boot和Spring Cloud:Spring Boot是一种用于快…...

【强训笔记】day25
NO.1 思路:哈希质数判断。 代码实现: #include <iostream> #include<string> #include<cmath> using namespace std;bool isprime(int n) {if(n<2) return false;for(int i2;i<sqrt(n);i){if(n%i0) return false;}return true…...

知识产权与标准化
知识产权与标准化 导航 文章目录 知识产权与标准化导航一、知识产权概述二、保护范围与对象三、保护期限四、知识产权归属五、侵权判定六、标准的分类 一、知识产权概述 知识产权:知识产权是指人们就其智力劳动成果所依法享有的专有权利,通常是国家赋予创造者对其…...

【LeetCode:2769. 找出最大的可达成数字 + 模拟】
🚀 算法题 🚀 🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀 🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨ 🌲 作者简介:硕风和炜,…...

编程5年的老哥说:我代码里从来不用锁,谁爱...
技多不压身! 大家好,我是 javapub。 今天一个朋友找我吐槽,说自己平时在工作中几乎用不到需要上锁的场景,就算有也只是并发很小、或者直接从有业务设计上就规避掉了。但一到面试,都是各种锁题,很头疼。 面…...

CogAgent:开创性的VLM在GUI理解和自动化任务中的突破
尽管LLMs如ChatGPT在撰写电子邮件等任务上能够提供帮助,它们在理解和与GUIs交互方面存在挑战,这限制了它们在提高自动化水平方面的潜力。数字世界中的自主代理是许多现代人梦寐以求的理想助手。这些代理能够根据用户输入的任务描述自动完成如在线预订票务…...

C++容器之位集(std::bitset)
目录 1 概述2 使用实例3 接口使用3.1 constructor3.2 count_and_size3.3 test3.4 any3.5 none3.6 all3.7 set3.8 reset3.9 filp3.10 to_string3.11 to_ulong3.12 to_ullong3.13 operators1 概述 位集存储位(只有两个可能值的元素:0或1,true或false,…)。 该类模拟bool…...