【YOLO】解决YOLOX训练时AP为0

训练Coco数据集可查看: YOLOX训练COCO数据集 因xml文件中不存在 difficult 参数导致的 ap=0 可查看:关于xml文件中不存在 difficult 参数导致的ap为0 前段时间被YOLOX刷屏了,各个公众号都在强推,号称:性能超Yolov5,吊打一切YOLO 于是,我满怀期待,下载下源码,准备试一试... 一、问题描述 嗯,没错,遇到了一堆bug,不过好在都解决了,最后训练的时候 好家伙,AP一直为0,上 Github 的 YOLOX 的 Issues 上一搜索,看来遇到同样问题的不止我一个 而且根据有些答复修改,发现也不对,最后陷入沉思... 直到昨天群组里,偶然有人说他成功使用了YOLOX并且进行了部署,我就呆了,告诉了他我训练时AP为0,并询问了他具体使用方法,当然得到的答复并没有真正解决我的问题... 二、发现问题 于是今早我又开始调试,检查,我突然想到是不是 数据加载出了问题 结果发现,还真就是这块儿导致的问题 三、解决问题 首先,保证自定义VOC格式数据是否正确 ├─datasets │ └─VOCdevkit │ └─VOC2007 │ ├─Annotations │ ├─ImageSets │ │ └─Main │ └─JPEGImages 在 Main 文件夹下一定有对应的 train.txt 和 val.txt 然后,对yolox/data/datasets/voc_classes.py进行修改,修改成你训练数据的类别(保险起见,最好每一个类别后都加上 ,): VOC_CLASSES = ( "panda", "tiger", ) 接着修改yolox/exp/yolox_base.py (这里应该也可以不用修改,因为后面的exps/example/yolox_voc/yolox_voc_s.py会对self.num_classes进行重载) 将self.num_classes修改为自己的类别数 self.num_classes = 2 (我的数据集是 2) 你还可以修改 self.inputsize, self.random_size 改变训练尺寸大小 你还可以修改 self.

【论文速览】图像分割领域的通用大模型SegGPT - Segmenting Everything in Context

文章目录 研究背景解决思路PainterSegGPT 实验效果(部分)思考参考资料 代码地址:https://github.com/baaivision/Painter Demo地址:https://huggingface.co/spaces/BAAI/SegGPT 研究背景 图像分割一直是计算机视觉领域的一项基础研究问题,在深度学习时代得到了迅猛发展,对于不同的分割子问题,涌现了很多又快又好的算法。但这些方法都是针对具体的子任务进行设计的,比如前景分割(foreground segmentation)、交互式分割(interactive segmentation)、语义分割(semantic segmentation)、实例分割(instance segmentation)以及全景分割(panoptic segmentation)。 交互式分割是一种图像处理技术,它允许用户通过进行正/负点击来提取目标掩模 不同子任务的分割模型有着其特殊的任务需求、分割类别、分割细粒度、数据类型等,这意味着要针对具体的问题进行模型的设计与训练。而该论文的目标就是提出一个模型,它能够解决所有的分割任务。如下图所示,该论文提出了SegGPT模型,即只用一个模型就能处理任何的上下文分割问题(segmenting everything in context)。 SegGPT全称是segment everything with a generalist Painter, 其中Painter是该团队的另一项工作,用上下文训练框架进行各项视觉任务(下节会对Painter进行简单介绍) 橘色的box表示对应的prompt图像与掩码,蓝色框为模型针对输入图像得到的结果。可以看到,SegGPT能够处理任意的物体分割(红色球、所有球体、阴影、上表面和物体轮廓等),多部分分割(自由女神像的特殊部分),彩虹分割、视频分割以及用可学习的prompt tuning进行闭集语义分割(close set semantic segmentation)。 解决思路 Painter Images Speak in Images: A Generalist Painter for In-Context Visual Learning 这里先介绍SegGPT基于的前置工作"Painter",Painter是该团队在CVPR2023年发布的一个通用的视觉大模型。它希望能够像NLP领域一种,基于预训练的大模型,通过设计不同的prompt来完成不同的任务。但与NLP不同,视觉任务的输出空间差异非常大,哪怕都是稠密预测任务【Painter主要基于稠密预测领域】,语义分割和深度估计的输出形式也是不一样的(一个是分类/另一个是回归)。其次,哪怕能够统一输出形式,如何设计prompt也是一个面临的问题。 为了解决这两个问题,Painter首先将输出空间统一成连续的输出图像表示(输出RGB图像),比如深度估计将0-10映射到0-255之间向下取整,语义分割的类别映射到具体的RGB值。 论文中,Painter统一了语义分割、深度估计、实例分割、关键点检测、图像去噪、图像去雨、图像增强七项任务(在in-domain和out-of-domain数据集上都有着较好效果) 为了让模型能够根据不同的prompt执行不同的任务,Painter在训练时会拼接两组图像,然后进行"masked image modeling"。具体来说:在输入时选择同域同任务下的两组图像进行拼接(每组图像包括输入图像和它对应的任务输出),然后进行如下所示的掩码重构学习(类似simMiM)。 在推理阶段,给定prompt( p r o m p t i n , p r o m p t o u t prompt_{in},prompt_{out} promptin​,promptout​)、测试图像( y i n y_{in} yin​),将它们和mask一起组合送入模型即可,如第一个大图所示,Painter能够根据不同的prompt来执行不同的任务。

【JAVASCRIPT】去除内容中所有HTML标签

