在pytorch中: torch.cat(x=[A,B],dim=n)函数:是将数据A,B沿着dim=n的方向进行拼接;x必须是list或者tuple类型的tensor. 例子: import torch x1 = torch.tensor([[1, 2, 3], [4, 5, 6]]) x2 = torch.tensor([[11, 12, 13], [14, 15, 16]]) x3 = torch.tensor([[21, 22], [23, 24]]) out1=torch.cat([x1,x2,x3],dim=-1) #(dim=-1:横着拼接) out2=torch.cat([x1,x2,x3],dim=1) #(dim=1:横着拼接) out3=torch.cat([x1,x2],dim=0) #(dim=0:竖着拼接) print(out1.shape) print("out1:\n",out1) print("out2:\n",out2) print("out3:\n",out3) ======================================== 输出结果 torch.Size([2, 8]) out1: #(dim=-1:横着拼接) tensor([[ 1, 2, 3, 11, 12, 13, 21, 22], [ 4, 5, 6, 14, 15, 16, 23, 24]]) out2: #(dim=1:横着拼接) tensor([[ 1, 2, 3, 11, 12, 13, 21, 22], [ 4, 5, 6, 14, 15, 16, 23, 24]]) out3: #(dim=0:竖着拼接) tensor([[ 1, 2, 3], [ 4, 5, 6], [11, 12, 13], [14, 15, 16]]) 注意:竖着拼接的两个数据的维度需要相同;dim=-1 和dim=1的效果是相同的。
1 fmt …
2 os …
3 io …
4 strconv 4.1 ParseBool() package main import ( "fmt" "strconv" ) func main() { // 根据传入的bool值转成string类型数据 // FormatBool(b bool) string var isOk bool = true boolString := strconv.FormatBool(isOk) fmt.Printf("bool 类型的数据转成字符串类型:%v type %T\n", boolString, boolString) // bool 类型的数据转成字符串类型:true type string } 4.2 ParseFloat() package main import ( "fmt" "strconv" ) func main() { // float类型转成字符串 // FormatFloat(f float64, fmt byte, prec, bitSize int) string /* 函数将浮点数表示为字符串并返回。 bitSize表示f的来源类型(32:float32、64:float64),会据此进行舍入。 fmt表示格式:'f'(-ddd.
一、女生做网络安全会不会压力很大? 压力是相对的。压力是不是很大,这个主要是去看跟谁比。
那网络安全压力会不会大,我们就和IT研发线上的其他岗位比比看。
目前互联网公司产品研发中基本上都涉及到产品经理、开发工程师、网络安全工程师,运维工程师等关键角色。
1、产品经理
产品经理这个岗位需要非常强的逻辑思维、信息处理和需求分析能力,而且需要对行业和业务有深刻的认知,能够带项目和产品,同时需要非常强的资源整合、管理协调、产品把控能力,客观来讲还是相对比较难的而且工作压力非常大,压力等级5颗星。所以不推荐一个女生去学习产品经理。
2、开发工程师
开发工程师俗称程序员,它在百度百科的解释是指从事程序开发、程序维护的专业人员。听上去就是一个相当高大上的行业,好像在人们眼中,电影里,那些面容冷峻,手指飞速敲打着键盘,使电脑黑色屏幕上闪现一串串代码的人,就应该是程序员的样子,但实际上在大多数人眼里,程序员的标签是:男性、高收入、不修边幅、技术宅。他们有以下几个典型特征:
长期脱发 不修边幅——万年的格子衫 不是在加班,就是在加班的路上 很明显,开发工程师工作压力也非常之大,压力等级4星半,对于喜欢追求“安逸”工作的女生来说,很明显是不合适的。
3、运维工程师
运维工程师,每天的工作就是搭建服务器、搭建网络、配置环境、安装软件;运维圈流行一句话:没有永垂不朽,我们不能保证硬件24小时在线,但需要保障服务24小时在线。因为这个工作最大的特点就是需要7*24小时待命,所以工作压力也是非常巨大,压力等级4颗星,基本上就看不到女生。
4、网络安全工程师
最后我们来说说网络安全工程师,所谓网络安全其实就是指通过采取必要措施,防范对网络的攻击、侵入、干扰、破坏和非法使用以及意外事故,使网络处于稳定可靠运行的状态,以及保障网络数据的完整性、保密性、可用性的能力,特点是:
细心耐心同理心执行力强 这些特点恰恰是绝大多数女生都具备的,所以女生非常适合学习网络安全:
1.女生更细心,善于发现程序中的bug; 2.女生更耐心,觉得能够胜任起步阶段的某些重复性工作; 3.女生沟通能力强且富有亲和力,和普遍都是男生的软件开发人员沟通起来,更有优势; 4.女生思考方式趋于感性,往往善于站在对方的角度考虑问题(换位思考) 发挥你擅长的优势,怎么会有很大的压力呢? 而且网络安全,不需要像产品经理一样,有强悍的管理沟通能力;不需要像开发一样,有强大的逻辑思维、加班能力;不需要像运维人员一样7*24小时待命,所以在几乎所有的互联网公司中,网络安全团队往往都是女生占据大部分。相比其他的互联网技术岗,网络安全对于女生来说压力最低,也是最适合女生选择的互联网技术岗。
二、网络安全压力大不大,去了解下网络安全的工作强度 介绍下网络安全的工作强度:
1、国企:早9点 晚6点 (网络安全、开发基本不加班)
2、互联网:弹性(早上11点前到就行,早来早走)工作模式,一天9小时左右。
3、私企:9~10.5个小时
所以,网络安全工作,相比开发,工作强度更低。所以相对于开发几乎全是抗压能力更强,可以接受秃头的男生,但网络安全接近一半是温柔似水的女生。
三、女生学网络安全法容易么? 网络安全难吗?
客观来讲,相比开发、运维,网络安全入门真的非常简单。
如果你是纯文科女生,属于少部分觉得测试还是有一些压力的,那我需要给你一个鼓励。最好的鼓励就是网络安全的薪资。
薪资不仅年年上涨现在均薪已经超过了15K,而且薪资在10年工作经验后,将会超过10年工作经验的开发。 网络安全学习资源分享: 零基础入门
对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。
CSDN大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享 (qq.com)
同时每个成长路线对应的板块都有配套的视频提供:
CSDN大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享 (qq.com)
因篇幅有限,仅展示部分资料,需要点击上方链接即可获取
当使用粘性定位的盒子出现,当滚动条滚动一段距离有效,然后就跟着滚动条滚出视口,不起作用了,要考虑看你是否设置了:
html,body{ height:100%; } 这个代码会影响html和body的高度,不是整个视口的高度 参考:
彻底理解粘性定位(position:sticky)_粘性定位不生效_又菜又爱玩的程序猿的博客-CSDN博客
命令行配置 Git全局设置 git config --global user.name "xxx" git config --global user.email "xxx@xxx.xxx" 配置SSH Key ssh-keygen -t rsa -C "xxx@xxx.com" # 连接Github、Gitlab的邮箱 # 过程中会指定输出的文件名,若存在多个邮箱账户,需修改不同的文件名 cat ~/.ssh/id_rsa.pub # 默认为id_rsa.pub,若在上步中修改文件名,则替换为修改后的文件名.pub # 拷贝公钥至剪切板 Windows: clip < ~/.ssh/rd_rsa.pub Mac: pbcopy < ~/.ssh/rd_rsa.pub GNU/Linux(requires xclip): xclip -sel clip < ~/.ssh/rd_rsa.pub # 将剪切板的公钥复制至Github、Gitlab等代码仓库的'SSH Key'配置中 # 测试连接 ssh -T git@github.com ssh -T git@gitlab.com 创建一个新仓库 git clone git@xxx # 在Github等代码仓库中点击'Clone'产生的'git@XXX' cd file # Clone到本地的文件夹 touch README.md git add README.
一、25岁女孩转行晚么? 25岁的女人,应该做什么?这样放在二三线城市或更为广阔的农村得到的答案往往是:年级也不小了,赶紧找个婆家嫁了吧。但是这样真的就是自己想要的生活吗?这样的日子一定就会幸福吗,前几年大热的电视剧《我的前半生》主角罗子君的故事就在眼前,一个全职妈妈,每天儿子上学,老公上班,阿姨做家务,日子无聊却安逸。然而丈夫突然提出离婚,原本平静的生活突然刮起了龙卷风,当事情发生的那一刻她是多么的无助。
当今社会的生活节奏已越来越快,人们的压力也与日俱增,待到结婚生子、柴米油盐酱醋茶的压力也会剧增;继续按照现有路线,做一条不咸不淡的咸鱼吗?还是积极准备需求突破,去亲手打造更好的未来呢?
正如毛主席所说,妇女能顶半边天,如何能更好的支撑住着半边天,经济独立至关重要。作为女性你得要有一份事业。并且热爱你的工作。因为一个女人只有有了事业她才能更独立,更能全身心的投入到工作上去,有了工作你才能维持最基本的生活。不需要你多富有,但是你得保证你的生活质量。只有有了事业你才能活得更充实 ,更独立。并且这时你也应该开始学会存储了。你已经过了向父母伸手要钱的时候了,如果某一天你突然失业,卡里如果没有一点存款那你拿什么来度过你那段艰难的失业期。你要知道现在这个社会能愿意雪中送炭的朋友已经不多了。
二、女生适合网络安全么? 女孩子不用读那么多书、做家庭主妇、全职太太的时代已经过去,越来越多的女性开始追求独立。独立的第一步,就是干一份自己喜欢的工作。什么样的工作比较适合女孩呢?IT行业的网络安全是非常适合女生的,因为网络安全工程师是一个没有性别歧视的职业,特别是对于跨专业、跨行业的女生尤为合适。
女生细心,善于发现程序中的Bug 女生有耐心,觉得能够胜任起步阶段的某些重复性工作 女生沟通能力强且富有亲和力,实际工作中能够快速的融入团队并与其他同事高效协作 女生工作细致,执行力强,而这往往是绝大多数女生的优势所在 女生思考方式趋于感性,往往善于站在对方的角度考虑问题(换位思考) 综上所述,女生确实比较适合学习网络安全。致自己:你要悄悄的拔尖,然后惊艳所有人。
三、25岁女生该如何转行? 那么问题来了,我应该如何悄悄的拔尖,然后惊艳所有人。自学网络安全好呢?还是选择一个靠谱的培训机构报班学习软件测试好呢?这需要问你自己你的学习决心有多大,你内心改变现状追求自己向往的生活得意愿有多强,毕竟学习是自己的事情,一切外在的手段看视频、刷面试题、做项目都只是一些学习辅助手段而已。
网络安全学习资源分享: 零基础入门
对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。
CSDN大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享 (qq.com)
同时每个成长路线对应的板块都有配套的视频提供:
CSDN大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享 (qq.com)
因篇幅有限,仅展示部分资料,需要点击上方链接即可获取
单细胞生信分析教程 桓峰基因公众号推出单细胞生信分析教程并配有视频在线教程,目前整理出来的相关教程目录如下:
Topic 6. 克隆进化之 Canopy
Topic 7. 克隆进化之 Cardelino
Topic 8. 克隆进化之 RobustClone
SCS【1】今天开启单细胞之旅,述说单细胞测序的前世今生
SCS【2】单细胞转录组 之 cellranger
SCS【3】单细胞转录组数据 GEO 下载及读取
SCS【4】单细胞转录组数据可视化分析 (Seurat 4.0)
SCS【5】单细胞转录组数据可视化分析 (scater)
SCS【6】单细胞转录组之细胞类型自动注释 (SingleR)
SCS【7】单细胞转录组之轨迹分析 (Monocle 3) 聚类、分类和计数细胞
SCS【8】单细胞转录组之筛选标记基因 (Monocle 3)
SCS【9】单细胞转录组之构建细胞轨迹 (Monocle 3)
SCS【10】单细胞转录组之差异表达分析 (Monocle 3)
SCS【11】单细胞ATAC-seq 可视化分析 (Cicero)
SCS【12】单细胞转录组之评估不同单细胞亚群的分化潜能 (Cytotrace)
SCS【13】单细胞转录组之识别细胞对“基因集”的响应 (AUCell)
SCS【14】单细胞调节网络推理和聚类 (SCENIC)
SCS【15】细胞交互:受体-配体及其相互作用的细胞通讯数据库 (CellPhoneDB)
SCS【16】从肿瘤单细胞RNA-Seq数据中推断拷贝数变化 (inferCNV)
SCS【17】从单细胞转录组推断肿瘤的CNV和亚克隆 (copyKAT)
SCS【18】细胞交互:受体-配体及其相互作用的细胞通讯数据库 (iTALK)
简介 单细胞技术和集成算法的最新进展使得构建包含许多供体、研究、疾病状态和测序平台的综合参考地图集成为可能。就像将测序读数映射到参考基因组一样,能够将查询细胞映射到复杂的、数百万个细胞的参考图谱上,以快速识别相关的细胞状态和表型是至关重要的。本文介绍了Symphony (https://github.com/immunogenomics/symphony),这是一种以方便、便携的格式构建大规模集成参考地图集的算法,可以在几秒钟内实现高效的查询映射。Symphony将查询细胞定位在稳定低维引用嵌入中,从而便于将引用定义的注释向下复制传输到查询。我们展示了Symphony在多个真实世界数据集中的强大功能,包括
(1)映射多供体、多物种查询以预测胰腺细胞类型;
(2)沿着胎儿肝脏造血的发育轨迹定位查询细胞;
(3)使用记忆T细胞的多模态citation-seq图谱推断表面蛋白表达。
Symphony 最早发表于 2021 年 Nature Communications 杂志上的一篇文章,文章题目为"
开发人员为什么会有35岁危机,其实是由多方面造成的。大体可以分为以下几个原因:
1、企业方的需求,程序员淘汰率高才能最划算
思考一个问题:
公司做一款新产品的时候可能需要一百个程序员来开发,但是做完了以后平时只需要五个程序员来维护就够了。那剩下的九十五个程序员怎么办? 解决方法1:
互联网中大型公司:安排开发其他项目
开发人员完成了一个项目的开发后,公司为避免人员闲置,往往会布置开发人员做其他项目的开发。
而这个项目,往往和之前开发的产品不是同一个类型。比如开发人员开发出了网站,公司是不会白白养着,往往会要求去开发OA、财务软件、通讯软件,手机APP…每种产品的业务逻辑不一样,导致开发经验的可移植性就较差,就需要留给开发人员足够的学习时间。
确是不如直接找有相关项目经验的开发人员性价比更高。
解决方法2:
互联网小公司:95人全部开掉。
很多互联网小公司其实就指着几个项目吃饭,一个项目完了以后未必还能有开发下一个的机会,说不定找不到投资明天就倒闭了。
另外即使到时候又需要人了,直接招新人不香吗?永远会有新的大学毕业生在找工作,他们可能没什么经验,可能技术一般,但是他们要的钱少,身体好,能熬夜,听话,好忽悠。
如果你是一个企业的管理者,排除掉感情因素,你也会用这种性价比高的新零件换掉旧零件。
2、程序员工作本身存在折磨,年龄大真扛不住
这个折磨不是说写代码,觉得写代码是折磨的人干不了这一行。
这里说的是来自同事和需求方的折磨。
写代码对程序员来说不难,难的是需求方的需求变来变去,一开始说要A,代码写到一半说要B,又得重新写,写了一大半又说要添加个C功能,但这个C功能必须底层就写好,不能写一半再加,这时候又要重写。
最后就是整个人都被折磨疯了。
除了需求变来变去之外,还有一个问题就是经常白天被抓去开各种乱七八糟的会,然后只能晚上写代码,这就又造成了加班的现象。
程序员天天加班不假,但并不是加班写代码,主要是白天都被抓去开会,晚上和人撕逼需求,深夜才能写代码。
老这么加班,年轻还可以顶着,年纪大了还真的顶不住。
3、互联网行业发展快,技术更新也快,对程序员的要求还越来越高
技术带来先进生产力的同时,技术的迭代也是非常快的,弄不好分分钟就被淘汰。
不像很多传统行业,技术的积累是逐渐稳固的,越老越吃香。
开发人员可不一样,他们掌握的东西如果不能快速迭代,很容易出现自己被世界淘汰。
买数码产品我们都知道越新越好对吧?技术也是如此【所以如果要选择开发语言,强烈建议选择不容淘汰,市场需求广泛,老当益壮语言,如JAVA,Python等,】。
2023年,但凡能为程序员开出高薪的公司,对于程序员的筛选都是比较严格的,不对,已经不是比较严格了,是很严格。
不信自己可以去网上搜搜各大公司招聘的面试问题和笔试题,自己试着答一下,看看结果。
从来没有白给钱的事情,高工资带来的必然是高要求。这就意味着开发人员需要不断的去更新自己的知识体系, 个人必须非常努力,努力钻研各种新技术。
总结:
1、企业方的需求,程序员淘汰率高才能最划算 2、程序员工作本身存在折磨,年龄大真扛不住 3、互联网行业发展快,技术更新也快,对程序员的要求还越来越高 所以程序员必须有足够的危机意识。
一方面要费脑筋去开发新产品;一方面又要去学习新的技术;一方面还得与产品经理撕逼;一方面还要白天被琐事纠缠,只能晚上去做开发,加班深夜,用身体抗; 最后还得想办法讨好领导,争取早日坐上技术管理不用在一线写代码。多重折磨之下,这个头发肯定是留不住的。
在35岁这个年纪,往往又有家庭和孩子,精力不能和年轻时一样,全部投入到工作中,所以在职场的竞争力就开始下降。所以就有了35岁危机这一说。
对于程序员而言,不只是所谓的35岁,更是要时刻警醒自己要做架构,研究算法,转管理。
最后免费分享给大家一份Python全套学习资料,包含视频、源码,课件,希望能帮到那些不满现状,想提升自己却又没有方向的朋友。
关于Python技术储备 学好 Python 不论是就业还是做副业赚钱都不错,但要学会 Python 还是要有一个学习规划。最后大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!
一、Python所有方向的学习路线 Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
二、Python必备开发工具 三、Python视频合集 观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。 四、实战案例 光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。 五、Python练习题 检查学习结果。 六、面试资料 我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。 这份完整版的Python全套学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】
安装oath-toolkit $ brew install oath-toolkit 获取MFA SECRET git clone https://github.com/scito/extract_otp_secret_keys.git --depth=1pip3 install protobufpip3 install qrcode[pil]打开app -> 转移账号 -> 导出账号 -> 选择账号 -> 识别二维码 保存到a.txtpython3 extract_otp_secret_keys.py -p a.txt 获取secret 配置环境变量 SSH_TERMINAL_PORT='5678' SSH_TERMINAL_USER='root' SSH_TERMINAL_IP='192.168.50.50' MFA_SECRET=*************** MY_PASSWORD=***************** export SSH_TERMINAL_PORT export SSH_TERMINAL_USER export SSH_TERMINAL_IP export MY_PASSWORD export MFA_SECRET alias mfa='oathtool --totp -b ${MFA_SECRET}' expect 脚本 #!/usr/bin/expect spawn ssh -p $env(SSH_TERMINAL_PORT) $env(SSH_TERMINAL_USER)@$env(SSH_TERMINAL_IP) expect "*password*" {send "$env(MY_PASSWORD)\r"} expect "*auth*" { set code [exec oathtool --totp -b $env(MFA_SECRET) ] send "
centos8配置国内yum源过程:
操作的主要思路为:
在不删除源文件的基础上,将源文件备份下载最新centos8国内的yum源文件更换地址 主要实现的代码如下:
进入root,切换至yum.repos.d目录cd /etc/yum.repos.d/ 创建新文件夹并将源文件备份为repo.bakmkdir backup && mv *repo backup/ 下载国内yum源文件curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-8.repo 更新下载yum源地址sed -i -e"s|mirrors.cloud.aliyuncs.com|mirrors.aliyun.com|g " /etc/yum.repos.d/CentOS-*sed -i -e "s|releasever|releasever-stream|g" /etc/yum.repos.d/CentOS-* 生成缓存yum clean all && yum makecache
1 问题由来
遇到一个需求,需要对 原数据的某个字段置为null,参考了教程,使用了注解
@TableField(value = “nick_name”,strategy = FieldStrategy.IGNORED)
private String nickName;
在User实体对象的属性上加了“strategy = FieldStrategy.IGNORED”,成功的将数据库对应的字段更新成了null。。但是,但是,但是其他的更新的sql也会跳过null值检查,造成的结果就是,另一个update语句,也将“nick_name”更新成了null…导致线上的数据直接出现问题。。。。
2 替换的解决办法
使用条件构造器组装sql
LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<>();
wrapper.eq(User::getId, user.getId());
wrapper.set(User::getNickName, null);
getBaseMapper().update(wrapper);
1
2
3
4
5
wrapper.set(User::getNickName, null);
将 nick_name设为null
不要使用 strategy = FieldStrategy.IGNORED,
不要使用 strategy = FieldStrategy.IGNORED,
不要使用 strategy = FieldStrategy.IGNORED,
3 为什么不建议使用注解
为了方法的通用性,updateById(T model)等其他更新方法,众所周知组装SQL一般会过滤null对应的字段(为null时不更新),但是,一旦加上了该注解,就会造成 updateById 的通用方法,有的过滤null,有的不过滤。。。这样的设计留的坑太大,稍不注意,就会把数据库对应的字段置为null…估计要跑路了
附:
//字段策略枚举类
public enum FieldStrategy {
IGNORED(0, “忽略判断”),
NOT_NULL(1, “非 NULL 判断”),
NOT_EMPTY(2, “非空判断”);
3、判断驱动表与非驱动表
1 LEFT JOIN 左连接,左边为驱动表,右边为被驱动表.
2 RIGHT JOIN 右连接,右边为驱动表,左边为被驱动表.
3 INNER JOIN 内连接, mysql会选择数据量比较小的表作为驱动表,大表作为被驱动表.
4 可通过EXPLANIN查看SQL语句的执行计划,EXPLANIN分析的第一行的表即是驱动表.
LEFT JOIN :左连接小表驱动大表
1 左边是驱动表,右边是被驱动表
2 小表驱动大表优于大表驱动小表
3 驱动表索引没有生效,被驱动表索引有效
LEFT JOIN: 内连接,表1驱动表2
1 数据库会自动选择数据量小的作为驱动表,大表作为被驱动表
2 执行效率,和左连接执行效率相差不大
3 驱动表索引没有生效,被驱动表索引有效
4 Exists和in的使用场景
SELECT * FROM A WHERE ID IN (SELECT ID FROM B) 1
当B表的数据较小时,IN 优于Exists.
SELECT * FROM A WHERE EXISTS (SELECT 1 FROM B WHERE B.ID = A.
PyTorch实现前馈神经网络(torch.nn) 1 回归任务 1.1 导入所需要的包1.2 自定义数据集1.3 构造数据迭代器1.4 模型构建1.5 参数初始化1.6 损失函数和优化器1.7 训练 1.7.1 定义训练函数1.7.2 开始训练模型1.7.3 绘制loss曲线2 二分类任务 2.1 导入所需要的包2.2 自定义数据集2.3 构造数据迭代器2.4 模型构建2.5 参数初始化2.6 损失函数和优化器2.7 训练 2.7.1 定义训练函数2.7.2 开始训练模型2.7.3 绘制loss曲线3 多分类任务 3.1 导入包3.2 下载MNIST数据集3.3 定义数据迭代器3.4 模型构建3.5 参数初始化3.6 损失函数和优化器3.7 定义准确率检验器3.8 训练 3.8.1 定义训练函数3.8.2 开始训练模型3.8.3 绘制loss、acc曲线 回归任务 该回归问题为高维回归问题,涉及的自变量过多,因此不适合用之前的线性回归模型,因为模型过于简单,导致训练的效率太低。因此我们考虑利用前馈神经网络,增加隐藏层,并且为了避免梯度消失问题,在隐藏层采用relu激活函数。
导入所需要的包 import torch from torch import nn from torch.nn import init import numpy as np from IPython import display import torch.utils.data as Data 自定义数据集 num_inputs = 500 num_examples = 10000 # true_w = torch.
BERT是google开源的一种自然语言处理领域的经典模型,全称是Bidirectional Encoder Representations from Transformers 。它使用多头注意力和位置嵌入,来替换不易并行的循环神经网络。它的出现一举打破自然语言处理领域11个不同问题的记录,直接将自然语言处理推动到了一个新的时代。
本实验使用pytorch的相关神经网络库, 编写BERT 的语言模型, 并基于训练好的词向量,利用少量的训练数据,微调BERT 模型用于文本分类任务。实验使用的数据集是IMDB数据集。实验的主要内容包括:
实验准备:搭建基于GPU的pytorch实验环境。下载IMDB数据集。数据预处理:使用pytorch所提供的标准数据接口,将原始数据处理为方便模型训练脚本所使用的数据结构。语言模型:参考《动手学深度学习》,搭建BERT 模型并加载大语料库上预训练的模型参数。推荐的预训练参数来源为huggingface。情感分类:基于训练好的语言模型,编写一个情感分类模型,包含一个BERT 模型和一个分类器(MLP)。首先,将一个句子中的每个单词对应的词向量输入BERT,得到句子的向量表征。然后将句向量作为分类器的输入,输出二元分类预测,同样进行loss 计算和反向梯度传播训练,这里的loss是交叉熵loss。此次实验中不固定BERT 模型的参数,而须随分类器一同训练以达到微调的目的。超参数调试:通过调整学习率等超参数提高情感分类模型的准确率。测试性能:选择在上一步中最合适的一组超参数训练得到最终的模型,然后在测试集上测试性能,并于第二次实验中采用RNN模型的实验结果进行对比分析。 相关的代码下载链接:从零开始在Pytorch实现Bert模型
Pytorch下用Bert+MLP实现文本情感分类网络 bert情感分类中用tokenizer实现文本预处理
pytorch实现具备预训练参数加载功能的bert模型
1.搭建实验环境 搭建GPU版Pytorch实验环境如下:
名称
版本
备注
Python
3.8
Pytorch
1.12.1
GPU
RTX2060
安装对应版本的cuda
2.下载IMDB数据集 下载IMDB数据集(地址:
https://ai.stanford.edu/~amaas/data/sentiment/
),解压后得到包含正负样本的电影评论数据集,具体如下:
3.数据预处理 对下载的数据集中的test和train分别进行预处理从而方便后续模型训练。预处理主要包括:txt文件读取、文本标签处理、特殊字符过滤、分词,使用了bert预训练模型的tokenizer将文本处理为bert所需输入形式,包括input_ids、token_type_ids和attention_mask以及每个文本的类别标签label。最后将处理后的数据,使用pickle 模块的 dump()方法进行序列化并存储,以方便后续调试。
读取IMDB数据
加载预训练的tokenizer并利用其对文本进行处理得到训练需要的输入数据集,其功能主要由ClsDataset()实现,核心代码如下。
数据集包括训练集、验证集和测试集,其中训练集和验证集由IMDB中的train文件夹中数据组成,总共25000个样本,随机分为训练集和验证集,大小分别为训练集20000样本,验证集5000样本,两个数据集不交叉。测试集由IMDB中的test文件夹中数据组成,用于最终的模型性能测试,大小为25000个样本。另外最终模型的训练在train文件夹的25000个样本上进行。
保存数据集
4.语言模型搭建和训练 4.1.搭建Bert模型 关于如何搭建Bert模型可以参考网上代码,或者参考本博客的相关文章和资源(
手动搭建Bert模型并实现与训练参数加载和微调)。
4.2.搭建情感分类模型 基于训练好的语言模型,编写一个情感分类模型,包含一个BERT 模型和一个分类器(MLP)。首先,将一个句子中的每个单词对应的词向量输入BERT,得到句子的向量表征。然后将句向量作为分类器的输入,输出二元分类预测,同样进行loss 计算和反向梯度传播训练,这里的loss是交叉熵loss。此次实验中不固定BERT 模型的参数,而须随分类器一同训练以达到微调的目的。
4.2.1.情感分类模型定义 情感分类模型,包含一个BERT 模型和一个分类器(MLP),两者间有一个dropout层,BERT模型实现了预训练参数加载功能。首先,将一个句子中的每个单词对应的词向量输入BERT,得到句子的向量表征。然后将句向量经过dropout层再输入分类器,最后输出二元分类预测。主要步骤及代码段如下:
4.2.2.训练情感分类模型 1)预训练模型和预处理数据集加载
加载预训练模型和预处理数据集,数据集为IMDB,预处理方法如3.3节所述,基于训练、验证、测试数据集构建了各自的迭代器train_loader、eval_loader、test_loader。
2)模型参数和训练参数定义
分别定义模型结构参数和训练的参数,其中由于GPU内存限制batch_size设置为4,但实际在训练时参数每8步更新一次,可以认为等效于每个batch_size为32.具体如下:
3)训练模型
实列化分类模型,并定义损失函数为CrossEntropyLoss(),优化器为Adam(),训练设备为GPU(cuda0),学习率等参数已在上一步说明,这些参数在训练中有调整。Bert模型的参数在实列化时加载了HuggingFace的bert_base_uncased预训练模型参数。
将模型设置为训练模式,加载输入样本和标签至GPU进行训练。
每个Epoch结束时,在验证集上测试模型的性能,包括分类准确度等指标,并保存当前表现最好的模型。
4.3.超参数分析和调试 在前述情感分类模型基础上对相关超参数进行了不同的调整、比较并分析了情感分类模型在各个情况下的性能。由于GPU内存限制和时间周期限制,并未对不同batchsize大小、不同优化器、MLP结构对模型性能的影响进行分析,仅分析比较了不同dropout和学习率对模型性能的影响。batchsize大小、不同优化器、MLP结构等超参数参考了《动手学深度学习》和网络上的资料设定,batchsize大小为32,优化器选择为Adam,MLP使用了1层,hidden_size大小与Bert输出维度一致为768。
5.实验结果 修改数据集,将训练集和验证集合并为训练集,在该数据集使用上一节分析得到的最优参数,Bert模型采用HuggingFace的bert_base_uncased预训练模型的结构参数,总共包含了12层Transformer。模型的其他参数也参考了HuggingFace的bert_base_uncased预训练模型的结构参数。vocab_size为bert_base_uncased预训练模型的字典大小,hidden_size为768,attention_head_num为12,intermediate_size为3072,hidden_act与论文中保持一致使用gelu,Dropout为0.1,学习率为5e-6,epoch为5。重新训练模型,并在测试集上进行模型性能测试。
目录
一、前言
二、使用coco128数据集进行训练
2.1 数据集准备
2.2 进行训练
三、使用自己制作的数据集进行训练和测试
3.1制作自己的数据集
3.2 开始训练
3.3 模型测试
四、让输入图片显示标签数量
一、前言 1.本文的目的在于帮助读者实现yolov5的训练,测试以及使用,偏重应用,将有较少代码讲解
2.本文将首先示范使用coco128数据集进行训练,向读者展示整个模型的使用过程,之后介绍如何制作自己的数据集并进行训练,最后一部分讲解如何让输出图片显示各个标签数量
3.本文使用的数据集coco128放在网盘里了,如果没有这个数据集的话可以去网盘上下载,yolov5的环境配置可以参考站内其他文章。
链接:https://pan.baidu.com/s/1MYSzPkPVUxpE1wt7zUxO0g 提取码:8r4i
二、使用coco128数据集进行训练 2.1 数据集准备 下好的数据集应该是如下图所示
images文件夹里存放的是我们要训练的图片,labels文件夹里存放的是打过标签的图片
目标检测需要手动进行打标签,这个我会在后面介绍使用自己数据集时进行详细介绍
2.2 进行训练 编译器这里我使用的Pycharm,打开项目如下图
这里我们需要知道两个yaml文件
第一个是data文件夹下的coco128.yaml 数据集参数文件
打开这个文件如下图,这个文件里是我们需要更改训练集以及测试集路径的地方,下面的names是每一个标签,可以看到coco128数据集里的标签数量是非常大的,我们平时自己玩的时候一般不会用到这么多标签。
接着我们需要了解的另一个文件是models文件夹下的从yolov5l到yolov5s的训练权重
我们打开yolov5s这个文件,如下图。这里nc是我们的标签数量。
以上两个文件我们目前都不用改,只是了解一下方便我们后面使用自己数据集进行测试时讲解
接着我们打开train.py文件,找到这个位置
--weights 初始训练权重
--cfg 模型参数位置
--data 数据集参数文件
直接开始运行train.py
慢慢等他跑完,最后的结果会存放在
exp到exp10都是你每次训练的结果,我这里训练了10次,所以有10个存放结果的文件夹
打开你最新的结果
weights是训练后模型的权重,随便点开val_batch1_pred.jpg可以看到训练后的效果
三、使用自己制作的数据集进行训练和测试 3.1制作自己的数据集 制作自己的数据集需要用到工具labelimg,直接在命令行输入下面这行代码进行下载
pip install labelimg -i https://pypi.tuna.tsinghua.edu.cn/simple 然后在yolov5项目的文件夹同级建立一个新的文件夹,文件夹名称可以自取,我这里使用DATA
并在DATA文件夹下创建如下两个文件夹和一个predefined_classes.txt文件
predefined_classes.txt是用来存放你的标签名称,我这里打三个标签分别是hair,eye,hands
接着,将你想要训练的图片放到images文件夹下(数据集100张以上才有一定效果,我这里拿105张动漫图片作演示)
命令行转到DATA文件夹 输入以下指令打开labelimg
labelimg images predefined_classes.txt 打开效果如下(右下角是文件列表,之前截图时候只放了三张所以列表里只有三张,训练时候有105张)
点击Change Save Dir选择DATA下的labels文件夹
1、instanceof说明 instanceof 是 Java 的保留关键字。作用是:测试它左边的对象是否是它右边的类的实例,返回 boolean 的数据类型。instanceof是Java中的二元运算符,左边是对象,右边是类;当对象是右边类或子类所创建对象时,返回true;否则,返回false。说明下:类的实例包含本身的实例,以及所有直接或间接子类的实例instanceof左边显式声明的类型与右边操作元必须是同种类或存在继承关系,也就是说需要位于同一个继承树,否则会编译错误 2、instanceof用法 2.1、左边的对象实例不能是基础数据类型 2.2、左边的对象实例和右边的类不在同一个继承树上 2.3、 null用instanceof跟任何类型比较时都是false 3、instanceof应用场景 instanceof一般用于对象类型强制转换
public class C extends B { private void print(Object a) { System.out.println(a+" instanceof"); } public void convert(String b) { if (b instanceof Object) { this.print(b); } } } public class InstanceofTest4 { public static void main(String[] args) { C c = new C(); c.convert("aa"); } } 输出结果: aa instanceof 应用示例
if (bookInfoList instanceof Page) { return ProductInfoServiceUtil.
查看原文:【数据seminar】GeoJSON 格式入门 —— 大数据处理地理信息的基础(内含中国省级数据)
目录
GeoJSON 的基础:JSON 格式
GeoJSON
GeoJSON 的区别
举个例子
获取地图信息
DataV
Geojson 是常见的一种地理信息的文件格式,基于JavaScript 对象表示法的地理空间信息数据交换格式。对于没有任何编程和基础的人来说,看到一串串的代码,就足够把人吓跑了。本文旨在通过浅显的语言,向大家介绍这种数据格式。相信大家在仔细阅读本文后,就能够自如的应付这种格式的文件。
GeoJSON 的基础:JSON 格式 JSON 格式是常见的用于数据传输的文件格式。语言描述容易显得太过复杂,我们举一个简单的例子(一看就会的那种):
一份JSON格式文件是这样的1:
可以看到,这份文件有“两层”内容,标示出来如下:
这么看,大概有些人已经猜到了,其实这个数据列成表格就是这样的:
这就是JSON 格式文件所实现的功能。可以简单的理解为将“一个表格的数据,用文字表述”2。
顺着这个思路,我们再仔细看看,这个文件的结构:首先,所有的内容都被包围在一个 「 {} 」 中,最大的{} 包裹了 「“people”:[{…},{…}]」的内容,所以 people 对于这组数据来说,是最大的一个变量(暂且这么称呼)。里面包含了两个变量(即"firstName”和"lastName")为一组的两组数据(即 “王 小明” 和“ 陈 小红”)。其中两组并列的数据用「,」(注意,是英文输入法下的「,」)隔开;一个变量下含有多个元素的用[]括住。这就是 JSON 格式的基础了。
对于 JSON 格式来说,people、firstName、lastName 这些其实并不叫变量,而是叫做 “Object”(对象),而其中“王”“小明”这样的数据,被称为 “Value”(值)。总的来讲,JSON 就是每一个 「变量」 都有对应的 「数值」 或者「 数值组合」 的数据格式,其本质就是一段字符串。
GeoJSON GeoJSON 的区别 GeoJSON 出现的目的就是为了表示地理空间信息。其实 GeoJSON 是JSON的一个子集。基本的语法结构上,两者其实是一样的,都是一个 Object 对应一个 Value 。但是不同点在于,GeoJSON 通过特定的 Object 来确定特定类型、特点功能的 Value。这其实很好理解,因为这些字符,是要排布在地图上的,而非在excel上。所以,需要有一些“变量”来储存位置信息,还有一些变量来储存我们要用的数据信息,所以要区分这些不同“功能”的变量,就需要约定一定的格式,来储存这些信息。这就是GeoJSON 和 JSON 的区别。
第11章:名字与地址转换 1、概述 这一章主要探讨实现主机名到ip地址、服务名到端口号之间转换的方法;
在IPv4的版本下,我们对应的有四个函数:
1. 主机名到ip地址,gethostbyname
2. ip地址反查主机名, gethostbyaddr
3.服务名到端口号, getservbyname
4.端口号反查服务名, getservbyport
上述的四个函数虽然好用,但是问题在于不兼容IPv6,于是我们引入了getaddrinfo函数,它会返回一个协议无关的地址信息的链表。围绕getaddrinfo函数,介绍了可以读取getaddrinfo函数返回值来返回错误信息的函数gai_strerror。同时由于getaddrinfo采用了动态内存的方式,我们引入freeaddrinfo来避免内存泄漏。
getaddrinfo虽然很强大,但是使用起来比较繁琐,有很多固定的处理逻辑。于是我们从不同的应用场景引入了五个对应的接口,我们用host_serv可以快速的基于主机名和服务名获取相对应的addrinfo而不用考虑内存释放、错误处理等。我们可以用tcp_connect,udp_client,udp_connect三个函数,来实现基于给定主机名(ip)和服务名(端口)来分别完成tcp客户连接,udp未连接套接字和udp已连接套接字,我们也可以用tcp_listen和udp_server来完成基于服务名字完成协议无关的服务器绑定。
我们然后提到了和getaddrinfo相对应的getnameinfo,它可以基于给定的套接字地址(包含了ip地址和端口号),反查出主机名字和服务名字。
最后我们提到了可重入函数的概念,不可重入的函数意味着如果信号处理函数和主控制流都调用了同一函数,那么存在着被覆盖重写的危险。我们指出ipv4的四个函数式不可重入的,而inet_ntoa(网络地址转换为ip地址字符串)也是不可重入的,inet_ntop(从网络地址转换为ip地址字符串)和inet_pton(将ip地址字符串转换为二进制数值)是可重入的,getaddrinfo和getnameinfo则是可重入的。我们指出errno虽然不是什么函数,但是由于其是进程独有(而不是线程独有),所以也有同样的风险。对于不可重入函数,我们建议在信号处理函数中避免调用,对于errno覆盖问题,我们建议采用事先保存,事后恢复值的办法。
2、域名系统(域名解析系统):实现了主机名与ip地址的映射;
主机名既可以是简单名字,例如host1,也可以是Fqdn全限定域名:主机名+域名:host1.baidu.com
资源记录:
DNS中的条目被称之为资源记录(RR),我们感兴趣的主要就几种
名称 示例 作用
A freebsd in A 12.106.32.254 将主机名字映射成IPv4地址;
AAAA freebsd in AAAA 3ffe:b80:1f8d:1:a00:20ff:fea7:686b 将主机名字映射成IPv6地址;
PTR 指针记录,将ip地址映射成主机名,是A、4A记录的反向记录;构建记录的结果字符串:
ipv4:32位ip地址的每个字节反转,然后在末尾加上in-addr.arpa;
ipv6:128位的32个四位组反转顺序,末尾加上ip6.arpa,兼容早期标准的Ip6.int;
使用nslookup命令来查询PRT记录,如:
nslookup -qt=prt 202.108.3.184
这个IP是 sina 的邮件主机,查询结果是:
184.3.108.202.in-addr.arpa name = mail3-184.sinamail.sina.com.cn.
如果IP没有反向解析,一般返回:
** server can't find 65.20.211.58.in-addr.arpa: NXDOMAIN
反向解析就是通过查询ip地址对应的ptr记录来得到该地址指向的域名;
和A记录相反,存储的是 ip 地址对应的主机名,该记录只存在于反向解析的区域数据文件中(并非一定)。PTR记录可以用来做垃圾邮件核验,比如以baidu域名发送邮件到163邮箱,163邮箱会对你的域名和你的IP地址校验看是否是baidu对应的地址,如果不是会被退信;
举例:
上例中的两个PTR记录分别为:
254.32.106.12.in-addr.arpa
b.6.8.6.7.a.e.f.f.f.0.2.0.0.a.0.0.a.0.1.0.0.0.d.8.f.1.0.8.b.0.e.f.f.3.ip6.arpa
MX 邮件交换记录,它指向一个邮件服务器,用于电子邮件系统发邮件时根据收信人的地址后缀来定位查找域名的mx记录然后定位到指定的邮件服务器。
CNAME ftp in cname linux.
安装依赖 pnpm add live2d-widget@latest --save 初始化以vue为示例 创建l2d.js(由于这个库是js写的所以ts不友好直接用js来写了)
import { L2Dwidget } from 'live2d-widget/lib/L2Dwidget.common.js' L2Dwidget.init({ tagMode: false, log: false, model: { jsonPath: 'http://1。xxx.xxx.xxx:8001/haru01.model.json' }, display: { position: 'left', width: 250, height: 400 }, mobile: { show: false } }) 更改模型 1.配置中的model为模型配置有现成的
"model": { // jsonPath: "https://unpkg.com/live2d-widget-model-chitose@1.0.5/assets/chitose.model.json", // jsonPath: "https://unpkg.com/live2d-widget-model-haruto@1.0.5/assets/haruto.model.json", // jsonPath: "https://unpkg.com/live2d-widget-model-hibiki@1.0.5/assets/hibiki.model.json", // jsonPath: "https://unpkg.com/live2d-widget-model-hijiki@1.0.5/assets/hijiki.model.json", // jsonPath: "https://unpkg.com/live2d-widget-model-izumi@1.0.5/assets/izumi.model.json", // jsonPath: "https://unpkg.com/live2d-widget-model-koharu@1.0.5/assets/koharu.model.json", // jsonPath: "https://unpkg.com/live2d-widget-model-miku@1.0.5/assets/miku.model.json", // jsonPath: "https://unpkg.com/live2d-widget-model-ni-j@1.0.5/assets/ni-j.model.json", jsonPath: "https://unpkg.com/live2d-widget-model-shizuku@1.0.5/assets/shizuku.model.json", // jsonPath: "
目录
第一题:不同子串编辑
第二题:成绩排名
第三题:承压计算
第四题:乘积尾零
第五题:单词分析
第六题:等差数列
第七题:递归倒置字符数组
第八题:递增三元组
第九题:第几个幸运数
第十题:分解质因数(感觉这题比较难理解)
第一题:不同子串 s1 = '0100110001010001' ls1 = [] for i1 in range(len(s1)): for i2 in range(len(s1)+1): if s1[i1:i2] not in ls1 and s1[i1:i2] != '': ls1.append(s1[i1:i2]) print(len(ls1)) 第二题:成绩排名 n = int(input()) information = [] for i1 in range(n): inf = input().strip().split() information.append(inf) information.sort(key=lambda x: int(x[1]), reverse=True) # 排成绩从大到小 for i in range(n): print(information[i][0]) 第三题:承压计算 '''试题文件 pyramid.txt ''' 7 5 8 7 8 8 9 2 7 2 8 1 4 9 1 8 1 8 8 4 1 7 9 6 1 4 5 4 5 6 5 5 6 9 5 6 5 5 4 7 9 3 5 5 1 7 5 7 9 7 4 7 3 3 1 4 6 4 5 5 8 8 3 2 4 3 1 1 3 3 1 6 6 5 5 4 4 2 9 9 9 2 1 9 1 9 2 9 5 7 9 4 3 3 7 7 9 3 6 1 3 8 8 3 7 3 6 8 1 5 3 9 5 8 3 8 1 8 3 3 8 3 2 3 3 5 5 8 5 4 2 8 6 7 6 9 8 1 8 1 8 4 6 2 2 1 7 9 4 2 3 3 4 2 8 4 2 2 9 9 2 8 3 4 9 6 3 9 4 6 9 7 9 7 4 9 7 6 6 2 8 9 4 1 8 1 7 2 1 6 9 2 8 6 4 2 7 9 5 4 1 2 5 1 7 3 9 8 3 3 5 2 1 6 7 9 3 2 8 9 5 5 6 6 6 2 1 8 7 9 9 6 7 1 8 8 7 5 3 6 5 4 7 3 4 6 7 8 1 3 2 7 4 2 2 6 3 5 3 4 9 2 4 5 7 6 6 3 2 7 2 4 8 5 5 4 7 4 4 5 8 3 3 8 1 8 6 3 2 1 6 2 6 4 6 3 8 2 9 6 1 2 4 1 3 3 5 3 4 9 6 3 8 6 5 9 1 5 3 2 6 8 8 5 3 2 2 7 9 3 3 2 8 6 9 8 4 4 9 5 8 2 6 3 4 8 4 9 3 8 8 7 7 7 9 7 5 2 7 9 2 5 1 9 2 6 5 3 9 3 5 7 3 5 4 2 8 9 7 7 6 6 8 7 5 5 8 2 4 7 7 4 7 2 6 9 2 1 8 2 9 8 5 7 3 6 5 9 4 5 5 7 5 5 6 3 5 3 9 5 8 9 5 4 1 2 6 1 4 3 5 3 2 4 1 X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X '''先读取文件成为列表''' f = open('pyramid.
Focal and Global Knowledge Distillation for Detectors Abstract 在目标检测当中,老师的特征和学生的特征在不同的区域有很大的变化,尤其是在前景和背景中。因此,如果我们平等地蒸馏,特征图之间的差异会恶化结果。(PS:目标检测中的蒸馏会比对教师模型和原模型的特征图)
翻译:前景不好学,背景很好学,如果这两部分内容进行一样地教授,效果不大好。
因此,我们提出了聚焦且全局蒸馏。聚焦蒸馏分割前景和背景,强迫学生关注教师的关键像素及通道;全局蒸馏则重建不同像素之间的关系,并将这一知识传递给学生。
微信链接
Method 通常而言,教师和学生之间的蒸馏过程如下所示:
f是调整通道,用于让教师特征和学生特征的通道保持一致。
这样一种方法平等地对待所有部分并且缺乏不同像素之间全局关系的蒸馏。
Focal Distillation 首先设置一个区分前景和背景的mask:
其中r表示GT boxes。
不同大小的目标会有不一样的损失,为了平衡这一问题,本文采用了一个规模化的mask:
Hr、Wr表示GT框的大小,
SENet和CBAM给出结论:关注重要的像素和通道有助于基于CNN的模型得到更好的结果。这里计算了像素或者通道层面的绝对平均值:
之后得到注意力图:
最终,我们的特征图损失如下:
其中的注意力mask采用的是教师模型的。
除此之外,还对学生得到的注意力图和教师的注意力图进行损失计算,其中l是L1loss:
Global Distillation 采用GcBlock来捕捉全局关系信息,并以此进行蒸馏:
对每一像素的一种重新赋值。
Decoupled Knowledge Distillation 知乎链接
logit蒸馏 和 特征蒸馏
前者计算量小且语义程度高,后者反之。理论来说高维语义特征的效果应该更加好,但事实却不是如此。
实验表明:只有应用NCKD才能获得与经典KD相当甚至更好的结果。
上述实验揭示了logit蒸馏效果不好的原因:经典的KD损失是高度耦合的形式。NCKD损失带有的权重与teacher在目标预测上的置信度是负相关的,即大的预测分数会带来小的权重。值得一提的是,训练样本的置信度普遍较高。
另外,如果训练数据越难,TCKD带给学生的提升就越大。
TCKD适合教难的,NCKD适合教简单的。但是一遇到简单的样本,在经典的KD损失中,NCKD的能力会被抑制。
Co-advise: Cross Inductive Bias Distillation 决定学生能力提升的不是教师的能力而是教师给予的归纳偏置;不同归纳偏置的给予可以带来更好的能力提升;token与教师的对齐有助于学习。
Linux 安装环境必须先具备gcc编译环境 版本选择
查看自己redis版本的命令
安全Bug按照官网提示,升级成为6.0.8及以上
目前建议都需要升级到6.0.8版本以上
本次我们用Redis7.0
Redis7安装步骤 下载获得redis-7.0.0.tar.gz后将它放入Linux目录/opt
/opt目录下解压redis
tar -zxvf redis-7.0.0.tar.gz
进入目录
在redis-7.0.0目录下执行make命令
查看默认安装目录: usr/local/bin
Linux下的/usr/local类似于Windows下的C:/Program Files
redis-bepchmark:性能测试工具,服务启动后运行该命令,看看自己本子性能如何
redis-check-aof:修复有问题的AOF文件
redis-check-dump:修复有问题的dump.rdb文件
redis-cli:客户端,操作入口
redis-sentinel: redis集群使用
redis-server: Redis服务器启动命令
将默认的redis.conf拷贝到自己定义好的一个路径下,比如/myredis
修改/myredis目录下redis.conf配置文件做初始化设置
redis.conf配置文件,改完后确保生效,记得重启redis服务,否则配置不会生效
默认daemonize no 改为daemonize yes
默认protected-mode yes 改为protected-mode no
默认bind 127.0.0.1 改为直接注释掉(默认bind 127.0.0.1只能本机访问)或改成本机IP地址,否则影响远程IP连接
添加redis密码 改为requirepass你自己设置的密码
启动redis服务
# 使用redis-server命令,后接redis的配置文件 redis-server /myredis/redis7.conf # 查看redis服务是否启动 ps -ef | grep redis | grep -v grep ... *:6379 # 说明成功启动 连接服务 # 使用redis-cli -a 密码 [-p 端口号] 连接服务 redis-cli -a 123456 -p 6379 # 命令端出现如下表示成功 127.
slurm 0.Pytorch环境问题1.slurm作业管理系统2.sinfo查看系统资源3.squeue查看作业状态4.srun交互式提交作业5.sbatch后台提交作业6.salloc分配模式作业提交7.scancel取消已提交的作业8.scontrol查看正在运行的作业信息9.sacct查看历史作业信息10.xxx.slurm作业模版11.关于联网12.Linux 常用命令13.官网手册14.完整的一套流程 0.Pytorch环境问题 pytorch最好这样装:
conda install pytorch==1.13.0 torchvision==0.14.0 torchaudio==0.13.0 pytorch-cuda=11.6 -c pytorch -c nvidia 1.slurm作业管理系统 系统使用Slurm作业管理系统,采用共享模式。为避免系统资源浪费,使用时请尽量保证满核提交(即为单节点核数的整数倍),不要在登录节点直接运行计算程序。作业管理系统常用命令如下:
sinfo:显示系统资源使用情况squeue:显示作业状态srun:用于交互式作业提交sbatch:用于批处理作业提交salloc:用于分配模式作业提交scancel:用于取消已提交的作业scontrol:用于查询节点信息或正在运行的作业信息sacct:用于查看历史作业信息 2.sinfo查看系统资源 sinfo得到的结果是当前账号可使用的队列资源信息,如下所示:
第一列PARTITION是队列名。第二列AVAIL是队列可用情况,如果显示up则是可用状态;如果是inact则- 是不可用状态。第三列TIMELIMIT是作业运行时间限制,默认是infinite没有限制。第四列NODES是节点数。第五列STATE是节点状态,idle是空闲节点,alloc是已被占用节点,comp是正在释放资源的节点,其他状态的节点都不可用。第六列NODELIST是节点列表。 sinfo的常用命令选项:
sinfo -n comput1
指定显示节点comput1的使用情况sinfo -p com
指定显示队列com情况其他选项可以通过sinfo --help查询 3.squeue查看作业状态 squeue得到的结果是当前账号的作业运行状态,如果squeue没有作业信息,说明作业已退出。
第一列JOBID是作业号,作业号是唯一的。第二列PARTITION是作业运行使用的队列名。第三列NAME是作业名。第四列USER是超算账号名。第五列ST是作业状态,R表示正常运行,PD表示在排队,CG表示正在退出,S是管理员暂时挂起。第六列TIME是作业运行时间。第七列NODES是作业使用的节点数。第八列NODELIST(REASON) 对于运行作业(R状态)显示作业使用的节点列表;对于排队作业(PD状态),显示排队的原因。
squeue的 常用命令选项:
queue -j 123456
查看作业号为123456的作业信息squeue -u paratera
查看超算账号为 paratera的作业信息squeue –p com
查看提交到com队列的作业信息squeue -w comput1
查看使用到comput1节点的作业信息其他选项可通过squeue --help命令查看。 4.srun交互式提交作业 srun [options] program命令属于交互式提交作业,有屏幕输出,但容易受网络波动影响,断网或关闭窗口会导致作业中断。
srun 命令示例:
srun -p com -w comput[1-2] -N 2 -n 40 -t 20 A.
目录
一、什么是缓存?
二、Web缓存
(一)前端缓存
(二)后端缓存
三、Django缓存
(一)缓存类型
(二)设置缓存
1.Memcached
2.Redis
3.数据库缓存
4.文件系统缓存
5.本地内存缓存
6.虚拟缓存(用于开发模式)
7.使用自定义缓存后端
8.缓存参数
(四)站点缓存
(五)视图缓存
(六)在 URLconf 中指定视图缓存
(七)模板片段缓存
(八)底层缓存 API
(九)访问缓存
四、基本用法
1.缓存键前缀
2.缓存版本控制
3.缓存键转换
4.缓存键警告
五、异步支持
六、注意事项
一、什么是缓存? 缓存的定义:缓存(cache),原始意义是指访问速度比一般随机存取存储器(RAM)快的一种高速存储器,通常它不像系统主存那样使用DRAM技术,而使用昂贵但较快速的SRAM技术。缓存的设置是所有现代计算机系统发挥高性能的重要因素之一。
缓存的优点汇总,加快页面打开速度,减少网络带宽消耗,降低服务器压力。
具体工作原理可参考:缓存_百度百科 (baidu.com)。通俗的说,这里涉及到计算机的各种存储,内存、磁盘、cpu等都算是计算机的存储器。
二、Web缓存 我们的django程序是计算机的一个进程,进程是运行在内存上的,当用户访问时,会在进程中开启一个线程处理请求。
(一)前端缓存 前端缓存即浏览器缓存,可以解决减轻请求服务器的频次、提高页面展示效率。在实际开发中,因网站的性质不同,往往会考虑缓存的问题。一般的展示型网站(官网、介绍等)为了减轻请求服务器的频次、提高页面展示效率将设置缓存配置。
前端缓存是根据请求头headers的expires和cache-control判断是否重新请求服务器,缓存的对象为html、css、js、图片等静态文件。
(二)后端缓存 通常情况下,计算一个值是很昂贵的(也就是耗费资源,而且速度很慢),所以把值保存到快速访问的缓存中,为下次需要时做好准备,会有巨大的好处。
Django 自带强大的缓存系统,可以让你保存动态页面,这样就不必为每次请求计算。为了方便,Django 提供了不同级别的缓存粒度。你可以缓存特定视图的输出,你可以只缓存难以生成的部分,或者你可以缓存整个网站。
三、Django缓存 (一)缓存类型 Memcached:一种高性能的分布式内存对象缓存系统,用于动态网站,以减轻数据库负载。
Redis:
数据库缓存:缓存信息存储在网站数据库的缓存表中,缓存表可以在项目的配置文件中配置,适合大中型网站使用。
文件系统缓存:缓存信息以文本文件格式保存,适合中小型网站使用。
本地内存缓存:django默认的缓存保存方式,将缓存存放在项目所在系统的内存中,之适用于项目开发测试。
虚拟缓存:django内置的虚拟缓存,市级上只提供缓存接口,并不能存储缓存的相关配置。
(二)设置缓存 缓存系统需要少量的设置。也就是说,你必须告诉它你的缓存数据应该放在哪里 —— 是在数据库中,还是在文件系统上,或者直接放在内存中。这是一个重要的决定,会影响你的缓存的性能;是的,有些缓存类型比其他类型快。
缓存设置项位于你的配置文件的缓存配置中。这里有缓存配置所有可用值的说明。
1.Memcached Memcached 以一个守护进程的形式运行,并且被分配了指定数量的 RAM。它所做的就是提供一个快速接口用于在缓存中添加,检索和删除数据。所有数据都直接存储在内存中,因此不会产生数据库或文件系统使用的开销。
在安装了 Memcached 本身之后,你需要安装一个 Memcached 绑定。有几个 Python Memcached 绑定可用;Django 支持的两个绑定是 pylibmc 和 pymemcache 。
目录
一、IO(输入输出流)图例
二、字节流和字符流:
三、InputStream输入流(把数据从文件读取到内存中):
InputStream代码示例:
四、OutputStream输出流(把数据从内存写入到目标文件中):
OutputStream代码示例:
五、注意事项:
一、IO(输入输出流)图例 输入还是输出是相对内存(缓冲区)而言的,而InputStream和OutputStream读取的是二进制文件
二、字节流和字符流: 字节流字符流读取方式基于二进制的读取方式基于字符的读取方式Java中对应抽象类InputStream/OutputStreamReader/WriterJava中对应实现类FileInputStream/FileOutputStreamFileReader/FileWriter 三、InputStream输入流(把数据从文件读取到内存中): 修饰符及 返回值类 型 方法名 说明 int read() 读取一个字节的数据,返回 -1 代表已经完全读取完成 int read(byte[]b) 最多读取 b.length 字节的数据到 b 中并返回实际读到的数 量; -1 代表以及读取完成 int read(byte[] b, int off, int len) 最多读取 len - off 字节的数据到 b 中,放在从 off 开始,返 回实际读到的数量; -1 代表读取完成 void close() 关闭字节流(基于二进制的读取方式) InputStream代码示例: import java.io.FileInputStream; import java.io.IOException; public class IO_InputStream { public static void main(String[] args) throws IOException { //创建输入流读取文件内容 FileInputStream fileInputStream = new FileInputStream("
目录
MYSQL备份恢复管理
一,备份类型
二,逻辑备份优缺点
三,MySQL备份内容 四,MySQL备份工具
五,MySQL备份策略
1,策略一:直接拷贝数据库文件
案例:直接拷贝备份数据库company
2,策略二:mysqldump备份数据库
案例一:备份恢复单个数据库
案例二:备份单个表
案例三:备份数据库的结构
案例四:mysqldump+binlog 完全+增量备份恢复
六,binlog日志的GTID新特性
1,什么是GTID
2,GTID的格式与存储
3,版本支持
4,如何开启
5, DDL和DML语句查看gtid
6,基于GTID进行查看binlog
案例:演示跨binlog文件截取日志。
MYSQL备份恢复管理 一,备份类型 热备份、温备份、冷备份 (根据服务器状态)
热备份:读、写不受影响;
温备份:仅可以执行读操作;
冷备份:离线备份;读、写操作均中止;
物理备份与逻辑备份 (从对象来分)
物理备份:复制数据文件;
逻辑备份:将数据导出至文本文件中;
完全备份、增量备份、差异备份 (从数据收集来分)
完全备份:备份全部数据;
备份速度慢,恢复快
增量备份:仅备份上次完全备份或增量备份以后变化的数据;
备份速度快,恢复慢;
差异备份:仅备份上次完全备份以来变化的数据;
备份速度慢,恢复快;
二,逻辑备份优缺点 (1)逻辑备份的优点:
在备份速度上两种备份要取决于不同的存储引擎
物理备份的还原速度非常快。但是物理备份的最小力度只能做到表
逻辑备份保存的结构通常都是纯ASCII的,所以我们可以使用文本处理工具来处理
逻辑备份有非常强的兼容性,而物理备份则对版本要求非常高
逻辑备份也对保持数据的安全性有保证
(2)逻辑备份的缺点:
逻辑备份要对RDBMS产生额外的压力,而裸备份无压力
逻辑备份的结果可能要比源文件更大。所以很多人都对备份的内容进行压缩
逻辑备份可能会丢失浮点数的精度信息
三,MySQL备份内容 数据文件
日志文件(比如事务日志,二进制日志)
存储过程,存储函数,触发器
配置文件(十分重要,各个配置文件都要备份)
用于实现数据库备份的脚本,数据库自身清理的Crontab等……
四,MySQL备份工具 Mysql自带的备份工具
mysqldump 逻辑备份工具,支持所有引擎,MyISAM引擎是温备,InnoDB引擎是热备,备份速度中速,还原速度非常非常慢,但是在实现还原的时候,具有很大的操作余地。具有很好的弹性。
mysqlhotcopy 物理备份工具,但只支持MyISAM引擎,基本上属于冷备的范畴,物理备份,速度比较快。
文件系统备份工具
cp 冷备份,支持所有引擎,复制命令,只能实现冷备,物理备份。使用归档工具,cp命令,对其进行备份的,备份速度快,还原速度几乎最快,但是灵活度很低,可以跨系统,但是跨平台能力很差。
目录 数据挖掘
一、数据挖掘理解
二、数据准备
1、缺失值处理
2、异常值处理
3、数据偏差的处理
4、数据的标准化
5、特征选择
三、数据建模
1、分类问题
2、聚类问题
3、回归问题
4、关联问题
四、评估模型
1、混淆矩阵与准确率指标
2、评估数据的处理
业务理解、数据理解、数据准备、构建模型、评估模型、模型部署。
一、数据挖掘理解 业务理解和数据理解
思考问题
数据挖掘只能在有限的资源与条件下去提供最大化的解决方案
把握数据
主要是看是否有数据、有多少数据、是什么样的数据、数据标签
二、数据准备 找到数据
数据探索
数据清洗
1、缺失值处理 删掉有缺失值的数据;补充缺失值;不做处理。
2、异常值处理 不同情况的异常值有不同的处理办法:
数据本身的错误,需要对数据进行修正,或者直接丢弃;数据是正确的,需要根据你的业务需求进行处理。如果你的目标就是发现异常情况,那么这种异常值就需要保留下来,甚至需要特别关照。如果你的目标跟这些异常值没有关系,那么可以对这些异常值做一些修正,比如限定最大值和最小值的标准等,从而防止这些数据影响你后面模型的效果。 3、数据偏差的处理 如果你需要比较均衡的样本,那么通常可以考虑丢弃较多的数据,或者补充较少的数据。
在补充较少的数据时,又可以考虑使用现有数据去合成一些数据,或者直接复制一些数据从而增加样本数量。当然了,每一种方案都有它的优点和缺点,具体的情况还是要根据目标来决定,哪个对目标结果的影响较小就采取哪种方案。
4、数据的标准化 http://t.csdn.cn/pz63Y
可以看我之前总结的文章。
5、特征选择 维度越多,数据就会越稀疏,模型的可解释性就会变 差、可信度降低。
这个时候就需要用到特征选择的技巧,比如自然语言处理里的关键词提取,或者去掉屏蔽词,以减少不 必要的数据维度。
构建训练集和测试集
在数据进入模型之前,你还需要对其进行数据采样处理。如果说前面的部分是为了给模型提供一个好的 学习内容,那么数据采样环节则是为了评估模型的学习效果。 在训练之前,你要把数据分成训练集和测试集,有些还会有验证集。
如果是均衡的数据,即各个分类的数据量基本一致,可以直接随机抽取一定比例的数据作为训练样 本,另外一部分作为测试样本。如果是非均衡的数据,比如在风控型挖掘项目中,风险类数据一般远远少于普通型数据,这时候使 用分层抽样以保障每种类型的数据都可以出现在训练集和测试集中。 当然,训练集和测试集的构建也是有方法的,比如:
留出法,就是直接把整个数据集划分为两个互斥的部分,使得训练集和测试集互不干扰,这个是最 简单的方法,适合大多数场景;交叉验证法,先把数据集划分成 n 个小的数据集,每次使用 n-1 个数据集作为训练集,剩下的作 为测试集进行 n 次训练,这种方法主要是为了训练多个模型以降低单个模型的随机性;自助法,通过重复抽样构建数据集,通常在小数据集的情况下非常适用。 三、数据建模 1、分类问题 分类是有监督的学习过程。
分类问题中包括以下 3 种情况:
二分类。 这是分类问题里最简单的一种,因为要回答的问题只有 “是” 或“否”。比如我在处理用户 内容时,首先要做一个较大的分类判断,即一条内容是否属于旅游相关内容,这就是二分类问题, 得出的结论是这条内容要么是旅游相关,要么不是旅游相关。多分类。 在二分类的基础上,将标签可选范围扩大。要给一条内容标注它的玩法,那种类就多 了,比如冲浪、滑雪、自驾、徒步、看展等,其种类甚至多达成百上千个标签。多标签分类。 是在多分类基础上再升级的方法。对于二分类和多分类,一条内容最后的结果只有 一个,标签之间是互斥的关系。但是多标签分类下的一条数据可以被标注上多个标签。比如一个人 在游记里既可以写玩法,也可以写美食,这两者并不冲突。 由于分类问题众多,所以用来解决分类问题的算法也非常多,像 KNN 算法、决策树算法、随机森林、SVM 等都是为解决分类问题设计的。
1.if语句 1.1什么是选择结构 1.1.1定义 选择结构又称为分支结构,是根据给定的条件是否成立来决定程序的执行流程。
1.1.2图示 1.2单分支if语句 1.2.1语句格式 if 条件 %关系运算或逻辑运算 语句组 %可以是一条语句也可以是多条语句 end 补充——MATLAB代码注释的方法
(1)单行注释:% + 注释内容
(2)多行注释:%{ 要注释的多行内容 %}
(3)快捷键: Ctrl + R 选中内容即可注释,Ctrl + T取消选中内容的注释
1.2.2图示 1.2.3条件解释 当条件结果为标量时,非零表示条件成立,零表示条件不成立。当条件结果为矩阵时,如果矩阵为非空,且不包含零元素,则条件成立,否则,不成立。例如[1 2 3 4 5]表示条件成立,[0 1 2 3 4]表示条件不成立 1.3双分支if语句 1.3.1语句格式 if 条件 语句组1 else 语句组2 end 1.3.2图示 1.3.3运用 1.4多分枝if语句 1.4.1语句格式 if 条件1 语句组1 elseif 条件2 语句组2 ... elseif 条件m 语句组m else 语句组n end 1.4.2图示 1.4.3运用 2.switch语句 2.1语句格式 switch 表达式 case 结果表1 语句组1 case 结果表2 语句组2 .
文章目录 一、显卡驱动安装二、安装anaconda二、cuda安装三、查看path是否有添加成果查看cuda版本 四、安装pytorch更新pip安装pytorch 五、安装pycharm六、查看pytorch 和 gpu是否可以使用总结 一、显卡驱动安装 搜索适合你电脑的显卡驱动,安装studio版本。
二、安装anaconda 具体安装步骤参考其他教程。
二、cuda安装 选择你的系统支持的cuda。
三、查看path是否有添加成果 进入 :我的电脑-属性-高级系统设置
进入环境变量。
可以安装多个cuda版本。
查看cuda版本 nvcc -V 四、安装pytorch 更新pip 安装pytorch 进入pytorch官网 https://pytorch.org/
选择适合系统的pyrorch版本。
五、安装pycharm 请查看其他教程。
配置pycharm编译环境和配套的包。
六、查看pytorch 和 gpu是否可以使用 import torch print(torch.__version__) print('g:',torch.cuda.is_available()) 成功了 !!!
总结
YOLOv3网络结构 文章目录 YOLOv3网络结构简介实现原理整体结构图示各结构组成及分析1. backbone部分2. neck部分3. head部分 输出解耦 简介 YOLOv3是一种基于深度学习的目标检测算法,由Joseph Redmon等人于2018年提出。YOLOv3是YOLO系列的第三个版本,相比于前两个版本,YOLOv3在速度和精度上都有了很大的提升,相较于YOLOv2的主要变化在于引入了多尺度的概念。
实现原理 YOLOv3实现的大致原理是由卷积神经网络(CNN)网络的输出把图片分成N×N个网格,然后每个网格负责去检测那些中心点落在该格子内的目标。YOLOv3设定的是每个网格单元预测3个box,所以每个box需要有 (x, y, w, h, confidence)五个基本参数,然后根据数据集的类型的不同还要有20或80个类别的概率。
整体结构图示 各结构组成及分析 1. backbone部分 YOLOv3使用了darknet-53的前面的52层(没有用于图像分类的全连接层)作为backbone部分,这部分是通用的,也可以加上全连接层拿来做图像分类等任务。
DarkNet53中大量使用残差结构的跳层连接,并且为了降低池化带来的梯度负面效果,作者直接摒弃了POOLing,用conv的stride来实现降采样。
如上图所示,蓝色方块×1,×2,×8分别表示该模块重复1次、2次和8次,橙色方块是该模块的名字,Conv Block 表示该模块是一个普通的卷积模块,Residual Block 代表该模块是一个残差网络结构(残差网络具体结构见《常用的卷积结构》)。
2. neck部分 YOLOv3的neck部分使用的是FPN,FPN是特征金字塔网络的缩写。它是一种特征提取方法,可用于目标检测任务。FPN可以从图像中提取不同尺度和分辨率的特征,然后将它们组合成一个特征金字塔。这个特征金字塔可以用于检测图像中不同大小的物体。
如上图所示,backbone部分输出的shape分别为(13,13,1024),(26,26,512),(52,52,256)。将这三个输出分别输入到FPN中,(13,13,1024)这一个输入,经过5次卷积后,输出(13,13,512),然后兵分两路,一路传入到head中,一路再经过一个卷积和上采样,得到(26,26,256),将这个输出和backbone的第2个输出也就是(26,26,512)进行堆叠操作(concat),得到(26,26,768)。以此类推:(26,26,768)再经过5次卷积,然后兵分两路,将上采样输出和backbone的输出进行堆叠操作;最后对(52,52,256)的输出也进行相同操作。最终得到三个分支来传给head部分。
区别concat与add操作:concat操作是把两个矩阵通道堆叠到一起,里面的数据不变,通道数为两者相加;add操作是把两个矩阵数据加在一起,两者通道数相同且不变,只是单纯的数据相加。
3. head部分 YOLOv3的head部分是YOLOv3的检测头部分,用于将neck部分的输出特征图转换为检测结果。YOLOv3的head部分包括三个卷积层,其中两个卷积层使用1×1卷积核,以减少特征图的通道数,最后一个卷积层使用1×1卷积核和3×3卷积核,以生成最终的检测结果。
如上图,FPN输出的3个分支,通过两层卷积输出预测head。这里最终输出的形式为:batchSize×(4+1+类别总数)×特征图宽×特征图宽。其中的4为预测框的tx,ty,tw,th。这里假定采用coco数据集,有80个类别,所以输出的tensor的channel输为255。
输出解耦 YOLOv3网络在head部分输出后还要经历对输出解耦的部分。具体实现过程如下:
我们以13×13的输出为例,原本416×416大小变成13×13,相当于缩小了416/13=32倍,也就是说原图32×32个小方块对应于最后输出的1×1的像素点。
如下图,蓝色的是实际的标注框,粉红色的是对应到13×13上的先验框,先验框是固定不变的,它的中心就是落在13×13的交点上,长宽就是除以32的结果每个特征图。由于先验框是我们一开始自己确定的,显然是不正确,需要模型对它调整。
我们将初始先验框坐标记为(cx,cy,pw,ph),模型输出的4为(tx,ty,tw,th),调整的公式如上图所示,中心点取sigmoid激活函数,sigmoid函数范围是0~1,也就是中心点的调整范围永远在右下角的框内,这也就是我们说的,物体的中心落在哪个格子里,该物体就由哪个框负责预测。
范围永远在右下角的框内,这也就是我们说的,物体的中心落在哪个格子里,该物体就由哪个框负责预测。
最后将长宽取exp后与先验框对应坐标相乘。这就得到了在13×13尺寸图上的预测框,然后再乘以32缩放回来就得到了最后的预测框。
1.npm i @vueuse/core 或者 yarn add @vueuse/core 2. 创建公共方法文件夹 src/hooks / index.js建议起名 // 按需引入懒加载 import { useIntersectionObserver } from '@vueuse/core' import { ref } from 'vue' export const useLazyData = (apiFn) => { const result = ref([]) // 数据对象存储 const target = ref(null) // dom对象 // 停止观察 const { stop } = useIntersectionObserver( target, ([{ isIntersecting }], observerElement) => { if (isIntersecting) { stop() // 调用API获取数据 apiFn().then(data => { result.
本文目录 1、延时---Delay1.1、enp2s0 网卡上增加100ms延时1.2、enp2s0 网卡上增加100ms ± 20ms的延时(80ms到120ms)1.3、enp2s0 网卡上增加100ms ± 20ms的延时(80ms到120ms),并且设置相关系数为50%1.4、enp2s0 网卡上增加100ms ± 20ms的延时(80ms到120ms),报文延时分布满足正态分布 2、丢包率---loss2.1、enp2s0 网卡模拟发送的报文有 16% 的丢包率2.2、enp2s0 网卡模拟发送的报文使用loss state/loss gemodel模型进行丢包2.3、enp2s0 网卡模拟发送的报文选用loss state/loss gemodel模型进行丢包时的enc选项 3、损坏/错误报文---corrupt3.1、enp2s0 网卡模拟发送的报文中随机选取 25%变成损坏的报文(在被随机选中做为错误报文的随机位置造成一个错误) 4、重复报文---duplicate4.1、enp2s0 网卡模拟发送的报文中随机选取 25%产生重复报文 5、乱序---reorder5.1、enp2s0 网卡模拟发送的报文中每5个报文就产生一个乱序包5.2、enp2s0 网卡模拟发送的报文中以50%的概率完全随机产生乱序包 6、基于报文数量(令牌桶TBF)的限速---limit7、基于报文长度的限速---rate8、基于时间窗的延时与限速---slot NetEm 是Linux的TC(traffic control)下的那个增强工具,使用这个工具可以在指定的网卡的发送方向上,注入网络延迟、丢包、重复、损坏和乱序等,用于在性能良好的局域网中,模拟出广域网中复杂的网络问题。 值得注意的是NetEm的规则是在指定网卡上生效的,所以所有从指定网卡发出的报文都会受到NetEm指定规则的影响。
NetEm借助于tc的qdisc框架,配置到网卡上,支持的命令格式如下(注意:一般来说netem要在root权限下配置)
tc qdisc ... dev DEVICE ] add netem OPTIONS OPTIONS := [ LIMIT ] [ DELAY ] [ LOSS ] [ CORRUPT ] [ DUPLICATION ] [ REORDERING ] [ RATE ] [ SLOT ] NetEm支持LIMIT, DELAY, LOSS, CORRUPT, DUPLICATION, REORDERING, RATE, SLOT这几种选项,下面会挨个详细介绍。
使用kubesphere搭建k8s集群 问题背景kubesphere搭建k8s集群Lyric: 脑海里 你的笑容太彻底 问题背景 在搭建k8s集群的时候踩了好多坑,真的蓝瘦,大多原因都是各种不兼容导致的,比如
Please wait for the installation to complete: >>—> 03:26:40 UTC failed: [master] error: Pipeline[CreateClusterPipeline] execute failed: Module[CheckResultModule] exec failed: failed: [master] execute task timeout, Timeout=7200000000000 connect is refused 最后发现不兼容主要是centos安装的版本所包含的依赖和kubesphere不兼容,因此想要安装成功,虚拟机也需要重新选择合适的版本,可以根据的我的版本进行安装,已经通过三次了
kubesphere搭建k8s集群 1 下载centos7.9的镜像:阿里镜像库
2 在VMware虚拟机上安装三台这个下载的centos镜像,更改静态IP
cd /etc/sysconfig/network-scripts su root vim ifcfg-ens33 BOOTPROTO=static ONBOOT=yes IPADDR=192.168.207.138 GATEWAY=192.168.207.2 NETMASK=255.255.255.0 DNS1=114.114.114.114 重启网络设置
systemctl restart network 3 每台虚拟机更新yum的软件包,时间设置等
yum -y update yum install -y conntrack yum makecache fast yum install -y ntpdate ntpdate time.
首先有一个规定:用printf输出char类型的数据时,输出的结果取决于控制符是%d或%u,
对了,char不仅是字符型变量,还是整型变量。
%d是有符号的整形数据,%u是无符号的整形数据(就是纯二进制数)。
如下图:
这是用%d输出的时候,那么之前提到过unsigned表示纯二进制,-1的计算机数【二进制】为全一,所以数值上为255.而signed就是有补码的那套规则,所以输出了-1.
这是用%u输出时,可以看到含有补码规则的signed变成了2^32,即int的最大二进制值。现在再解释为什们两种数据为什们不一样。
我们知道,int有32为的二进制数【4个8】,char只有8位二进制数,差了24位,从char提升到int时,前面是要增加数字的,那么对signed来说,它【-1是11111111】补上符号位,即最高位的数字,补了24个1,对unsigned来说它就全补0,运算得到255.
目录
数据库备份,数据库为school,素材如下
1.创建student和score表
2.为student表和score表增加记录
3.备份数据库school到/backup目录
4.备份MySQL数据库为带删除表的格式,能够让该备份覆盖已有数据库而不需要手动删除原有数据库
5.直接将MySQL数据库压缩备份
6.备份MySQL数据库某个(些)表。此例备份student表
7.同时备份多个MySQL数据库(其他数据库素材自行准备)
8.仅仅备份数据库结构
9.备份服务器上所有数据库
10.还原MySQL数据库
11.还原压缩的MySQL数据库
12.使用mydumper备份数据库
13.使用mydumper恢复数据库
数据库备份,数据库为school,素材如下 1.创建student和score表 CREATE TABLE student ( id INT(10) NOT NULL UNIQUE PRIMARY KEY , name VARCHAR(20) NOT NULL , sex VARCHAR(4) , birth YEAR, department VARCHAR(20) , address VARCHAR(50) ); 创建score表,SQL代码如下: CREATE TABLE score ( id INT(10) NOT NULL UNIQUE PRIMARY KEY AUTO_INCREMENT , stu_id INT(10) NOT NULL , c_name VARCHAR(20) , grade INT(10) ); 2.
关于腾讯云轻量应用服务器和云服务器CVM的区别,之前腾讯云百科写过一篇文章来对比,阿腾云又更新了一篇新的区别对比文章,比之前的要更加详细,包括轻量服务器的使用限制、CPU型号、公网限制月流量、内网连通性、硬盘存储等多方面对比:
目录
腾讯云轻量应用服务器和CVM云服务器的区别
1、CPU内存性能差异
2、费用成本差异
3、轻量服务器限制月流量
4、计费模式差异
5、CPU型号及主频说明
6、系统盘区别
7、内网连通性及集群应用区别
8、升级或降低配置
9、操作系统镜像区别
10、更换IP地址说明
11、是否支持IPv6
12、防火墙和安全组区别
轻量和CVM云服务器功能对比表
网站搬家备案在腾讯云,依旧选择腾讯云服务器,腾讯云轻量应用服务器成本低,轻量应用服务器和云服务器有什么区别?为什么轻量应用服务器要比云服务器划算呢?本着一分钱一分货的原则,阿腾云小编原本打算继续购买云服务器CVM,无奈,轻量应用服务器的确实很诱人,阿腾云小编马上去查了一下同CPU内存配置下的轻量应用服务器和云服务器性能区别,于是有了这篇文章:
腾讯云轻量应用服务器和CVM云服务器的区别 腾讯云轻量应用服务器Lighthouse是一种开箱即用,轻量不同于云服务器CVM,轻量服务器是面向轻量级应用的云服务器,适合中小企业或个人开发者使用。轻量应用服务器主要用于在云端构建网站、小程序/小游戏、电商、云盘/图床以及各类开发测试和学习环境。可领券:https://curl.qcloud.com/HmjGZiLu 满减优惠券。
轻量应用服务器具有简单、应用、开箱即用、套餐售卖、高带宽、限制月流量等特性,腾讯云百科来详细说下轻量服务器和CVM云服务器区别对比:
1、CPU内存性能差异 轻量应用服务器为什么便宜?是不是轻量主机的CPU、内存的计算性能不如云服务器CVM呢?同CPU内存配置下的轻量服务器和标准型CVM云服务器性能处于同一水准,如下图:
标准型云服务器CVM和轻量服务器CPU、内存性能水准相同
为了证明轻量应用服务器的性能问题,阿腾云去查了下官方文档,有明确说明,同CPU内存配置下的轻量应用服务器和标准型云服务器CVM在性能上是无差别的,轻量与同规格的标准型云服务器 CVM相比,轻量应用服务器的CPU、内存性能与其处于同一水准。
2、费用成本差异 轻量应用服务器CPU内存公网带宽配置要高一些,性价比高。官方文档说同规格的轻量应用服务器和标准型云服务器性能处于同一水准,成本差这么多,到底差在哪里?因为轻量应用服务器是限制月流量的。每台轻量应用服务器都是按套餐售卖的,每个套餐都有月流量限制。
阿腾云以2核4G5M带宽轻量服务器为例,虽然是5M公网带宽,但是每月限制500GB月流量,如果流量超额了,需要额外支付流量费用,费用为0.8元每GB。既然说到这了,就来说下腾讯云轻量应用服务器的月流量包问题:
3、轻量服务器限制月流量 轻量应用服务器是按套餐售卖的,每个套餐都有月流量限制,在套餐内的流量是免费的,当每月的流量超额后,需要另外支付流量费,轻量服务器不支持单独购买流量包。如下图:
腾讯云轻量服务器限制月流量
轻量服务器地域不同,如下表:
地域费用(元/GB)中国内地、新加坡、东京、法兰克福、首尔0.8中国香港1.0孟买0.58硅谷0.5 值得注意的是,轻量服务器的计费流量指的是公网出方向流量,内网流量和公网入方向流量都是免费的,如下图:
腾讯云轻量服务器流量收费和免费
关于轻量应用服务器,大家不要有流量恐慌,对于一般的应用而言都是够用的。腾讯云百科以网站为例,对于一般的网站,这个流量是够用的,像腾讯云百科账号下的轻量实例,每个月流量都是有剩余的,而且如果网站接入CDN和对象存储COS的话,更省流量。当然对于视频类的应用,流量肯定是不够用的。
云服务器CVM没有流量限制,买多少带宽,就会分配多少固定的独享公网带宽,不限制月流量。
4、计费模式差异 前面阿腾云已经说了,轻量应用服务器是按套餐售卖的,CPU、内存、带宽和系统盘配置是固定的,并且仅支持包年包月计费模式,用户根据实际需要选择对应的套餐。而云服务器CVM支持多种计费模式,如按量计费、包年包月和竞价实例,如下图:
腾讯云服务器CVM计费模式
并且云服务器CVM实例规格、CPU内存、带宽和系统盘等配置用户可以自由选择的。参考:https://cloud.tencent.com/document/product/213/2180
5、CPU型号及主频说明 创建轻量应用服务器时不支持指定底层物理服务器的 CPU 型号,腾讯云将随机分配满足套餐规格的物理CPU型号,通常优先选择较新代次的CPU型号。如下图:
轻量应用服务器时不支持指定CPU型号随机分配处理器
而云服务器CVM每款实例都有CPU型号与之对应,阿腾云以CVM标准型S5实例为例,S5云服务器CPU采用Intel® Xeon® Cascade Lake或者Intel® Xeon® Cooper Lake 处理器,主频2.5GHz,睿频3.1GHz,更多不同实例规格CPU处理器型号对照请参考:https://cloud.tencent.com/document/product/213/11518
6、系统盘区别 轻量应用服务器全系标配SSD云硬盘,而云服务器CVM系统盘或数据盘可选高性能云硬盘、通用型SSD云硬盘或SSD云硬盘,可以参考:腾讯云CBS云硬盘官方详解
在硬盘存储方面,轻量应用服务器更具优势。另外需要注意的是,轻量应用服务器的云硬盘和云服务器的云硬盘是相互独立,不支持相互挂载。
7、内网连通性及集群应用区别 云服务器CVM为专业级云服务器,CVM实例可以和负载均衡、云数据库内网连接搭建高可用高容灾集群应用。而轻量应用服务器一般用于只需要一台云服务器的单机应用。云服务器CVM可以创建专有网络VPC,并在专有网络上自行规划和维护网络,例如:指定私网IP地址、规划内网、创建交换机等功能。
可以使用阿里云测速工具 aliyunping.com 测试一下本地到阿里云服务器各个地域节点的Ping值网络延迟。
在内网连通性方面,轻量应用服务器相对于云服务器CVM要差一些。云服务器CVM有可用区概念,而轻量应用服务器不可自由选择可用区。并且轻量应用服务器实例创建完成后,不支持更换内网IP地址。以前轻量服务器不支持更换公网IP地址,现在已经支持更换公网IP了。轻量不支持用户自定义配置私有网络 VPC,网络由系统自动创建并分配。详细参考:https://curl.qcloud.com/8Eps6xac
8、升级或降低配置 轻量应用服务器只支持升级套餐,不只是降级,并且必须是从当前套餐整体升级套餐,不可以单独升级CPU、内存,或者单独升级公网带宽,单独升级某些配置是不可以的。但是云服务器CVM更加自由,可以自定义调整CVM实例配置,CPU、内存、公网带宽都可以随便升级或降配。参考:CVM调整实例配置
9、操作系统镜像区别 轻量应用服务器提供应用镜像模板,用户可以通过应用镜像一键搭建所需程序及程序依赖的配置环境,如下图:
参考内容:http://docs.ros.org/en/humble/Tutorials/Beginner-CLI-Tools/Introducing-Turtlesim/Introducing-Turtlesim.html
1.简介 Turtlesim是一个用于学习ROS 2的轻量级模拟器。它说明了ROS 2在最基本的层面上所做的事情,便于了解以后如何处理真实的机器人或机器人模拟。
ros2工具方便用户管理ROS系统、与ROS系统交互使用的。可以使用它来启动节点、设置参数、收听主题等。
rqt 是 ROS 2 的图形用户界面(GUI)工具。rqt中所做的一切都可以在命令行上完成,但rqt提供了一种更用户友好的方式来操作ROS2元素。
2.Turtlesim 2.1.安装Turtlesim 首先是安装Turtlesim(按照官方流程安装ROS 2的话,实际已经安装好了Turtlesim,只需检查即可)。
安装Turtlesim的命令如下:
sudo apt update sudo apt install ros-humble-turtlesim 检查Turtlesim的安装情况命令如下:
ros2 pkg executables turtlesim 运行结果为:
turtlesim draw_square
turtlesim mimic
turtlesim turtle_teleop_key
turtlesim turtlesim_node
2.2.简单使用turtlesim 打开一个终端,输入如下命令:
ros2 run turtlesim turtlesim_node 则会启动turtlesim(这个软件是模拟一个受控的机器人),如下图:
再打开另一个终端,输入如下命令:
ros2 run turtlesim turtle_teleop_key 此时可以使用方向键控制小乌龟行进,用来模拟控制机器人。
3.rqt 3.1.安装rqt 正常流程安装ROS 2时,是自动安装好rqt工具的,如果没有安装,则运行如下命令(Ubuntu20.04或更新):
sudo apt update sudo apt install ~nros-humble-rqt* 打开一个终端输入:rqt,则可以启动rqt工具,如下图:
3.2.使用rqt 在rqt工具中选择Plugins > Services > Service Caller,就可以列举出所有的服务。
什么是蚁群算法 蚁群算法(Ant Colony Optimization,ACO)是一种基于蚂蚁在寻找食物时的行为而发展起来的启发式算法。蚁群算法是一种群体智能算法,它模拟了蚂蚁在寻找食物时的行为,通过多个个体之间相互合作、信息交流来寻找最优解。它的主要思想是通过模拟蚂蚁在寻找食物时释放信息素的过程,让蚂蚁们在搜索空间中寻找最优解。
在蚁群算法中,每只蚂蚁表示一个搜索的个体,它们根据信息素和启发式信息(例如距离、费用等)来选择下一步移动的位置,并在移动的过程中更新信息素。信息素是一种用于指导蚂蚁移动的化学物质,它在蚂蚁走过的路径上留下痕迹,其他蚂蚁可以通过检测这些痕迹来选择路径。当蚂蚁在搜索过程中找到更优的解时,它会释放更多的信息素,以吸引其他蚂蚁前来搜索。
蚁群算法可以用于求解各种优化问题,如旅行商问题、调度问题、图论问题等。它具有并行性强、适应性好、鲁棒性强、易于实现等优点,在实际应用中得到了广泛的应用。
蚁群算法的常用步骤 在Python中,可以通过以下步骤实现蚂蚁群算法:
定义问题和目标函数:首先需要明确要解决的问题和目标函数,例如旅行商问题的目标是找到一条最短的路径,使得旅行商可以经过所有城市且只经过一次,而调度问题的目标是最小化完成所有任务所需的时间。初始化蚂蚁群和信息素:创建一个蚂蚁群,并初始化每只蚂蚁的位置和信息素值。信息素是一种用于指导蚂蚁移动的化学物质,它在蚂蚁走过的路径上留下痕迹,其他蚂蚁可以通过检测这些痕迹来选择路径。计算蚂蚁的移动概率:根据信息素和启发式信息(例如距离、费用等),计算每只蚂蚁在当前位置下一步移动到每个可行位置的概率。这里可以使用一个蚁群算法的核心公式:
p ( i , j ) = ( t a u ( i , j ) a l p h a ∗ e t a ( i , j ) b e t a ) / Σ ( t a u ( i , k ) a l p h a ∗ e t a ( i , k ) b e t a ) p(i,j) = (tau(i,j)^alpha * eta(i,j)^beta) / Σ(tau(i,k)^alpha * eta(i,k)^beta) p(i,j)=(tau(i,j)alpha∗eta(i,j)beta)/Σ(tau(i,k)alpha∗eta(i,k)beta)
一、编译模块程序,不需要内核源码,只需要linux-header头文件。在/usr/src/目录下。前期淌坑。 $ uname -r 4.13.0-36-generic # 和下面的内核版本不一致,是由于在两个电脑上操作的 $ ls /usr/src/ linux-headers-4.13.0-36 linux-headers-4.13.0-36-generic 网上推荐的在ubuntu下载linux源码的指令是 sudo apt-get install linux-source。
但这个下载的默认是linux-source-5.4.0 - Linux kernel source for version 5.4.0 with Ubuntu patches. 放在了/usr/src/目录下。
查看ubuntu下,内核版本的指令是 uname -r。
uname -r 5.15.0-69-generic 查看 apt 下 linux-source的资源包, 发现还是有5.15.0的。可以现在对应版本的。
:~$ apt-cache search linux-source linux-source - Linux kernel source with Ubuntu patches linux-source-5.4.0 - Linux kernel source for version 5.4.0 with Ubuntu patches linux-gkeop-source-5.4.0 - Linux kernel source for version 5.
目录
数据库环境准备(所有机器,以node1为例)
一,下载glibc版本的Mysql 二,新建用户以安全方式运行进程 三,安装并初始化mysql 四,修改mysql提供主配置文件
五,为mysql提供sysv服务脚本
六、启动mysql
七、修改mysql的root密码
九,登录mysql数据库
MYSQL日志管理
一,数据库中数据丢失或被破坏可能原因
二,MySQL日志
1,MySQL日志--错误日志
2,MySQL日志--通用查询日志
3,MySQL日志--慢查询日志
4,MySQL日志--二进制日志
数据库环境准备(所有机器,以node1为例) 一,下载glibc版本的Mysql mysql-5.7.36-linux-glibc2.12-x86_64.tar.gz
下载完成后查看
[root@node1 ~]# ll 二,新建用户以安全方式运行进程 (1)创建系统组mysql,指定组id为306,-r:系统组
[root@node1 ~]# groupadd -r -g 306 mysql (2)创建系统用户mysql,指定组id为306,组id为306
[root@node1 ~]# useradd -g 306 -r -u 306 mysql (3)查看结果
[root@node1 ~]# id mysql 三,安装并初始化mysql (1)把mysql包解压到/usr/lcoal/下面
[root@node1 ~]# tar xf mysql-5.7.36-linux-glibc2.12-x86_64.tar.gz -C /usr/local/ (2)切换到/usr/local目录下面为mysql包做个软链接名为mysql
[root@node1 ~]# cd /usr/local/ [root@node1 local]# ln -sv mysql-5.7.36-linux-glibc2.12-x86_64/ mysql (3)修改所有有关mysql的权限
最近在做题的时候常常遇到题目对于时间复杂度的控制,虽然暴力的方法可以通过OJ,但是这样做并没有达到题目本身的目的。虽然自己代码中循环结构的时间复杂度可以控制,但是却不是很清楚python各种内置函数和各种数据结构的可用方法的时间复杂度,所以查阅相关资料做个总结。
List
list.copy():copy操作需要将数组中的元素全部赋值给一个新的list,因此平均和最坏时间复杂度都是O ( n ) O(n)O(n)
list.append(obj):append操作只需要在list尾部添加元素,不需要遍历整个list,因此平均和最坏时间复杂度都是O ( 1 ) O(1)O(1)
list.pop(index):
当index = -1时,pop操作类似append,它只需要考虑list尾部的元素,因此平均和最坏时间复杂度都是o ( 1 ) o(1)o(1)
当index位于[ 0 , l e n ( l ) ] [0, len(l)][0,len(l)]之内时,pop操作需要找到弹出元素的索引,因此平均和最坏时间复杂度都是o ( k ) o(k)o(k)
list.insert(index, obj):插入元素需要遍历list先找到需要插入的位置,因此平均和最坏时间复杂度都是o ( n ) o(n)o(n)
Get Item 、Set Item:获取或更新指定索引位置的元素只需要直接到该位置操作即可,因此平均和最坏时间复杂度都是O ( 1 ) O(1)O(1)
list.remove(obj):移除指定的元素需要遍历整个list,因此平均和最坏时间复杂度都是O ( n ) O(n)O(n)
list.extend(seq):extend操作在尾部扩展list,平均和最坏时间复杂度都是O ( k ) O(k)O(k)
list.sort():sort操作这里使用的是归并排序(merge sort),因此平均和最坏时间复杂度都是O ( n log n ) O(n \log n)O(nlogn)
方法 通过CMD命令行进入tar.gz.part文件的目录下通过如下命令将各个分卷压缩包XXXX.tar.gz.part合并为一个完整的压缩包XXX.tar.gz: copy /b XXXX.tar.gz.part* XXX.tar.gz 然后再用解压软件解压就好(如:WinRAR) 举例 进入DeepScene_FreiburgForest\freiburg_forest_raw文件夹
输入如下命令 copy /b freiburg_forest_raw.tar.gz.part* freiburg_forest_raw.tar.gz 在同一个文件夹下会生合并后的压缩包freiburg_forest_raw.tar.gz
然后再用WinRAR解压
Tensor张量 什么是TensorTensor的创建1. 直接创建2. 通过numpy创建3. 依据数值创建4. 依据概率分布创建 Tensor的属性Tensor的操作1. 张量拼接与切分2. 张量索引3. 张量变换4. 将张量移动到GPU Tensor的数学运算1. 加减乘除2. 对、指、幂函数3. 三角函数 什么是Tensor 张量是一种特殊的数据结构,与数组和矩阵非常相似。在 PyTorch 中,我们使用张量对模型的输入和输出以及模型的参数进行编码。
张量相当于一个多维数组。
torch.Tensor(dtype, shape, device, data, requires_grad, grad, grad_fn, is_leaf) requires_grad:指示是否需要梯度
grad:data的梯度
grad_fn:创建Tensor的function
is_leaf:是否是叶子节点(张量)
Tensor的创建 1. 直接创建 张量可以直接从数据中创建。数据类型是自动推断的。
从data创建,可以是list,numpy。
torch.tensor(data, dtype=None, # 默认与data一致 device=None, # cuda/cpu requires_grad=False, # 是否需要梯度 pin_memory=False) # 是否存于锁页内存,通常为False 例如:
data = [[1, 2],[3, 4]] x_data = torch.tensor(data) 2. 通过numpy创建 从numpy创建的tensor源于ndarray共享内存,当修改其中一个的数据,另一个也会被改动。
np_array = np.array(data) x_np = torch.from_numpy(np_array) 让tensor和numpy共享底层内存 t = torch.
目录 一、常用快捷键1、Notepad++常用快捷键:2、centos7快捷键3、idea快捷键4、excel 一、常用快捷键 1、Notepad++常用快捷键: 1)Ctrl-D:复制当前行; 2)Ctrl-L:删除当前行; 3)Ctrl-T:上下行交换; 4)F3:找下一个; 5)Shift-F3:找上一个; 6)Ctrl-Shift-F:在文件中找; 7)Ctrl-U:变为小写; 8)Ctrl-Shift-U:变为大写; 9)Ctrl-Q:块注释/消除注释。 常用替代操作:
1) \t 去换行符 2) \r\n 多行合并 3) \s+$ 替换为空。\s的意思是匹配任何空白字符 4) $表示行尾,^表示行首 5) 单行分解成多行查找目标, 替换\r 6) 匹配字符串去除所存在的行 `^.*H22G.*$` 7)去除空行^\s 8) 去除行尾空格) \s+$ 9) 删除字符串前面的 ^.*pm 10) 删除字符串后面的 pm.*$ 11) 字符串中的多个空格换成一个 [ ]+ 2、centos7快捷键 1、光标移动 ctrl + < 移动到前一个单词开头 ctrl + > 移动到后一个单词结尾 ctrl + A 移动到开头 ctrl + E 移动到结尾 alt + B 向左移动一个单词 alt + F 向右移动一个单词 ctrl + B 向左移动一个字符 ctrl + F 向右移动一个字符 esc + B 向左移动一个单词 esc + F 向右移动一个单词 ctrl + XX 在上次光和当前光标所在字符间跳转 esc + T 交换光标位置前的两个单词 2、删除 ctrl + K 删除光标后所有字符(剪切) ctrl + U 删除光标前所有字符(剪切) ctrl + W 删除光标前一个单词 ctrl + D 删除光标所在字符(光标右侧) ctrl + H 删除光标前字符(光标左侧) 3、撤销 ctrl + _ 撤销操作 ctrl + Y 粘贴ctrl+U/K剪切的内容 ctrl + ?
1、$forceUpdate() ,全局强制刷新
用法:在改变数据但是未更新后面直接加
this.$forceUpdate()
2、this.$set()
对局部强制刷新 ,性能消耗较低 ,是将set函数绑定在vue原型上(修改属性)
第一个参数代表要更新的那个 数组/对象
第二个参数表示 数组下标/对象属性名称
第三个参数表示 改变的新值
this.$set(this.dictOptions, 'isPublic', 1) //更新对象 this.$set(this.model.roleList,this.selectKey,this.model.roleList[this.selectKey]) //刷新数组 3、Vue.set()
全局强制刷新 性能消耗比this.$set高 ,是将set函数绑定在构造函数上(可以添加属性)
用法与this.$set()一致
问题:
一对多关系表使用MybatisPlus的Ipage进行分页查询,会先执行联表查询sql语句,然后进行分页。
像图中联表查询一对多关系,会有多条重复数据,使用Ipage分页会将这10条数据返回到xml中resultMap绑定的type。造成一页展示的数据少于10条。
针对这种我们采用子查询的方式解决:
一对多关系,
property:主表中关联表的属性名,
column: 主表传递给子查询的字段
select:子查询的方法
javaType:返回的类型
mapper接口
// 分页主表查询 IPage<List<UsedCar>> queryUsedCarSearchListCopy(@Param("page") IPage<UsedCar> pageUtil,@Param("params") Map<String, Object> params); // 子查询方法名 List<UsedCarImage> queryImageList(@Param("carId") Long carId); // service层 @Override public PageUtils queryPage(Map<String, Object> params) { QueryWrapper<UsedCar> queryWrapper = new QueryWrapper<>(); // Ipage分页, IPage<UsedCar> pageUtil = new Page<UsedCar>(Long.parseLong((String) params.get("page")),Long.parseLong((String) params.get("limit"))); // Ipage作为参数传递 IPage<List<UsedCar>> page =usedCarMapper.queryUsedCarSearchListCopy(pageUtil,params); PageUtils pageUtils = new PageUtils(page); return pageUtils; } 主表查询:
子查询sql,通过select进行了绑定
#{carId}是主查询传递过来的字段
,mybatisPlus分页一对多关联表查询,可以正常显示了
1、背景 因为在2021年给自己定了目标和计划,学习ffmpeg,所以这篇文章是实现计划的第一步。
ffmpeg 众所周知,就不展开介绍了,下面给出 FFmpeg 4.2 windows x64 lib库和头文件的下载地址(粉丝免积分下载):
download.csdn.net/download/u0…
本文也是属于博主的入门学习总结与分享,因此我们先从ffmpeg的软解码开始,从解码到绘制,一起体验下亲自动手的快乐。本文的语言环境基于C++,界面部分是 QT。
2、流程分析 在开始看代码之前,我们必须先了解下ffmpeg软解的常规流程:
在以前的教程中我们经常见到av_regeister_all,这是旧版ffmpeg的用法,必须在开始进行初始化,新版的ffmpeg4.0之后已经不需要了,详见github: av_register_all() has been deprecated in ffmpeg 4.0。
1.1 avformat_open_input 为 AVFormatContext 分配空间,打开输入的视频数据并且探测视频的格式,这个函数里面包含了复杂的格式解析与探测算法,可解析的内容包括:视频流、音频流、视频流参数、音频流参数、视频帧索引等。用雷神的话说就是 可以算作FFmpeg的“灵魂”。
1.2 avformat_find_stream_info 获取多媒体流的信息,包括码流、帧率、时长等信息。但是有些早期格式或者裸流数据它的索引并没有放到头当中,因此需要在后面进行探测。注意一个视频文件中可能会同时包括视频文件、音频文件、字幕文件等多个媒体流。
1.3 av_find_best_stream 当视频被解封装出来后,需要分开处理音频和视频,需要找到对应的音频流和视频流,获取音视频对应的stream_index。
1.4 avcodec_find_decoder(enum AVCodecID id) "Find a registered decoder with a matching codec ID." 上一步找到的AVStream中的成员变量 codecpar->codec_id 就是这儿的参数 ID,codecpar类型为AVCodecParameters。网上的很多资料为 AVCodecContext->codec_id,这个用法在FFMPEG3.4及以上版本已经被弃用了,官方推荐使用codecpar。
1.5 avcodec_alloc_context3 创建AVCodecContext并分配空间。
1.6 avcodec_parameters_to_context 该函数用于将流里面的参数,也就是AVStream里面的参数直接复制到AVCodecContext的上下文当中,执行真正的内容拷贝。avcodec_parameters_to_context()是新的API,替换了旧版本的avcodec_copy_context()。
1.7 avcodec_open2 用给定的 AVCodec 去初始化 AVCodecContext。
到这儿,解码器的初始化工作已经完成。下面就可以开始真正的解码操作了。
1.8 av_read_frame 读取码流中的音频若干帧或者视频一帧,av_read_frame()函数是新型ffmpeg的用法,对 av_read_packet 进行了封装,旧用法之所以被抛弃,就是因为以前获取的数据可能不是完整的,而av_read_frame()保证了视频数据一帧的完整性,使读出的数据总是完整的一帧。
const { defineConfig } = require('@vue/cli-service') module.exports = defineConfig({ lintOnSave: false, transpileDependencies: true, devServer: { port: 8081, proxy: 'https://daidai.qhwoyoung.com/' // proxy: 'http://www.daidai.fun/' }, publicPath: './', assetsDir: 'static', productionSourceMap: false, configureWebpack: config => { // 为生产环境修改配置... if (process.env.NODE_ENV === 'production') { config.mode = 'production' // 打包文件大小配置 config.performance = { maxEntrypointSize: 10000000, maxAssetSize: 30000000 } } } })
文章来源:https://www.bilibili.com/video/BV153411n7B5/?p=5&spm_id_from=333.880.my_history.page.click
1.为什么要用hooks ,单纯的使用class组件不行吗? react是用于构建用户界面的JavaScript库,使用class组件有点大材小用,组件中很少用到class的继承,组件之间很少进行访问,但是使用函数式组件,他能更好的胜任根据状态来渲染UI的工作,hooks内部拥有了维护状态的能力,且hooks带来了逻辑复用的能力.
2.react模型的本质 react模型本质就是model->views的一个过程,给他数据,他将为你展示ui,即state+props=组件
3.hooks是什么 hooks是函数,是一个提供了状态和生命周期等特性的函数
4.在什么时候使用setState使用回调函数作为参数 1.初始状态需要经过一些计算,localStorage中拿值
2.状态需要迭代累加,setXxx((上一次的值)=>{return 新的值}),即多次调用setXxxx,页面显示的是多次调用setXxxx后的新值,而不是最后一个setXxx覆盖得到的新值.
function addClick(){ setCount(count + 1) setCount(count + 1) setCount(count + 1) //最后一次的值覆盖上面的值 } function addClick(){ setCount((num)=>{ return num + 1 }) setCount((num)=>{ return num + 1 }) setCount((num)=>{ //最后一次的调用,是基于上次是调用结束后的值 return num + 1 }) } //这两种调用方式在页面展示的内容是不一样的 5.useState更新视图的过程 1.setState的每次调用,都会使函数式组件里面的代码重新走一遍
2.useState只会在组件初次渲染的时候使用初始值,之后都会使用更新后的值
3.一个函数式组件中的state是共享的,多次渲染会相互影响
6.副作用,useEffect 函数式组件除了渲染UI之外的操作都算是副作用操作
1.主要作用:函数式组件里面的return 的jsx ; 定义的state等
2.副作用:请求,修改dom,定时器的定义和清除,localStarage等
推荐将副作用的代码写在useEffect里面
7.useEffect的执行时机 1.页面挂载的时候执行一次(componentDidMount)
2.页面更新的时候触发,可能触发多次(componentDidUpdate)
3.在useEffect中发送ajax请求的小细节
//1.错误写法 useEffect(async ()=>{ const res = await fetchGetApi(data) console.
1. 什么是端到端测试 端到端测试(End-To-End Testing, 简称E2E测试)是一种从头到尾测试整个软件产品以确保应用程序流程按预期运行的技术。它定义了产品的系统依赖性,并确保所有集成部分按预期协同工作。
端到端测试的主要目的是通过模拟真实用户场景并验证被测系统及其组件的集成和数据完整性,主要从最终用户的体验进行测试。
2. 端到端测试的模型 在我们当前的业务实践中,端到端测试由测试同学主导编写,用例代码和业务模块独立仓库管理。
下面按照用户使用银行卡申购指数基金为例,说明端到端测试的依赖关系:
可以看到,端到端测试的用例模块是跟业务模块独立存在的,并且逻辑也比集成测试用例和接口测试都要复杂,通过模拟真实用户行为、打通系统全周期的测试方式,来验证系统的全链路流程。
3. 端到端测试的优点 扩大测试覆盖范围确保应用程序的正确性缩短发布时间降低成本检测Bug通过添加比其他测试方法(如单元和功能测试)更详细的测试案例,帮助团队扩大他们的测试范围。通过运行基于终端用户行为的测试用例,确保应用程序的正确执行。帮助发布团队缩短上市时间,允许他们自动化关键用户路径。通过减少测试软件的时间,降低构建和维护软件的总体成本。 4. 端到端测试的挑战 端到端测试也不是万能的,任何收益必然伴随着成本。端到端测试的挑战如下:
4.1 编写耗时长 端到端测试需要对产品服务流程有完整的了解才能编写测试用例,因此编写的耗时很长。如果你的产品属于大型产品,那用户在产品中就有很多的浏览途径。我们不能针对每个路径进行测试。
所以,通常做法是更频繁地使用单元测试、接口测试,只对最高优先级的用户工作流使用端到端测试。
4.2 测试用例设计难度大 因为端到端测试是模拟用户的真实行为,因为在设计这些测试用例时就需要考虑多许多因素。
比如,一个在多浏览器运行的web程序,每个浏览器都有不同的规范。这意味着我们需要针对不同浏览器编写测试。时间成本很高。
在开发过程中,不能依赖端到端测试来快速寻找代码反馈,而是应该使用单元测试和接口测试。
4.3 容易终端且难以维护 端到端测试因为要走完完整流程,流程长,涉及系统多,非常容易中断,用例的前置依赖也非常多,这些都强依赖一个稳定的服务测试环境。整体维护成本非常高。
4.4 站在用户角度 用户不是在体验功能,而是通过产品解决他们的某些问题。所以端到端测试应该侧重于如果有效有效地解决用户问题。
并不是所有的开发团队都详细了解用户意图的。所以在开发期间就必须尽快部署,快速收集用户反馈。
5. 端到端测试的最佳实践 要进行端到端测试,遵循以下概述的做法至关重要,以确保测试顺利进行和成本可控。
5.1 优先考虑最终用途 模拟用户:创建测试用例时,像用户一样进行测试。了解第一次使用该应用程序的人的心态。易用性:是否容易找到所有选项?特征有标注吗?用户能否通过两步或三步得到他们想要的东西?文档先行:使用有助于阐明用户观点的验收测试文档和用户故事,相应地设计测试用例。考虑投入产出:将 E2E 测试重点放在失败会导致最大问题的应用程序功能上。从这些特性开始,设计更精细的测试用例来验证它们。 5.2 避免异常测试 E2E 测试最适合用于测试常见的用户场景。对于特殊的用户场景,使用单元测试或接口测试。
5.3 维护整体用例的代码结构 由于 E2E 测试涵盖整个应用程序,因此测试用例必然很复杂。每个系统组件都必须进行测试,这增加了故障点以及调试每个异常的难度。结构和组织在 E2E 测试中至关重要。通过单元测试和接口测试等底层测试消除简单的错误。 5.4 优化环境和清理机制 确保测试环境随时可以开始测试。测试完成后,务必清理测试数据,以便环境恢复到原始状态,从而准备好再次进行测试。 鉴于端到端测试的重要性,需要从项目一开始就对其进行规划。端到端测试最好手动进行,因为它允许测试人员设身处地为用户着想。如果需要自动化测试,最好将其限制在只需要重复操作的低风险功能上。