function getHtmlText(val) { if (val != null && val != "") { var re1 = new RegExp("<.+?>|&.+?;", "g"); //匹配html标签的正则表达式,"g"是搜索匹配多个符合的内容 var msg = val.replace(re1, ""); //执行替换成空字符 msg = msg.replace(/\s/g, ""); //去掉所有的空格(中文空格、英文空格都会被替换) msg = msg.replace(/[\r\n]/g, ""); //去掉所有的换行符 return msg.substr(0, 100); //获文本文字内容的前100个字符 } else return '' } //调用 getHtmlText(html)

Mac版下载安装jdk教程

1.JDK下载网址https://www.oracle.com/java/technologies/downloads/ 下载选择macOS成功后直接安装根据指示安装即可 2.打开终端执行命令: java -version可查看版本 ava -version java version "1.8.0_361" Java(TM) SE Runtime Environment (build 1.8.0_361-b09) Java HotSpot(TM) 64-Bit Server VM (build 25.361-b09, mixed mode) 3.查看安装的路径:/usr/libexec/java_home -V /usr/libexec/java_home -V Matching Java Virtual Machines (2): 1.8.361.09 (x86_64) "Oracle Corporation" - "Java" /Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home 1.8.0_361 (x86_64) "Oracle Corporation" - "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0_361.jdk/Contents/Home /Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home 4.创建设置环境文件:touch .bash_profile(如果有了该文件就不用创建) 5.打开设置环境文件:open -e .bash_profile 6.设置环境变量 JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_361.jdk/Contents/Home(文件位置) PATH=$JAVA_HOME/bin:$PATH:. CLASSPATH=$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar:. export JAVA_HOME export PATH export CLASSPATH 7.执行保存环境变量:source .

React+antd表单校验

React使用ant-design进行Form表单校验问题 关键字:React、Form表单校验、antd V4.18.5 V4版本最新校验规则写法 出现的错误 v4版本的antd在使用validator去设置自定义校验规格会提示警告:callback已经弃用 // 编辑最大值规则 const maxValidators = (_, value, callback) => { if (maxCount >= minCount || minCount === null) { // return Promise.resolve('') callback && callback('') } else { // return Promise.reject('不得小于最小值') callback && callback('不得小于最小值') } }; 解决方案1 校验时返回Promise对象 // 编辑最大值规则 const maxValidators = (_, value, callback) => { if (maxCount >= minCount || minCount === null) { return Promise.resolve('') } else { return Promise.

前端rem适配(自适应布局)

前言 在开发过程中,前端会存在多种不同的适配方案,如自适应布局,响应式布局。 自适应布局:在不同设备,不同视口宽度的情况下,让页面显示效果相同。响应式布局:在不同设备,不同视口宽度的情况下,让页面显示不同的效果,如手机端和PC端的不同效果。 在自适应布局中,em、rem是目前常用的适配手段,接下来主要探讨使用rem进行自适应适配的方案。 一、场景 已知设计图宽度是1920*1080,现需要对不同终端,不同屏幕大小(如1920*1080 125%,1920*1080 100% ,2560*1600 125%,3000*2000 200&本人电脑)进行适配。 二、计算 模糊计算 一般在使用rem做自适应布局中,会首先未根节点设置一个数值( html: { font-size: 62.5% } ); 其计算过程如下: 1. 首先大多数浏览器的默认字体大小都是16px;根据rem计算原则得到此时的rem为 1rem = 根节点字体大小 = 16px 2. 为了方便计算,此时想把 1rem = 10px,之后的开发中设置125px可以直接转化成12.5rem html { font-size: 62.5% } ( 10px / 16px ) 3. 所以此时 1rem = 16px * 62.5%(10px / 16px) = 10px 精确计算 开发之前,先对照设计图计算并设置出rem const setRem = () => { const reScreenSize = (wid) => { // 当设备宽度小于1400px时,不在改变rem的值 if (wid <= 1400) return; let w = document.

onnx报错问题

用onnxruntime报错: onnxruntime.capi.onnxruntime_pybind11_state.InvalidArgument: [ONNXRuntimeError] : 2 : INVALID_ARGUMENT : Failed to load model with error: Unknown model file format version. 安装了onnx和onnxruntime之后还是报错,upgrade到最新版本还是报错。 发现是因为之前导出的.onnx模型和现在的版本不匹配,所以需要重新export一下,结果又报下面的错: ONNX: export failure ❌ 0.0s: Unsupported ONNX opset version: 17 这个是因为opset的版本问题,把export时默认的17改成11就可以了。 python3 export.py --include onnx --weight /root/yolov5/runs/train-cls/exp4/weights/best.pt --opset 11 另外记得export的时候要指定imgsz,不然就是默认的640,之后用的时候就要匹配。 我没有原始pt文件,我只有onnx文件,所以没办法重新export,运行报错: onnxruntime.capi.onnxruntime_pybind11_state.InvalidGraph: [ONNXRuntimeError] : 10 : INVALID_GRAPH : This is an invalid model. Error in Node:Identity_0 : No Op registered for Identity with domain_version of 13 可以通过下面的代码查看支持的opset version

Linux 开启防火墙和指定端口

1、开启防火墙 systemctl start firewalld 2、开放指定端口 firewall-cmd --zone=public --add-port=1935/tcp --permanent 命令含义: –zone #作用域 –add-port=1935/tcp #添加端口,格式为:端口/通讯协议 –permanent #永久生效,没有此参数重启后失效 ​ 3、重启防火墙 firewall-cmd --reload ​ 4、查看端口号 netstat -ntlp //查看当前所有tcp端口· ​ 例: netstat -ntulp |grep 1935 //查看所有1935端口使用情况·

yolov5详解与改进

https://github.com/z1069614715/objectdetection_script YOLOV5改进-Optimal Transport Assignment Optimal Transport Assignment(OTA)是YOLOv5中的一个改进,它是一种更优的目标检测框架,可以在保证检测精度的同时,大幅提升检测速度。 在传统的目标检测框架中,通常采用的是匈牙利算法(Hungarian Algorithm)进行目标与检测框的匹配。这种算法虽然能够找到最优匹配,但是在实际应用中,由于匹配的计算量过大,往往会导致检测速度过慢。 OTA算法通过引入一种新的目标与检测框之间的距离度量方式,可以在不增加计算量的情况下,更快速地进行目标与检测框的匹配。具体来说,OTA算法将目标与检测框之间的距离转换为一个概率分布,然后通过最小化两个概率分布之间的Wasserstein距离的方式,进行目标与检测框的匹配。由于Wasserstein距离的计算量较小,因此OTA算法可以大幅提升检测速度。 除了加速检测速度,OTA算法还可以提高检测精度。传统的匈牙利算法可能会将一些不准确的匹配作为最优匹配,从而导致检测精度下降。OTA算法通过最小化两个概率分布之间的Wasserstein距离,在一定程度上可以避免这种情况的发生,提高了检测精度。 总的来说,OTA算法是YOLOv5中的一个重要改进,它通过引入一种新的目标与检测框之间的距离度量方式,可以在不增加计算量的情况下,更快速地进行目标与检测框的匹配,提高了检测速度和精度。 下面是OTA算法的代码实现和公式: 公式: 首先,定义两个分布 p p p和 q q q,分别表示目标框和预测框之间的距离分布。则最优的匹配可以表示为如下的问题: min ⁡ T ∈ Ψ E ( i , j ) ∼ T [ d i , j ] \min_{T\in\Psi} \mathbb{E}{(i,j)\sim T}[d{i,j}] T∈Ψmin​E(i,j)∼T[di,j] 其中, d i , j d_{i,j} di,j​表示目标框和预测框之间的距离, T T T表示匹配矩阵, Ψ \Psi Ψ表示所有合法的匹配矩阵集合。 E ( i , j ) ∼ T [ d i , j ] \mathbb{E}{(i,j)\sim T}[d{i,j}] E(i,j)∼T[di,j]表示在匹配矩阵 T T T的约束下,目标框和预测框之间距离的期望值。

数据结构C语言----单链表基本操作

目录 创建单链表1.头插法创建单链表(带头结点&&不带头结点)2.尾插法创建单链表(带头结点&&不带头结点) 按位序插入(带头结点&&不带头结点)单链表指定结点的前插操作(带头结点)按位序删除按值删除(带头结点&&不带头结点) 创建单链表 1.头插法创建单链表(带头结点&&不带头结点) // 带头结点的头插法 LinkList List_HeadInsert(LinkList *L) { LNode *s; int x; *L = (LNode *)malloc(sizeof(LNode)); // 创建头结点 (*L)->next = NULL; // 初始为空链表 scanf("%d", &x); // 输入结点的值 while (x != 9999) { // 输入9999表示结束 s = (LNode *)malloc(sizeof(LNode)); // 创建新结点 s->data = x; s->next = (*L)->next; (*L)->next = s; // 将新结点插入表中,L为头指针 scanf("%d", &x); } return *L; } // 不带头结点的头插法 LinkList List_HeadInsertNo(LinkList *L) { // 初始化链表 LNode *s; // 要插入的节点 int x; // 要插入的元素 *L = (LinkList)malloc(sizeof(LNode)); *L = NULL; scanf("

C语言实现两个数交换的最优方案

C语言实现两个数交换的最优方案 实现方式一:通过指针变量,异或处理 #include <stdio.h> void swap(int *x, int *y) { int temp = (*x) ^ (*y); //设a为临时变量,存储异或值 *y = temp ^ (*y); //相当于b=a *x = temp ^ (*x); //相当于a=b } void main() { int a = 33; int b = 66; int *pa = &a; int *pb = &b; swap(pa, pb); printf("a= %d ,b = %d \n", a, b); } 实现方式二: 直接异或运算 #include <stdio.h> void main() { int a = 33; int b = 66; a = a ^ b ^ a; //也可以不设置临时变量,因为异或值没有发生变化 b = a ^ b ^ b; printf("

遗传算法为主的多目标优化算法来优化一个复杂的机器学习模型的多个超参数

这个实例中,我们将使用遗传算法为主的多目标优化算法来优化一个复杂的机器学习模型的多个超参数,以获得更好的分类性能。 我们的目标是使用遗传算法为主的多目标优化算法来优化支持向量机(SVM)的多个超参数,包括 C、gamma 和 kernel。我们的优化目标是最大化 SVM 模型在测试集上的准确度,并最小化 SVM 模型的复杂度。同时,我们需要满足 SVM 模型的计算时间不能超过一个预定的阈值。 首先,我们需要准备一个用于 SVM 分类的数据集。在这个实例中,我们将使用 Scikit-learn 库中的鸢尾花数据集。我们可以使用以下代码来加载数据集: from sklearn.datasets import load_iris iris = load_iris() X = iris.data y = iris.target 接下来,我们需要定义一个适应度函数来评估每个个体的优化性能。在这个问题中,我们使用 SVM 对数据进行分类,并计算模型的准确度和复杂度。同时,我们还需要惩罚超时的个体。下面是适应度函数的代码实现: from sklearn.model_selection import train_test_split from sklearn.svm import SVC import time def fitness(individual): C, gamma, kernel = individual start = time.time() X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42) clf = SVC(C=C, gamma=gamma, kernel=kernel) clf.fit(X_train, y_train) end = time.

go语言的sort库的使用(go语言如何进行排序)

go语言的sort库的使用(go语言如何进行排序) 首先没有编译器的可以通过这个网址进行敲代码:Lightly 简介 sort包是Go语言标准库中的一个包,它提供了对切片进行排序的函数。可以使用sort包将任何可比较的类型(例如整数、浮点数和字符串)的切片排序。 下面是sort包中两个主要的排序函数: sort.Sort():对一个实现了sort.Interface接口的切片进行原地排序。sort.Stable():对一个实现了sort.Interface接口的切片进行稳定排序(排序结果中元素相等的顺序不会改变)。 为了让一个类型使用sort包进行排序,该类型必须实现sort.Interface接口。这个接口定义了三个方法: Len():返回切片的长度。Swap(i, j int):交换切片中索引为i和j的元素。Less(i, j int) bool:返回索引为i的元素是否应该排在索引为j的元素之前。 例如,如果我们有一个字符串切片需要排序,可以实现以下接口: type StringSlice []string func (s StringSlice) Len() int { return len(s) } func (s StringSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } func (s StringSlice) Less(i, j int) bool { return s[i] < s[j] } 在上面的代码中,我们定义了一个名为StringSlice的新类型,它表示一个字符串类型的切片。然后,我们为该类型实现了sort.Interface接口中定义的三个方法。 // 对字符串切片进行排序 strs := []string{"apple", "orange", "banana", "grape"} sort.Sort(StringSlice(strs)) fmt.Println(strs) // Output: [apple banana grape orange] 在上面的代码中,我们定义了一个名为StringSlice的新类型,它表示一个字符串类型的切片。然后,我们为该类型实现了sort.

js中元素获取的5种方式

<div class="box" id="box1"> <p>段落1</p> <p>段落1</p> <p>段落1</p> <p>段落1</p> 第一个 </div> <div class="box" id="box2"> <p>段落2</p> <p>段落1</p> <p>段落1</p> <p>段落1</p> 第二个 </div> <div class="box" id="box3"> <p>段落3</p> <p>段落1</p> <p>段落1</p> <p>段落1</p> 第三个 </div> 1、通过id获取元素 通过id获取到的元素是唯一的,id的名字是不能重复的 var box1 = document.getElementById('box1'); console.log(box1); 2、H5中新增加的 querySelector获取元素 querySelector只能获取页面中的第一个元素,括号中可以使用选择器 通俗理解:就是样式中的选择器怎么写,括号中就怎么写 var box3 = document.querySelector('.box'); console.log(box3); 通过id获取元素和 querySelector,只能获取一个元素,注意两者之间的区别 3、H5中新增加的querySelectorAll获取元素 var p3 = document.querySelectorAll('div p'); console.log(p3); 4.通过class获取元素 class获取元素也是获取到多个,形成一个数组 var box2 = document.getElementsByClassName('box'); console.log(box2); 5、通过标签名获取元素 标签名获取元素也是获取到多个,形成一个数组 var a1 = document.getElementsByTagName('div') console.log(a1); var box5 = document.

【项目展示】基于Unity3D开发的FPS游戏

介绍 写上一篇文章时翻出的老古董,于是决定录一个时隔两年的“初玩实况”。这个项目也当年游戏设计开发课程的小组大作业,同组同学负责了剧情设计、场景设计搭建、文档等部分,游戏开发的部分则是由我负责。游戏里的各类模型资源、音效等都是找的许多资源包拼凑出来的,程序部分没有依赖插件全部由自己实现。 游戏整体体量不大,单一流程两个关卡,包括步枪、霰弹、火箭筒等5种武器(可以爆头)以及一种普通敌人、一种精英敌人(有出场警告)、一种BOSS(有出场动画),同时也包括了简单的场景交互(可以打爆的油桶)以及关卡隐藏资源等。 展示 射击游戏Demo

Shell倒序打印字符练习

1. 你需要打印一个给定的数字的反序,如输入10572,输出27501,如果没有输入数据,应该抛出 错误和使用脚本说明 #编写脚本文件 <使用shell中rev方法> #!/bin/bash read -p "please input a num:" num if [ -z $num ] then echo "Error! The input cannot be empty." else echo $num > /test01.txt rev /test01.txt fi 2.写出SHELL函数RevertInput,函数必须获取三个参数,然后将三个参数倒序echo打印出来,函 数必须检查参数个数的合法性,如果参数非法,打印”Illegal parameters”,对于下面的输入: RevertInput “this is para1” para2 para3 应该输出:para3 para2 this is para1 #编写脚本文件 #!/bin/bash RevertInput () { if [ ! $# -eq 3 ] then echo "Illegal parameters!" else echo "$3 $2 $1" fi } RevertInput "

KaiwuDB 分布式数据库-介绍

软件简介 KaiwuDB 是浪潮打造的一款分布式数据库产品,具备强一致、高可用分布式架构、分布式水平扩展、高性能、企业级安全等特性,自研的原生分布式存储引擎支持完整 ACID,支持 PostgreSQL 协议访问。同时提供自动化运维、监控告警等配套服务,为用户提供完整的分布式数据库解决方案。 特性 完全去中心化架构 KaiwuDB 集群中各个节点的地位完全对等,同时所有功能封装在一个二进制文件中,可以做到尽量不依赖配置文件直接部署。对外提供标准 SQL 接口,集群中任意节点都可以作为接入节点处理用户的 SQL 请求。 高可用性 支持不停机在线扩容、故障秒级恢复,可跨数据中心和跨地域分布,以应对来自数据中心电源中断或网络中断,以及区域电力故障等问题。 弹性扩展 原生分布式存储引擎与上层数据库实例均支持 EB 级数据弹性扩展,提供可动态无限扩展的存储容量。客户端查询请求可以发送到集群任意节点,且每个查询可独立并发执行(无论有无冲突),意味着集群的吞吐能力可以随着节点数的增加线性提升。 强一致性 支持分布式事务 ACID,使用高效的无锁分布式事务保障 ACID 语义;Raft 算法保证分布式多副本强一致、外部读写一致。 云原生 提供托管、Docker、二进制进程多种运行态,扩展运维管理容易;逻辑集中,物理分布,资源透明分片。托管服务提供自动故障恢复,自动拓展功能。 安全可靠 支持权限管理、数据库审计、加密、VPC 协同等功能;可靠性上,数据库引擎原生支持多数据中心容灾机制,无单点故障。多租户隔离,以平台化形式对上层应用与微服务提供数据访问能力,不同微服务的底层数据逻辑隔离。 易于使用 安装包仅为一个二进制文件,将所有功能、插件、工具都融合其中,极易部署管理。通过管理控制台可在几分钟内启动并投入生产的数据库。控制台提供常见的数据库运维操作,提供常见的系统监控数据和性能分析数据。 协议级兼容 高度兼容 postgre 通信协议、语法及客户端。对已有应用程序,无需应用程序代码调整,即可无缝切换。 多元业务场景支持 同时支持联机事务处理 (Online Transactional Processing ,OLTP) 及联机分析处理 (Online Analytical Processing ,OLAP) ,帮助用户基于一套系统同时承载在线交易及数据分析业务,可广泛应用于工业物联网、商业智能分析、电商推荐系统、搜索引擎等业务场景。 成熟稳定 存储节点为浪潮云存储产品,由浪潮成熟度和稳定性得到保证,KaiwuDB 团队专注于分布式数据库研发,提优质定的企业级支持。 应用场景 ● 金融级商业数据库应用场景 ​ KaiwuDB 数据库系统分布式数据库基于通用 x86 服务器便可轻松支撑起上亿的用户访问,并且完整支持分布式事务、强一致、多副本高可用,满足分布式核心交易业务需求完全基于云计算理念实现,同时支持云服务模式与独立部署,既具有云架构的敏捷与弹性,也兼顾了独立性与高性能,既可满足传统核心应用对安全与性能的要求,又能轻松实现业务上云。 ● 多地部署异地多活场景 ​KaiwuDB 数据库系统具有原生数据强一致性的独特优势,支持统一部署,数据地理分区,高延迟网络条件下的数据一致性技术、分布式的多副本强一致,可以满足“中央-地方”多级多地部署需求。分部和各地分支机构在各自数据中心的集群进行常规业务操作,总部通过统一逻辑视图进行数据透明汇总和分析。 ● 海量数据存储访问场景 ​KaiwuDB 数据库系统支持节点快速弹性完成垂直、水平扩展缩容,存储容量最大到 4EB,完全满足用户的海量数据存储和查询要求。可以广泛应用于工业远程监控和远程控制、智慧城市的延展、智能家居、车联网、充电桩加油站等传感监控设备多、采样率高、数据上报存储数据量大的场景。

分布式数据库SQL引擎之解析器

SQL引擎是 KaiwuDB 核心系统之一,主要包括三部分:解析器、优化器、执行器,它处理客户端传来的命令,解析器将命令解析编译成数据库能识别运行的命令,优化器将命令进行优化,优化的优劣直接影响数据库的性能,执行器最后进行执行命令。 一条SQL语句的生命周期: 图1 SQL执行流程 从图1可以看出,一条语句在数据库中的执行过程如下: (1)数据库接收客户端传来的语句文本; (2)经过词法解析得到一组词条; (3)词条经过语法解析得到语法树(Abstract Syntax Tree,AST); (4)AST经过语义解析得到表达式供优化器使用; (5)经过规则优化(Rule-Based Optimization,RBO),主要是做查询的重写,如表达式化简,谓词下推等; (6)再经过代价优化(Cost-Based Optimization,CBO)得到最优的查询表达式,此过程主要是列举所有路径并计算各路径的代价,选择代价最小的路径作为计划构建的基础; (7)构建逻辑计划再构建物理计划; (8)执行器执行计划; (9)返回结果。 SQL解析器: 所有进入数据库的语句都需要经过解析的过程,才能被数据库所识别,解析器主要包括三部分:词法解析、语法解析、语义解析。 词法解析: 词法解析的任务是从左到右一个字符一个字符地读入解析程序,对字符流进行扫描然后根据构词规则识别字符并切割成一个个词条,切词的规则是遇到空格进行切割,遇到“;”结束词法解析。 Example: SELECT a FROM test WHERE a > 4; 通过词法解析后,该SQL语句被切割成以下词条: 语法解析: 语法分析的任务是在词法分析的结果上将词条序列组合成各类语法短句,组成的短句将与既定的语法规则进行匹配,若匹配成功则生成对应的抽象语法树(Abstract Syntax Tree,AST),否则报语法错误。 Example: 存在以下simple_select_clause的既定规则: 图2 simple_select_clause语法规则 图2规则中红色标记的都是终结符,一般是大写的关键字以及符号等,小写的是非终结符,一般用作规则的命名。 进行语法解析时,会将词法解析生成的词条逐一移进,每移进一个词条都会进行匹配规则的操作,如果匹配得上就会进行规约操作,否则继续进行移进,直到所有词条移进完毕且成功规约则解析完毕,生成对应的语法树。 例如词法解析得到词条如下: 语法解析先移进SELECT词条,无规约且剩余词条,继续移进;移进词条a,a可以规约成tartet_list,进行规约操作,用tartet_list替代词条a,还剩余词条,继续移进;移进FROM,无规约且剩余词条,继续移进;移进test,test可以规约成from_list,进行规约操作,用from_list替代词条test,然后from和from_list还可以规约成from_clause,继续进行规约操作,还剩余词条,继续移进;移进WHERE,无规约且剩余词条,继续移进;移进a,a可以规约成expr,用expr替代a,剩余词条,继续移进;继续移进>,无规约且剩余词条,继续移进;继续移进4,4可以规约成expr,用expr替代4,此时expr>expr可以规约成a_expr,用a_expr替代expr>expr,然后where和a_expr规约成where_clause,最终SELECT和target_list和from_clause和where_clause规约成simple_select_clause,至此解析完毕,而后生成对应的语法树。 语义解析: 语义分析的任务是对语法解析得到的语法树(AST)进行有效性审查,如表、列、列类型、函数、表达式等进行检查。 例如查询语句:SELECT a FROM test WHERE a > 4; 针对上面的例子将会审查三个地方: 1、from_clause;审查语句中的表test是否存在; 2、target_list;审查a列是否是from子句某个关系或视图的属性; 3、where_clause;审查a列是否是from子句某个关系或视图的属性且a列的类型是否能进行>4的比较操作。 语义解析结束后会生成对应表达式供优化器使用。

多个confirm弹窗

async openHTML() { let arr = ['1', '2', '3'] for await (const item of arr) { console.log(item) this.$confirm(item, '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { this.$message({ type: 'success', message: '删除成功!' }); }).catch(() => { this.$message({ type: 'info', message: '已取消删除' }); }); } 这种情况下 不能控制弹窗取消后 后面的弹窗不显示 如果不需要这部分功能还可以这样写。 否则 ,用递归写法: abc(arr){ this.count++ if(this.count<arr.length){ this.$confirm(arr[this.count], '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { this.abc(arr) }).catch(() => {

IDEA根据wsdl生成java代码(Generate Java Code from WSDL)以及乱码问题的解决

目录 一、根据wsdl生成java代码 1、创建待存放java代码的目录,点击“帮助”=>“查找操作”,打开查找窗口; 2、输入wsdl并查找,点击“从WSDL生成Java代码”,打开新的窗口; 3、选择wsdl文件,并选择输出路径,点击确定即可生成java代码。 二、解决乱码问题 乱码原因: 解决方法: 1、将乱码的文件夹设置为GBK,保证文件夹下的文件再打开不会显示乱码: 2、选择某个GBK文件,点击IDEA右下角GBK,改为UTF-8,在弹出框里选择“转换”; 3、将文件夹下所有文件改为UTF-8之后,再在“设置”里将文件夹的文件编码由GBK改为UTF-8,即达到将该目录下全部GBK文件转为UTF-8文件,,并且用IDEA打开也不再乱码。 4、可借助EmEditor文本编辑器批量将GBK转为UTF-8,使用EmEditor打开全部待转编码的文件,然后点击“文件”=>“以指定编码全部保存”。 5、终极解决办法: 6、wsimport.exe常用命令组合 一、根据wsdl生成java代码 看了很多博文都是在Tool里有个WebServices,我的IDEA是2021版,工具菜单下没有WebServices。好像是较新的版本都没有。 不用太纠结这个问题,参考以下步骤可实现相同功能: 1、创建待存放java代码的目录,点击“帮助”=>“查找操作”,打开查找窗口; 2、输入wsdl并查找,点击“从WSDL生成Java代码”,打开新的窗口; 3、选择wsdl文件,并选择输出路径,点击确定即可生成java代码。 二、解决乱码问题 乱码原因: 乱码是因为文件编码不一致,Win10默认字符编码为936(GBK),导致IDEA根据wsdl生成的java文件编码为GBK,而如果IDEA设置了全局/项目编码为UTF-8,这时打开文件就会乱码。 解决方法: 可修改IDEA配置,单独将乱码文件配置为GBK也能解决乱码问题,但是文件太多时很不方便。可借助EmEditor文本编辑器统一将所有选中的GBK文件转为UTF-8。 具体解决步骤如下: 1、将乱码的文件夹设置为GBK,保证文件夹下的文件再打开不会显示乱码: 2、选择某个GBK文件,点击IDEA右下角GBK,改为UTF-8,在弹出框里选择“转换”; 3、将文件夹下所有文件改为UTF-8之后,再在“设置”里将文件夹的文件编码由GBK改为UTF-8,即达到将该目录下全部GBK文件转为UTF-8文件,,并且用IDEA打开也不再乱码。 4、可借助EmEditor文本编辑器批量将GBK转为UTF-8,使用EmEditor打开全部待转编码的文件,然后点击“文件”=>“以指定编码全部保存”。 5、终极解决办法: 修改Windwos系统默认字符编码,由GBK改为UTF-8。 参考地址: win10怎么设置系统默认编码为UTF-8 理想很丰满,现实很骨感,改了系统默认编码后根据wsdl生成的java代码还是有乱码。 继续往下看... 继续研究,IDEA默认使用的生成工具,就是JDK文件夹bin目录下“wsimport.exe”工具。 这个wsimport.exe工具生成代码时,不是取的系统当前字符编码,而是统一默认为GBK(估计和当前系统语言还是有一定关系的,至少知道是简体中文)。 所以要想自动生成的文件编码为UTF-8,需要在执行命令时,加上字符集。 打开命令提示符窗口,cd进入wsimport.exe所在路径,执行如下命令: wsimport -encoding utf-8 -keep -s D:\temp -p com.lawyer.user -verbose http://服务地址?wsdl 参数说明: -encoding : 指定编码格式 -keep:是否生成java源文件 -d:指定.class文件的输出目录 -s:指定.java文件的输出目录, 此目录必须存在 -p:定义生成类的包名,不定义的话有默认包名 -verbose:在控制台显示输出信息 -b:指定jaxws/jaxb绑定文件或额外的schemas -extension:使用扩展来支持SOAP1.2 6、wsimport.exe常用命令组合: wsimport -encoding utf-8 -s D:\demo -p com.

Python集合中元素是否可重复?

Python集合中元素是否可重复?答案是不可以!在集合中,每一个元素都只能有一个,意思就是说集合中的元素是不能出现重复的情况。 Python中集合中的元素是不可以重复的! 集合定义: 集合set,是一个无序的不重复元素序列。 创建: 可以使用大括号{}或者set()函数创建集合。 注意:创建一个空集合必须用set()而不是{},因为{}是用来创建一个空字典。 格式: parame = {value01,value02,…} 或者 set(value) 举例: jihe = {1,2,3,4,5} #与字典看上去类似,但是是不一样的。字典是dict1 = {key:value,key2:value2,}需要key 添加元素: 使用set.add()方法 例: set1 = {1,3} set1.add(2)print(set1)

ICLR 2022: Perceiver IO 结构化输入和输出的通用架构

Perceiver IO A General Architecture for Structured Inputs & Outputs 2107.14795.pdf (arxiv.org) deepmind-research/perceiver at master · deepmind/deepmind-research · GitHub Abstract A central goal of machine learning is the development of systems that can solve many problems in as many data domains as possible. Current architectures, however, cannot be applied beyond a small set of stereotyped settings, as they bake in domain & task assumptions or scale poorly to large inputs or outputs.

UDP实现服务器和客户端通信

目录 UDP通信介绍 UDP通信流程图 代码实现UDP相互通信 server(服务器) client(客户端) 结果演示 UDP通信介绍 UDP (User Datagram Protocol) 是一种面向无连接的传输层协议,它不保证数据包的可靠性,但具有传输速度快的优点。在UDP通信中,数据包被封装在UDP数据报中,每个数据报包括目标端口号和源端口号,不需要在每个数据包中都建立连接或断开连接。 UDP通信的工作方式与TCP通信不同。在TCP通信中,客户端和服务器之间需要先建立连接,然后才能传输数据。而在UDP通信中,客户端和服务器可以直接发送数据包,不需要事先建立连接。这使得UDP通信更加简单和快速,但也使得它更容易受到数据包丢失、重复和乱序等问题的影响。 UDP通信通常用于那些对可靠性要求不高的应用程序,例如DNS查询、视频和音频流传输等。它也常用于实现一些实时性较高的应用程序,因为它能够在较短的时间内传输数据包。 UDP通信流程图 代码实现UDP相互通信 server(服务器) // 引入所需头文件 #include <stdio.h> #include <sys/types.h> #include <netinet/in.h> #include <sys/socket.h> #include <arpa/inet.h> #include <unistd.h> #include <string.h> #include <stdlib.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/types.h> #include <sys/socket.h> int main(int argc, char const *argv[]) { int sockfd = socket(AF_INET, SOCK_DGRAM, 0); // 创建UDP数据包套接字 if (sockfd < 0) // 如果创建失败则打印错误信息并退出程序 { perror("socket err"); return -1; } struct sockaddr_in saddr, caddr; // 创建两个IPV4套接字地址结构体 saddr.

element plus 变量css css :root 用法

场景: 用到技术: vue vite element plus 我这里是 修改 element plus css 需要用到 这里先说 root 变量用法及声明。 1. 静态文件 创建一个 public.css 文件 :root { --hoverc: #fe4800; --hoverbgc: #fef8f5; } 2. App.vue 入口文件引入 public.css <template> <div>App.vue文件</div> </template> <script> export default { } </script> <style lang="scss"> // 引入 css @import url(./assets/css/public.css); </style> 3. 使用变量 <template> <div class="use"></div> </template> <style lang="scss" scoped> // 使用 --hoverc .use {background: var(--hoverc); width: 100px; height: 100px; } </style> 效果图: 接下来就可以 修改 element plus css 的变量了 先贴代码 <style lang="

【uni-app】vue组件无法使用uni-app页面生命周期函数(如onLoad、onShow)

问题:工作中在写uni-app页面时,有一整个页面是写成了一个组件,在主页中引用这个组件,发现组件页面无法使用uni-app页面的生命周期函数(如onLoad、onShow) 分析:组件页面只能使用vue生命周期函数 解决方案: 子组件上添加ref,父组件通过ref在页面相对应的生命周期函数中调用子组件的方法(如刷新列表数据)

卷积输出大小的计算公式

定义 m m m: feature map的大小 k k k: kernel_size大小 s s s: stride大小 p p p: padding大小 公式 m ′ = ⌊ m − k + 2 × p s + 1 ⌋ m'=\lfloor \frac{m-k+2\times p}{s}+1 \rfloor m′=⌊sm−k+2×p​+1⌋ 例如,如果是kenel_size = 3 =3 =3的卷积,要想feature_map的尺寸减半,那么当stride = 2 =2 =2时,padding是多少呢?则需要令 ⌊ m − 3 + 2 × p 2 + 1 ⌋ = m 2 \lfloor \frac{m-3+2\times p}{2}+1 \rfloor=\frac{m}{2} ⌊2m−3+2×p​+1⌋=2m​,又因为有 ⌊ m − 3 + 2 × p 2 + 1 ⌋ = ⌊ m − 3 + 2 × p + 2 2 ⌋ = ⌊ m − 1 + 2 × p 2 ⌋ \lfloor \frac{m-3+2\times p}{2}+1 \rfloor=\lfloor \frac{m-3+2\times p+2}{2}\rfloor=\lfloor \frac{m-1+2\times p}{2}\rfloor ⌊2m−3+2×p​+1⌋=⌊2m−3+2×p+2​⌋=⌊2m−1+2×p​⌋

智能优化算法之遗传算法

该算法已被很多篇文章讲解,本文将会去除很多较简单的内容,挑选认为重点核心部分进行讲述,内容中有属于信息的收集整理部分,也有属于自己理解的部分。 1、遗传算法概述 遗传算法是一类借鉴生物界的进化规律演化而来的随机化搜索方法。它是由美国的J.Holland教授1975年首先提出,其主要特点是直接对结构对象进行操作,不存在求导和函数连续性的限定;具有内在的隐并行性和更好的全局寻优能力;采用概率化的寻优方法,能自动获取和指导优化的搜索空间,自适应地调整搜索方向,不需要确定的规则。遗传算法的这些性质,已被人们广泛地应用于组合优化、机器学习、信号处理、自适应控制和人工生命等领域。它是现代有关智能计算中的关键技术之一。 2、遗传算法的基本操作 遗传算法有三个基本操作: 选择( Selection) 、 交叉( Crossover) 和变异( Mutation) • 选择。 从当前种群中选出优良的个体, 使它们有机会作为父代种群为下一代种群进行更新迭代。 根据各个个体的适应度值, 按照一定的规则或方法从上一代群体中选择出一些优良的个体遗传到下一代种群中。 选择的依据是适应性强的个体为下一代贡献一个或多个后代的概率大。 • 交叉。 通过交叉操作可以得到新一代个体, 新个体组合了父辈个体的特性。 将群体中的各个个体随机搭配成对, 对每一个个体, 以交叉概率交换它们之间的部分染色体。 • 变异。 对种群中的每一个个体, 以变异概率改变某一个或多个基因座上的基因值为其他的等位基因。 同生物界中一样,变异发生的概率很低, 变异为新个体的产生提供了机会。 3、遗传算法的基本步骤 遗传算法的基本步骤包含了编码、解码、初始种群生成、适应度计算、选择、交叉、变异 1)编码: GA在进行搜索之前先将解空间的解数据表示成遗传空间的基因型串结构数据, 这些串结构数据的不同组合便构成了不同的点。 遗传算法的搜索核心是编码方式(遗传算子)的选择,因此对于遗传算法的研究,其中最常见的内容与方向是遗传算子,遗传算子的选择多样性也导致了算法表现的多样性,常见的选择方式如图所示: 常见的编码方式有:二进制编码、自然数编码、实数编码和树形编码等,常见的编码有二进制编码与自然数编码,很多实际问题如VRP调度问题更多采用自然数编码。(编码方式不赘述,根据模型需要自行选择即可) 2)初始群体的生成:随机产生N个初始串结构数据, 每个串结构数据称为一个个体, N个 个体构成了一个群体。 3)适应度评估:适应度表明个体或解的优劣性。 不同的问题, 适应性函数的定义不同。 4)选择:选择的目的是为了从当前群体中选出优良的个体。 选择体现了达尔文的适者生存原则。 常见的选择方式有: 轮盘赌法Roulette-wheel selection: 轮盘赌选择法是依据个体的适应度值计算每个个体在子代中出现的概率,并按照此概率随机选择个体构成子代种群。轮盘赌选择策略的出发点是适应度值越好的个体被选择的概率越大。 为了计算选择概率,需要用到每个个体i的适应度值: 从给定种群中选出M个个体就等价于旋转M次轮盘,在选择个体前实际上不必对种群中的个体进行排序。 锦标赛选择(Tournament selection) 在锦标赛选择中,从种群中随机采样s个个体(注意:采样是有放回的),然后选择最优的个体进入下一代,只有个体的适应度值优于其他s-1个竞争者时才能赢得锦标赛。注意最差的个体永远不会幸存,而最优的个体在其参与的所有锦标赛中都能获胜。 可以通过改变锦标赛的大小s来改变,对于较大的s值,弱者被选中的机会较小,常见的有二元锦标赛和三元锦标赛等。与适应度值比例选择相比,锦标赛选择由于缺乏随机噪声,同时锦标赛选择也和遗传算法适应度函数的尺度无关。 随机遍历选择(Stochastic-universal selection) 随机遍历选择(SUS)是一种根据给定概率以最小化波动概率的方式选择个体的方法。可以将其认为是一种轮盘赌游戏,在轮盘上有p个等间距的点进行旋转。SUS使用一个随机值在等间隔的空间间隔内选择来选择个体。相比较于适应度比例选择法,该方法中较劣个体也有很好的机会被选择,从而奖励了不公平性。该选择方法是由James Baker提出的,展示了其原理,其中n为要选择的个体数量。随机遍历采样保证了选出的子代,比轮盘赌法更加接近希望得到的结果。 精英选择(Elite selection) 精英选择将一小部分最优的候选解,原封不动的复制到下一代中,这会对性能产生巨大的影响,因为这保证了GA不会浪费时间重新发现以前拒绝的部分解。通过精英主义被保留下来的个体仍然有资格被选为下一代的父代。精英主义也与记忆有关:记住目前找到的最优解。不过精英主义的问题在于会导致GA收敛到局部最优,所以纯粹的精英主义是一场通向最近局部最优的竞争。 5)交叉:交叉操作是遗传算法中最主要的遗传操作。 通过交叉操作可以得到新一代个体, 新个体组合了其父辈个体的特性。 常见的交叉方式有:

JavaScript中var、let、const的区别简要介绍

1.var声明的是函数级作用域,let和const声明的是块级作用域 function myFunc() { var a = 1 } console.log(a) // caught ReferenceError: a is not defined ​ 变量a定义在了函数myFunc里面,当我们企图在函数外面打印变量a时会抛出ReferenceError——引用不存在的变量。 function myFunc() { let a = 1 const a1 = 1 } console.log(a) // caught ReferenceError: a is not defined console.log(a1) // caught ReferenceError: a1 is not defined if(true) { let b = 1 const b1 = 1 } console.log(b) // caught ReferenceError: b is not defined console.log(b1) // caught ReferenceError: b1 is not defined while(true) { let c = 1 const c2 = 1 break } console.

在 Amazon SageMaker 上玩转 Stable Diffusion: 基于 Dreambooth 的模型微调

本文将以 Stable Diffusion Quick Kit 为例,详细讲解如何利用 Dreambooth 对 Stable Diffusion 模型进行微调,包括基础的 Stable Diffusion 模型微调知识,Dreambooth 微调介绍,并且使用 Quick Kit 通过一个 demo 演示微调效果。 01 Stable Diffusion 模型微调 目前 Stable Diffusion 模型微调主要有4种方式:Dreambooth、LoRA (Low-Rank Adaptation of Large Language Models)、Textual Inversion、Hypernetworks。 它们的区别大致如下: Textual Inversion (也称为 Embedding),它实际上并没有修改原始的 Diffusion 模型, 而是通过深度学习找到了和你想要的形象一致的角色形象特征参数,通过这个小模型保存下来。这意味着,如果原模型里面这方面的训练缺失的,其实你很难通过嵌入让它“学会”,它并不能教会 Diffusion 模型渲染其没有见过的图像内容。 Dreambooth 是对整个神经网络所有层权重进行调整,会将输入的图像训练进 Stable Diffusion 模型,它的本质是先复制了源模型,在源模型的基础上做了微调(fine tunning)并独立形成了一个新模型,在它的基本上可以做任何事情。缺点是,训练它需要大量 VRAM,目前经过调优后可以在 16GB 显存下完成训练。 LoRA 也是使用少量图片,但是它是训练单独的特定网络层的权重,是向原有的模型中插入新的网络层,这样就避免了去修改原有的模型参数,从而避免将整个模型进行拷贝的情况,同时其也优化了插入层的参数量,最终实现了一种很轻量化的模型调校方法。 LoRA 生成的模型较小、训练速度快,推理时需要 LoRA 模型+基础模型,LoRA 模型会替换基础模型的特定网络层,所以它的效果会依赖基础模型。 Hypernetworks 的训练原理与 LoRA 差不多,目前其并没有官方的文档说明,与 LoRA 不同的是,Hypernetwork 是一个单独的神经网络模型,该模型用于输出可以插入到原始 Diffusion 模型的中间层。 因此通过训练,我们将得到一个新的神经网络模型,该模型能够向原始 Diffusion 模型中插入合适的中间层及对应的参数,从而使输出图像与输入指令之间产生关联关系。

hbuilderx获取公众号的code

温馨提示:以下代码可直接复制,改一点东西就可以直接用哦 (欢迎赐教,如果对你有用的话给我点个赞叭~~~) export default { onLaunch: function() { this.toWx() }, methods: { toWx() { // 判断是否是微信内置浏览器 const isWechat = () => { let ua = window.navigator.userAgent.toLowerCase(); return ua.match(/MicroMessenger/i) == 'micromessenger'; } if (isWechat) { // 授权回调 var appid = '填入你的appid'; //获取路径(要在微信内置浏览器打开,或者是用你部署环境的链接打开) let local = window.location.href.split("#")[0]; // 拼接在微信时打开的url let url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + appid + "&redirect_uri=" + encodeURIComponent(local) + "&response_type=code&scope=snsapi_base&state=1#wechat_redirect"; // 从url中截取code let code = this.GetParam(window.location.href.split("#")[0], "code"); if (!code) { window.

ubuntu上安装(或者升级)nodejs,提供两个测试demo

1. 打开终端进行更新 sudo apt update 2. 安装npm sudo apt install npm 3. 安装n sudo npm install n -g 4. 通过n工具安装稳定版本nodejs sudo n stable 5. 查看版本 node -v 提供两个demo文件 一个是app.js文件,文件名为app.js,提供了一个3000的端口号 const express = require('express'); const multer = require('multer'); const app = express(); const storage = multer.diskStorage({ destination: (req, file, cb) => { cb(null, 'uploads/'); }, filename: (req, file, cb) => { cb(null, file.originalname); }, }); const upload = multer({ storage: storage }); // const upload = multer({ dest: 'uploads/' }); app.

匹配yyyy-MM-dd日期格式的正则表达式

^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$ 解释: ^:匹配行的开头 \d{4}:匹配四个数字,表示年份 -:匹配一个横杠 (0[1-9]|1[0-2]):匹配01到12的月份,0开头的要匹配两位数字,1开头的只需匹配一个数字 -:匹配一个横杠 (0[1-9]|[12]\d|3[01]):匹配01到31的日,0开头的要匹配两位数字,1或2开头的第二个数字可匹配0到9,3开头的第二个数字可匹配0或1 $:匹配行的结尾 该正则表达式可以匹配如下格式的日期: 2023-04-11 2023-01-01 2023-12-31 但不能匹配如下格式的日期: 23-04-11(年份不足四位) 2023-4-11(月份或日不足两位) 2023-02-29(二月没有29日)

js红绿灯的实现方法

题目:某个路口的红绿灯,会按照红灯亮5s,黄灯亮2s,绿灯亮3s这样的顺序无限循环。要求:每一秒打印当前在亮的灯 async/await实现 let timer = null const printContent = (str) => { console.log(str) } const sleep = (time, light) => { return new Promise((resolve, reject) => { printContent(light) clearInterval(timer) timer = setInterval(() => { printContent(light) }, 1000) setTimeout(resolve, time) }) } const main = async () => { while (true) { await sleep(5000, '红灯') await sleep(2000, '黄灯') await sleep(3000, '绿灯') clearInterval(timer) } } main() 其中,调用clearInterval(timer)方法时,会停止当前设置的定时器,从而避免了多个定时器同时运行的情况。setTimeout(resolve, time) 用于在经过指定的时间 time 后,解决当前的 Promise

C++Primer第五版 习题答案 第五章 语句(Statements)

练习5.1 什么是空语句?什么时候会用到空语句? 最简单的语句是空语句,空语句只有一个单独的分号: ;//null statement 如果在程序的某个地方,语法上需要一条语句但逻辑上不需要,此时应该使用空语句。 练习5.2 什么是块?什么时候会用到块? 复合语句是指用花括号括起来的语句和声明的序列,复合语句也被称作块。 如果在程序的某个地方,语法上需要一条语句,但是逻辑上需要多条语句,则应使用复合语句。 练习5.3 使用逗号运算符重写1.4.1节的 while 循环,使它不再需要块,观察改写之后的代码可读性提高了还是降低了。 #include <iostream> int main() { int sum = 0, val = 1; while (val <= 10) sum += val, ++val; std::cout << "Sum of 1 to 10 inclusive is " << sum << std::endl; return 0; } 可读性降低了 练习5.4 说明下列例子的含义,如果存在问题,试着修改它。 (a) while (string::iterator iter != s.end()) { /* . . . */ } (b) while (bool status = find(word)) { /* .

RocketMQ 5.0 时代,6 张图带你理解 Proxy!

大家好,今天来聊一聊 RocketMQ 5.0 中的 Proxy。 RocketMQ 5.0 为了更好地拥抱云原生,引入了无状态的 Proxy 模块,新的架构图如下: 引入 Proxy 模块后,Proxy 承担了协议适配、权限管理、消息管理等计算功能,Broker 则更加专注于存储。这样存储和计算相分离,在云原生环境下可以更好地进行资源调度。 1.Proxy 介绍 RocketMQ 5.0 把客户端的部分功能下沉到 Proxy,Proxy 承接了之前 客户端的计算能力,客户端变得更加轻量级。 1.1 NameServer 从上面的架构图可以看到,Producer/Consumer 不再需要注册到 NameServer,这一部分功能下移到了 Proxy,由 Proxy 跟 NameServer 进行交互,比如查询 TopicRouteData。代码如下: public CompletableFuture<QueryRouteResponse> queryRoute(ProxyContext ctx, QueryRouteRequest request) { CompletableFuture<QueryRouteResponse> future = new CompletableFuture<>(); try { //省略部分代码 ProxyTopicRouteData proxyTopicRouteData = this.messagingProcessor.getTopicRouteDataForProxy( ctx, addressList, topicName); List<MessageQueue> messageQueueList = new ArrayList<>(); Map<String, Map<Long, Broker>> brokerMap = buildBrokerMap(proxyTopicRouteData.getBrokerDatas()); TopicMessageType topicMessageType = messagingProcessor.

opencv笔记(三十一)——Mat 矩阵数据类型转换convertTo

一、数据类型转换 1.一般图像文件格式使用的是unsigned 8bits,对应的数据类型有:CV_8UC1、CV_8UC2,CV_8UC3 其中,CV_8UC3表示3通道8位的unsigned char型 float是32位,对应的CvMat数据结构类型是:CV_32FC1,CV_32FC2,CV_32FC3 double是64位,对应的CvMat数据结构类型是:CV_64FC1,CV_64FC2,CV_64FC3, 其中,CV_64FC3表示64位的3通道double型 如果想实现不同数据类型之间的转化,需要使用convertTo函数 2.需要注意的地方:公式里用到了exp函数,图片默认是unsigned char型,范围是0-255,公式中的0.5是0-1范围内的,所以需要将原图像转换为double型,将灰度值都转换为0-1之间,就可以利用该公式进行相应的运算。处理完以后,图像还是CV_64FC3类型,如果直接保存,点开图像会发现,显示全黑,这是因为电脑默认打开图片是CV_8UC3类型的,所以还需要将CV_64FC3乘以255,再转换为CV_8UC3 3.Vec3b---表示每一个Vec3b对象中,可以存储3个char(字符型)数据,比如可以用这样的对象,去存储RGB图像中的一个像素点 Vec3d---表示每一个Vec3d对象中,可以存储3个double(字符型)数据 Vec3f---表示每一个Vec3d对象中,可以存储3个float(字符型)数据 函数 void convertTo( OutputArray m, int rtype, double alpha=1, double beta=0 ) const; 参数 示例 在应用分水岭算法分割图像时,标记图像为32位有符号整型CV_32S变量(以便定义超过255个标签,每个值标记一类物体,如255标记目标,128标记背景,0标记未知等等)构成的矩阵markers,想要将标记图像显示出来必须转换其数据类型。 markers.convertTo(tmp,CV_8U,255,255); 将矩阵markers转换为CV_8U类型的矩阵tmp:tmp(x,y)= markers(x,y)*255+255.这样,将图像做线性变换,使值为-1的像素变为0(-1*255+255=0)。值大于255的像素将赋值为255,这是因为CV32S转换为无符号CV_8U时,应用了饱和度运算。具体应用参看分水岭算法的相关博文。 正常float转8UC1只要 dstmat.convertTo(aa, CV_8U, 255); 就好。 注:Mat保存图片时,只能保存unsigned 8bits类型的格式,其他格式可以显示但不能imwrite 二、IplImage与Mat互转 这是为了把经典的OpenCV图像导成矩阵,第一句创建一个320×240的图像;第二句话把IplImage转成Mat;第三句话把Mat转成IplImage;第四句把Mat转成CvMat。 三、三通道与单通道互转 参考: Mat数据类型 convertTo_c++ mat 转float*_soldier123333的博客-CSDN博客 OpenCV—矩阵数据类型转换cv::convertTo_cv.convertto_iracer的博客-CSDN博客

JavaScript中的filter()方法详解

什么是filter()方法? 在JavaScript中,filter()是一个数组方法,用于从数组中过滤出符合特定条件的元素,并返回一个新数组。 该方法接受一个回调函数作为参数,这个回调函数会被应用于数组的每个元素。回调函数可以返回true或false,如果返回true,则该元素将被包含在新数组中,否则则不包含。该方法不会改变原始数组,而是返回一个新的数组,其中包含符合条件的元素。 filter()方法的语法 filter()方法的语法如下所示: array.filter(callback[, thisArg]) 其中,array是要过滤的数组,callback是一个回调函数,thisArg是可选的参数,用于设置回调函数中的this值。 filter()方法的回调函数 filter()方法的回调函数接受三个参数:当前元素、当前元素的索引和数组本身。其中,当前元素是必需的,而索引和数组是可选的。 回调函数必须返回一个布尔值。如果返回true,则当前元素将包含在新数组中,否则不包含。 使用filter()方法过滤数组 现在,让我们看看如何使用filter()方法过滤一个数组。假设我们有一个数字数组,我们想从中过滤出所有偶数。我们可以使用filter()方法和一个箭头函数来实现,如下所示: const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; const evenNumbers = numbers.filter(number => number % 2 === 0); console.log(evenNumbers); // [2, 4, 6, 8, 10] 在上面的代码中,我们首先定义了一个数字数组numbers。然后,我们使用filter()方法和一个箭头函数来过滤出所有偶数。箭头函数的逻辑是,如果一个数字可以被2整除,则返回true,否则返回false。最后,我们将过滤出的所有偶数存储在一个新数组evenNumbers中,并将其打印到控制台上。 使用filter()方法过滤对象数组 除了数字数组外,我们也可以使用filter()方法过滤对象数组。假设我们有一个对象数组,每个对象都有name和age属性,我们想过滤出所有年龄大于等于18岁的对象。我们可以使用filter()方法和一个箭头函数来实现,如下所示: const people = [ { name: 'Alice', age: 25 }, { name: 'Bob', age: 17 }, { name: 'Charlie', age: 30 }, { name: 'David', age: 16 }, { name: 'Eva', age: 18 } ]; const adults = people.

yolov5改进之加入CBAM,SE,ECA,CA,SimAM,ShuffleAttention,Criss-CrossAttention,CrissCrossAttention多种注意力机制

本文所涉及到的yolov5网络为6.1版本(6.0-6.2均适用) yolov5加入注意力机制模块的三个标准步骤(适用于本文中的任何注意力机制) 1.common.py中加入注意力机制模块 2.yolo.py中增加对应的注意力机制关键字 3.yaml文件中添加相应模块 注:所有注意力机制的添加方法都是一致的,加入注意力机制是否有效的关键在于注意力机制添加的位置,本文提供两种常用常用方法。 注:需要下列所有注意力机制已经改好的代码版本及yaml文件(到手即用),请私聊我(免费) 目录 1.CBAM注意力机制 2.SE注意力机制 3.ECA注意力注意力机制 4.CA注意力注意力机制 5.SimAM注意力机制 6.ShuffleAttention注意力机制 7.CrissCrossAttention注意力机制 1.CBAM注意力机制 class ChannelAttention(nn.Module): def __init__(self, in_planes, ratio=16): super(ChannelAttention, self).__init__() self.avg_pool = nn.AdaptiveAvgPool2d(1) self.max_pool = nn.AdaptiveMaxPool2d(1) self.f1 = nn.Conv2d(in_planes, in_planes // ratio, 1, bias=False) self.relu = nn.ReLU() self.f2 = nn.Conv2d(in_planes // ratio, in_planes, 1, bias=False) self.sigmoid = nn.Sigmoid() def forward(self, x): avg_out = self.f2(self.relu(self.f1(self.avg_pool(x)))) max_out = self.f2(self.relu(self.f1(self.max_pool(x)))) out = self.sigmoid(avg_out + max_out) return out class SpatialAttention(nn.

mybatisplus多表查询返回vo对象,如何在java代码中实现

在使用MyBatis-Plus进行多表查询时,可以使用`@TableName`注解来指定表名,使用`@TableField`注解来指定表字段,使用`@JoinQuery`注解来指定关联查询条件。例如,我们有两个表`user`和`order`,它们的关联字段是`user_id`,现在需要查询出用户信息和对应的订单信息,可以定义一个VO类`UserOrderVO`,如下: ```java @TableName("user") public class UserOrderVO { @TableField("user_id") private Long userId; @TableField("user_name") private String userName; @TableField(exist = false) private List<Order> orders; // 关联查询结果 // 省略getter/setter方法 } ``` 在VO类中,使用`@TableName`注解指定表名,使用`@TableField`注解指定表字段,`exist = false`表示该字段不是表中的字段,只是用来存放关联查询结果。 接下来,使用`@JoinQuery`注解指定关联查询条件,如下: ```java @Mapper public interface UserOrderMapper extends BaseMapper<UserOrderVO> { @JoinQuery(value = "order", condition = "user.user_id = order.user_id", type = JoinType.LEFT_JOIN) List<UserOrderVO> selectUserOrder(); } ``` 在Mapper接口中,使用`@JoinQuery`注解指定关联查询条件,`value`属性指定关联表名,`condition`属性指定关联条件,`type`属性指定关联方式(此处使用左连接查询)。 最后,在Service层中调用Mapper接口查询数据,如下: ```java @Service public class UserOrderService { @Autowired private UserOrderMapper userOrderMapper; public List<UserOrderVO> getUserOrder() {

【例6】计算e=1+1/1!+1/2!+1/3!+...当1/n!<1e-7停止

#include <iostream> using namespace std; void main() {double e=1.0,u=1.0;//不能赋值整数,否则除法运算得不出想要的结果 int n=1; do{ e=e+u;//求累加和 n=n+1;//计算分母中的n u=u/n;//得到下一个加数 }while(u>=1.0e-7); cout<<"e="<<e<<"(n="<<n<<")"<<endl; }

Linux--常用redis命令

文章目录 一、连接redis二、切换库三、查看所有keys四、删除指定key五、退出redis 一、连接redis 连接本地redis客户端 redis-cli 二、切换库 切换redis库 select 3 三、查看所有keys 输入 keys * 查看redis 缓存key keys * 四、删除指定key 删除指定key del login_admin 五、退出redis exit/quit

SpringBoot进行测试出现提示TestContextAnnotationUtils错误

问题:SpringBoot进行测试出现提示TestContextAnnotation-Utils错误, 解决方法:测试类型的包版本不一致!!!一定保证spring框架、jdk、maven等相关版本一致对应。比如可以适当降低一些版本就ok了。 出现上面的问题是因为我们将 Spring Boot 从版本 2.3.3 升级到了 2.4。 在依赖 spring-test 中,我们还是定义 5.2.8.RELEASE 了这个版本。 如果升级版本到 Spring Boot 2.4 的版本的话,你可以首先取消掉 5.2.8.RELEASE 这个版本的限制。 如果取消掉版本的话,你可以看到 Spring 的测试使用的是 5.3.1 的版本。 最后,通过控制台测试就可以看到版本兼容性问题就已经解决了。

STM32CubeMX+STM32F407+FreeRTos+LAN8720 以太网通信实现数据收发功能

目录 前言 一、STM32CubeMX配置 二、修改代码 三、硬件测试 总结 前言 该工程应用的以太网芯片是LAN8720,代码是基于STM32CUbeMx6.2.1配置生成的,在CubeMx中配置了ETH和LWIP,还有串口1和FREERTOS,最后通过创建任务函数实现udp的以太网数据收发功能。在测试中,可以在电脑的DOS窗口ping通在LWIP设置的单片机开发板的ip地址,通过网络调试助手可以实现数据的收发功能。 一、STM32CubeMX配置 1、选择STM32F407VET6芯片创建工程,首先配置RCC和SYS,再配置时钟,配置界面如下 2、配置ETH,配置界面如下 3、配FREERTOS和LWIP,配置界面如下 4、分配中断优先级,配置界面如下(如果需配置串口,先配置一下串口) 5、到这里,CubeMX就算配置完成了,就可以生成代码了 二、修改代码 1、打开生成的工程文件,找到HAL_ETH_MspInit函数,在最下面添加芯片复位的三行代码(作用是在芯片初始化时,对芯片复位一下,该芯片复位引脚对应我单片机开发板上的PA3) 2、在main.c中添加修改函数,首先是包含的文件,然后是创建任务函数, #include "main.h" #include "cmsis_os.h" #include "lwip.h" #include "usart.h" #include "gpio.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "stdio.h" #include "udp_echoserver.h" /* USER CODE END Includes */ /* USER CODE BEGIN 0 */ void controlTask(void * param) { MX_LWIP_Init(); vTaskDelete( NULL ); } void commandTask(void * param) { udp_echoserver_init(); while(1) { vTaskDelay(2); } } TaskHandle_t StartTaskHandle; void StartTask(void * arg) { taskENTER_CRITICAL(); xTaskCreate(controlTask, "

数据中台建设(三):数据中台架构介绍

数据中台架构介绍 数据中台要求全企业共用一个数据技术平台、共建数据体系、共享数据服务能力。实际上一个企业中由于各个业务线发展不均衡,各自都有独立的数据处理架构,导致共享数据非常困难,所以要构建数据中台不仅是对技术架构的改变,同时还是对整个企业业务运转模式的改变,需要企业在组织架构和资源方面给予支持。数据中台是一个企业战略行动,绝非一个项目组或者一个小团队就能做的,需要了解整个企业的业务情况,对业务进行梳理,还需要技术支撑、组织的支撑,否则很难推行下去。 一、数据中台构建方法论 数据中台的建设内容包含技术体系、数据体系、服务体系、运营体系四大体系。 技术体系 技术体系是构建数据中台的基础支撑,对于技术体系而言包括两部分:大数据存储计算技术和数据中台工具技术组件。 大数据存储计算技术包含:Hadoop、Spark、Flink、Clickhouse 等技术,企业一般不会自己建设,只需要进行合理的选型即可。 数据中台工具技术包含:数据汇集、数据资产管理、平台服务管理工具等相关技术。 数据体系 数据体系是指全企业的数据通过各种方式汇聚到数据中台,在数据中台中按照一定的建模方式进行加工处理,形成企业的数据资产体系。不同企业业务不同对应的数据不同,当然构建的数据体系内容也不同,但是建设的方法都是类似的。 服务体系 数据中台与大数据平台最主要的区别是数据中台中数据能方便的以服务化的方式支撑业务。服务体系是通过中台的服务组件能力,把数据变为一种服务能力。例如:客户微观画像系统、信用评估服务、风险预警服务等,让数据能够方便的参与到业务中去并为业务带去价值。 运营体系 运营体系是数据中台的守护者,通过运营体系保证整个中台的健康、持续运转。运营体系包含平台资源占用监控、数据质量监控、数据价值评估等,其目标是让中台持续健康运转,产生持续价值。 结合以上构架数据中台四大体系,构建数据中台可分为如下 5 个步骤,如图所示: 1)理现状 梳理企业已拥有的数据、业务特点,使用的技术,部门等企业组织形态等现状。 2)立架构 架构中包含“组织架构”、“业务架构”、“技术架构”、“应用架构”、“数据架构”。 组织架构:组织架构主要是保证中台项目的顺利落地需要企业考虑的整体组织保障,其中角色主要包含:业务人员、IT 人员、供应商、相关负责人。 业务架构:保证数据中台能够适用于企业业务的业务管理流程。 技术架构:主要针对数据中台中数据存储、计算相关技术选型。 应用架构:应用架构就是根据业务设计哪些数据服务。 3)建资产 数据资产建设包含数据汇集、数据仓库建设、数据治理、标签体系建设,其中最重要的就是标签体系建设,所谓标签体系建设就是面向具体对象构建的全维度数据标签,通过标签体系可以方便地支撑应用。 4)用数据 将通过数据中台构建的数据资产通过服务化的方式应用到具体的业务中,发挥数据价值。 5)做运营 运营主要包含数据监控审计、数据价值评估等内容,通过数据运营,让更多的人和业务感知到数据的价值。数据中台构建稳定之后,一般会循环 3~5 步骤,不断挖掘数据和业务场景的结合点。 由以上建设数据中台内容体系来看,建设数据中台除了有对应的方法论之外,还需要有对应的支撑技术、组织架构。“方法论”、“支撑技术”、“组织架构”实际上是建设数据中台的“三板斧”,缺少任何一个条件都不能建设好中台。 二、数据中台功能架构 数据中台总体架构图如下: 下面简述以上数据中台的各个部分,可以参照后续小节分析内容。 数据汇集 数据汇集是数据中台数据接入的入口,所有数据来自于业务系统、日志、文件、网络等,这些数据存储在不同的网络环境和存储平台,通过数据汇集工具可以将这些数据汇集到数据中台中。 数据开发 数据汇集到中台之后,数据都是按照原始状态堆砌在一起,业务无法使用,数据开发可以通过一整套数据加工及管理工具,将数据进行清洗处理。 数据体系 此部分主要是大数据平台中数据仓库构建内容。 数据资产管理 通过数据体系建立起来的数据资产较为偏技术,业务人员比较难理解,数据资产管理是以企业全员更好理解的方式把企业数据展现给全企业人员。数据资产管理包括对数据资产目录、元数据、数据质量、数据血缘、数据生命周期等进行管理和展示。 数据服务体系 数据服务体系就是把数据变为一种服务能力,通过数据服务让数据参与到业务,数据服务体系是数据中台存在的价值所在。数据中台服务提供快速的服务生成能力以及服务的管控、鉴权、计量等功能。 运营体系和安全管理 运营体系和安全管理是数据中台健康持续运转的基础。建设内容主要涉及企业资产管理和数据安全,使数据越用越多,越用越活。 三、数据中台技术架构 数据中台的技术架构如下:

ROS已装背景下安装PCL和VTK,解决VTK和PCL_ROS冲突问题

前情提要: 本人同时需要pcl_ros和PCL,其中装PCL_ROS是装了ROS之后,补两个包:pcl-conversions pcl_ros, 然后PCL另装。 如果用经典方法Ubuntu18.04安装PCL(详细教程)安装PCL的话,会导致vtk包的冲突问题,即PCL需要某版本的VTK才能编译通过,而pcl_ros需要另一版本的VTK才能通过,由此产生了冲突的问题,进而产生了安装VTK、PCL和VTK版本选择、PCL在已有ROS下的安装问题,过程中产生了一系列bug。 本文旨在解决这样一个问题: 在安装ROS的前提下,安装适配版本的VTK和PCL。 1.ROS INTSLL Install ROS-Melodic on ubuntu18.04 安装后需要为pcl_ros补两个包: sudo apt install ros-melodic-pcl-conversions ros-melodic-pcl-ros 2.PCL INSTALL 背景:在已经安装ROS的背景下安装PCL 版本适配:PCL 1.8.1 + VTK 7.1.1(重要:必须适配版本) 一、安装PCL依赖 sudo apt-get update sudo apt-get install git build-essential linux-libc-dev sudo apt-get install cmake cmake-gui sudo apt-get install libusb-1.0-0-dev libusb-dev libudev-dev sudo apt-get install mpi-default-dev openmpi-bin openmpi-common sudo apt-get install libflann1.9 libflann-dev # ubuntu18对应1.9 sudo apt-get install libeigen3-dev # 这个需要自己下载正确版本安装 sudo apt-get install libboost-all-dev sudo apt-get install libqhull* libgtest-dev sudo apt-get install freeglut3-dev pkg-config sudo apt-get install libxmu-dev libxi-dev sudo apt-get install mono-complete sudo apt-get install libopenni-dev sudo apt-get install libopenni2-dev sudo apt-get install openjdk-8-jdk openjdk-8-jre 二、VTK安装 1.

Apifox:API 接口自动化测试完全指南

1. 前言 在开始前大家可以先阅读:深入了解自动化测试:什么是自动化测试及其作用? 大家好,这是一篇关于 Apifox 的接口自动化测试教程。相信你已经对 Apifox 有所了解:“集 API 文档、API 调试、API Mock、API 自动化测试,更先进的 API 设计/开发/测试工具”。 笔者是后端开发,因此这篇教程关注的是 API 自动化测试,如果你也是后端开发,正苦于没有好的方式测试接口,对保证线上接口稳定性没有信心,那么这篇文章就是为你准备的,如果你学会了 Apifox 接口自动化测试,它几乎是一个会陪伴你整个职业生涯中的一件称心应手的兵器。 接口测试可不是简单的请求一两个接口再检查一下响应结果那么简单,没有贴近业务场景的测试意义不大,但完全模拟业务场景,一比一真实的去还原用户操作流程的测试势必会很复杂,如 接口需要登陆后才能操作怎么办?一个接口依赖上一个接口请求返回的数据怎么办?后端对请求有签名验证怎么办?后端任务是异步处理的怎么办?... 不要担心,既然是完全指南,这些问题我们就都会讲到,Apifox 强大的能力可以解决这些问题,下面我们会用真实的案例,逐步讲解覆盖到这些所有的场景。建议大家打开 autotest.apifox.cn 这个项目,一边学习里面的公共脚本(公共脚本、测试套件等都打包放在 百度网盘),一边跟着练习。 2. 接口自动鉴权 知识点:环境变量、公共脚本、pm.sendRequest脚本发送请求 我们通过一个需要登录才能访问的后台新闻列表接口,来演示接口自动登录鉴权。 默认情况下访问该接口提示需要登录: 如果要正常访问该接口的数据,需要在 header 中提供 AdminToken: token 头,这是一个常见的需要 JWT 登录认证接口。 很自然的我们想到,如果自动请求登录接口获取 token 值,然后在每次请求前自动带上这个 AdminToken 头不就行了吗,没错就是这样简单,伪代码如下: 完整的代码见 「公共脚本」admin: login and Auth 这里我们从登录接口获取 token 后,将其缓存到本地的环境变量中,这样就不必每次都请求登录了。 现在我们已经完成了 请求登录接口获取 token,并设置到 请求头中的功能,然后我们再把此 公共脚本 应用到 新闻列表的接口上,实现在 请求新闻列表接口 前自动完成 “登录”。 后台有很多接口访问都需要登录,如果一个个地去设置 前置脚本 就太麻烦了,所以这里我们直接在 admin 后端接口的分组目录上设置 前置操作 公共脚本admin: login and Auth,这样整个 admin 下的全部接口都能自动登录了:

解决 java: 非法字符: ‘\ufeff‘

问:java: 非法字符: '\ufeff' 是什么问题? 答:这个错误通常表示在Java代码中存在一个非法字符,这个字符通常是一个不可见的字符,比如 Unicode BOM (Byte Order Mark)。BOM 是一个特殊的字符,用于指示文本的字节顺序,但是在Java中,它是不必要的。 要解决这个问题,您可以使用文本编辑器中的“另存为”选项,并确保保存文件时不要包含 BOM。您也可以使用一些文本编辑器,如 Notepad++,它可以轻松地删除 BOM。另外,您还可以尝试使用另一种编码格式,如 UTF-8 without BOM,这样可以避免 BOM 的出现。 如果您使用的是版本控制系统,如Git,您也可以尝试从历史记录中恢复一个没有 BOM 的版本,并将其用作新版本的基础。 问:Notepad++,它可以轻松地删除 BOM ;怎么弄? 答: 在 Notepad++ 中删除 BOM 非常简单。请按照以下步骤操作: 打开 Notepad++ 并打开包含 BOM 的文件。点击“Encoding”菜单,然后选择“Encode in UTF-8 without BOM”(在菜单中通常显示为“UTF-8 无 BOM”)。点击“文件”菜单,然后选择“保存”或“另存为”,以保存您的更改。 这样就可以将您的文件转换为 UTF-8 编码,并删除 BOM。请注意,如果您在文件中使用了一些特殊字符,可能需要进行其他处理,以确保它们仍然被正确地编码和解码。

(Windows下NVIDIA 显卡可用)ChatGLM-6B的安装文档(媲美GPT-3.5),存一个!

目录 一、前言 二、下载(建议直接跑python程序下载,最新的最稳定) 三、部署 3.1 配置环境 3.2 启动 demo 程序 3.2.1 启动 cli_demo.py 3.2.2 启动 web_demo.py 3.2.3 启动 web_demo2.py 四、【最新】ChatGLM-6B-int4 版本教程 4.1 下载 4.2 配置环境,Windows下NVIDIA 显卡可用 4.3 启动 demo 程序 五、小结 转载:清华 ChatGLM-6B 中文对话模型部署简易教程_---Olive---的博客-CSDN博客 一、前言 近期,清华开源了其中文对话大模型的小参数量版本 ChatGLM-6B(GitHub地址:https://github.com/THUDM/ChatGLM-6B)。其不仅可以单卡部署在个人电脑上,甚至 INT4 量化还可以最低部署到 6G 显存的电脑上,当然 CPU 也可以。 随着大语言模型的通用对话热潮展开,庞大的参数量也使得这些模型只能在大公司自己平台上在线部署或者提供 api 接口。所以 ChatGLM-6B 的开源和部署在个人电脑上,都具有重要的意义。 博主测试后发现,对比 huggingface上其他同参数量的模型来说,ChatGLM-6B 的效果已经是很好的了,更何况它还有 130B 的版本,官网说明(官方博客:https://chatglm.cn/blog)是优于 GPT-3.5 效果的(130B 版本正在内测,博主没有拿到测试资格,所以无法确认)。所以把 ChatGLM-6B 部署在个人电脑或者服务器上还是很好玩的,这个参数量还要什么自行车。 最新更新】ChatGLM-6B 在 2023/03/19 更新增加了量化后的 INT4 模型,官方直接针对性的量化模型后提供下载。对比原版自己设置量化效果好一些,而且模型大小只有 4G,极大地加快了下载速度。 对于只有 CPU 或者只有 6G 显存的同学,可以直接选择量化后的模型下载和部署,本文单独更新了 ChatGLM-6B-int4 版本的部署教程,在第四章,需要部署的可以直接跳转到第四章,忽略前面的内容。huggingface 地址:https://huggingface.