图表示学习和异质信息网络 图表示学习基本概念相关技术基于降维解析的方法基于矩阵分解的方法基于随机游走的方法基于深度学习的方法 异质信息网络基本概念语义探索方法元路径受限元路径加权元路径元结构/元图 异质网络表示学习 选自 [1]李青,王一晨,杜承烈.图表示学习方法研究综述[J/OL].计算机应用研究:1-16[2023-05-11].DOI:10.19734/j.issn.1001-3695.2022.09.0504. [2]石川,王睿嘉,王啸.异质信息网络分析与应用综述[J].软件学报,2022,33(02):598-621.DOI:10.13328/j.cnki.jos.006357. 图表示学习 图表示学习是指将一个图中的节点或者整(子)图映射到低维向量空间的过程,其主要目是使低维向量空间中的几何关系能够反映原始图中的结构信. 优化后的低维向量空间所学习到的嵌入向量能够作为特征输入来处理下游任务.在解决特定任务时,使用图表示学习技术进行学习的对象也有所不同,可以将图表示学习分为以下 3 种:
节点嵌入:图数据中的节点往往表示了各类重要实体,这些节点本身具有大量的属性作为其特征,通过捕捉节点的属性,对其进行表示学习以获得更低维度的节点嵌入,能够对现实中的实体进行更有效的分析.边嵌入:实体间存在的或紧密或疏远的关系,可借助于图的边来表示.边所表示的不同依赖关系存在着重要性大小的差异,使得部分边自带有权重属性.因此,在对边进行表学习时,可获得边本身的属性特征及所关联节点的特征来进行补充表示.子图嵌入:子图嵌入即将子图作为一个整体进行表示学习,获得低维嵌入向量.该方法首先需要根据一定的规则构造适当的子图,接着在子图中捕捉图中节点的属性和结构特征.在处理的数据量较大时,子图有时用于代替整图,能够大大减少计算成本. 基本概念 图: G = < V , E , T , X > G=<V,E,T,X> G=<V,E,T,X>, V V V是节点集合, E E E是边集, X X X表示属性矩阵。函数 φ : V → T v \varphi:V\rightarrow T_v φ:V→Tv 和 ϕ : E → T E \phi:E\rightarrow T_E ϕ:E→TE分别对节点和边进行映射,其中 T V T_V TV表示节点类型的集合, T E T_E TE表示边类型的集合。若 T V = T E = 1 T_V=T_E=1 TV=TE=1,则G是一个同构图,若 ∣ T V ∣ + ∣ T E ∣ > 2 |T_V|+|T_E|>2 ∣TV∣+∣TE∣>2,则G是一个异构图。
文章目录 1、为什么要使用ini或者其它(例如xml,json)配置文件?2、ini文件基本介绍3、ini配置文件的格式4、C++读写ini配置文件5、 代码示例6、 配置文件的解析库 文章转载于:https://blog.csdn.net/weixin_44517656/article/details/109014236
1、为什么要使用ini或者其它(例如xml,json)配置文件? 如果我们程序没有任何配置文件时,这样的程序对外是全封闭的,一旦程序需要修改一些参数必须要修改程序代码本身并重新编译,这样很不好,所以要用配置文件,让程序发布后还能根据需要进行必要的配置;配置文件有很多如INI配置文件,XML配置文件,还有就是可以使用系统注册表等。注意:ini的后缀名也不一定是".ini"也可以是".cfg",“.conf ”或者是”.txt"。因为ini文件实质就是txt文本文件。
配置文件除了读取外还可以写入:例如用户设置了习惯模式,这样下次启动读取文件的时候也是该模式
kv文件,是ini执行后出现的文件
2、ini文件基本介绍 .ini 文件是Initialization File的缩写,即初始化文件 [1] ,是windows的系统配置文件所采用的存储格式,统管windows的各项配置,一般用户就用windows提供的各项图形化管理界面就可实现相同的配置了。但在某些情况,还是要直接编辑.ini才方便,一般只有很熟悉windows才能去直接编辑。开始时用于WIN3X下面,WIN95用注册表代替,以及后面的内容表示一个节,相当于注册表中的键。除了windows2003很多其他操作系统下面的应用软件也有.ini文件,用来配置应用软件以实现不同用户的要求。一般不用直接编辑这些.ini文件,应用程序的图形界面即可操作以实现相同的功能。它可以用来存放软件信息,注册表信息等。 3、ini配置文件的格式 1、INI文件由节、键、值组成。
节: [section] 参数(键=值) name=value 注解 注解使用分号表示(;)在分号后面的文字,直到该行结尾都全部为注解。 1)对节进行说明:
所有的parameters都是以sections为单位结合在一起的。所有的section名称都是独占一行,并且sections名字都被方括号包围着([ and ])。在section声明后的所有parameters都是属于该section。对于一个section没有明显的结束标志符,一个section的开始就是上一个section的结束,或者是end of the file。Sections一般情况下不能被nested,当然特殊情况下也可以实现sections的嵌套。因为INI文件可能是项目中共用的,所以使用[Section Name]段名来区分不同用途的参数区。 2)对参数进行说明:
INI所包含的最基本的“元素”就是parameter;每一个parameter都有一个name和一个value,name和value是由等号“=”隔开。name在等号的左边。 3)对注释内容进行说明:
在INI文件中注释语句是以分号 “;” 开始的(有些人定义类是由#注释,例如下面的RrConfig)。所有的所有的注释语句不管多长都是独占一行直到结束的,在分号和行结束符之间的所有内容都是被忽略的。 4、C++读写ini配置文件 在VC中涉及的函数有如下四种。
1)读取字符串
//头文件:windows.h //返回字符串的实际大小,根据系统环境不同失败返回值不同(0或-1) DWORD GetPrivateProfileString( LPCTSTR lpAppName, // INI文件中的一个字段名[节名]可以有很多个节名(配置文件的section名),这个字串不区分大小写; LPCTSTR lpKeyName, // lpAppName 下的一个键名,也就是里面具体的变量名(配置文件的key名),这个字串不区分大小写; LPCTSTR lpDefault, // 如果lpReturnedString为空,则把这个变量赋给lpReturnedString,一般设为空(""); LPTSTR lpReturnedString, // 存放键值的指针变量,用于接收INI文件中键值(数据)的接收缓冲区 DWORD nSize, // 前一个参数对象lpReturnedString的缓冲区大小 LPCTSTR lpFileName // 完整的INI文件路径名 ); 2)读取整型值
文章目录 概要使用技巧1. 建表、插入数据2.以id分组,把age字段的值拼成一行,逗号分隔(默认)3.以id分组,把age字段的值拼成 一行,分号分隔4.以id分组,把去冗余的age字段的值打印在一行5.以id分组,把age字段的值打印在一行,逗号分隔,以age排倒序 发现问题解决问题 概要 ` group_concat函数是mysql中非常实用的函数,它可以将同一个分组下的行拼接在一起。其完整语法:
GROUP_CONCAT([DISTINCT] 要连接的字段 [Order BY ASC/DESC 排序字段] [Separator ‘分隔符’])
使用技巧 1. 建表、插入数据 #建表语句 CREATE TABLE `test_group_concat` ( `id` int(11) NOT NULL COMMENT 'id', `age` int(11) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; #插入测试数据 INSERT INTO `test`.`test_group_concat` (`id`, `age`) VALUES (1, 20); INSERT INTO `test`.`test_group_concat` (`id`, `age`) VALUES (1, 20); INSERT INTO `test`.`test_group_concat` (`id`, `age`) VALUES (1, 10); INSERT INTO `test`.`test_group_concat` (`id`, `age`) VALUES (3, 30); INSERT INTO `test`.
文章目录 项目背景项目功能测试计划与设计功能测试自动化测试 测试结果功能测试结果UI自动化测试结果 项目背景 在浏览网站时,发现好多网站开放出聊天的窗口,我们一发送消息就会收到一条消息,好奇这个功能是怎么实现的,最后查阅资料发现收发消息的操作是通过服务端先接收到消息,再主动向客户端推送消息,所以呢就想做一个聊天网站实现上述的功能,但是实现服务器推送的方法很多,此项目选择使用了WebSocket协议来实现上述功能
项目功能 注册:用户可以申请注册一个账号登录:用户使用注册的账号进行登录好友管理模块:在搜索框输入要添加好友的用户名,即可申请添加好友会话管理模块:用户可以点击好友来创建不存在的会话消息管理模块:用户可以和自己的好友实时聊天 测试计划与设计 本次测试的环境为:Windows操作系统Win11,Chrome浏览器
功能测试 测试步骤:
分析需求,提取测试点针对测试点设计测试用例根据测试用例手工执行测试针对测试结果输出报告 测试用例
这里针对项目的界面,功能,安全,性能,兼容性,易用性设计测试用例
此处只粘贴部分用例,完整的用例可访问Gitee链接查看
链接: 畅聊趣坊测试用例
测试步骤
这里记录两个核心功能的测试步骤:
添加好友发送消息 添加好友的测试步骤:
先正确登录来到主页面 再查找要添加的好友 查找到,点击添加 使用无痕模式登录被添加的账号 点击同意 查看添加好友结果 发送消息的测试步骤:
甲先给乙发送消息 乙查看是否收到消息,并向甲回应一条消息 查看甲是否收到消息 自动化测试 自动化测试的优点:
自动化测试可代替一部分手工测试,提高测试的执行效率,并且随着项目版本的迭代,回归测试的压力越来越大,借助自动化测试提高回归测试效率
注意:自动化测试只能代替一部分手工测试,不能完全替代手工测试
自动化测试的步骤:
分析项目的核心功能针对核心功能设计自动化测试用例针对测试用例编写自动化脚本执行脚本记录结果 设计自动化测试用例
此处针对三个主要的模块设计用例:
用户模块会话好友管理模块消息管理模块 编写自动化测试脚本
此处只粘贴部分脚本代码,完整脚本可访问Gitee链接
链接: 畅聊趣坊UI自动化测试脚本
import org.junit.jupiter.api.*; import org.openqa.selenium.Alert; import org.openqa.selenium.By; import org.openqa.selenium.WebElement; import java.time.Duration; @TestMethodOrder(MethodOrderer.OrderAnnotation.class) public class ClientTest extends InitAndEnd{ @BeforeEach void login() throws InterruptedException { driver.get("http://47.108.53.70:8080/login.html"); driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3)); driver.findElement(By.cssSelector("#username")).sendKeys("admin"); driver.
作者:Insist--
个人主页:insist--个人主页
作者会持续更新网络知识和python基础知识,期待你的关注
目录
一、什么是RIP协议?
二、为什么要使用RIP?
三、RIP用在哪里?
四、RIP协议的工作原理
五、总结
前言
本文将给大家讲解什么是RIP,为什么使用它,以及它的工作原理
一、什么是RIP协议? RIP协议(Routing Information Protocol,路由信息协议)是一种基于距离矢量的内部网关协议,即根据跳数来度量路由开销,进行路由选择。
相比于其它路由协议(如OSPF、ISIS等),RIP协议实现更简单,对带宽、配置和管理等要求也更低,但受到路由跳数和收敛速度的限制,跳数大于15就认为网络不可达,所以无法用在大型复杂网络中。
二、为什么要使用RIP? 在出现动态路由之前,静态路由有几个问题无法解决:
问题一:当网络拓扑结构和链路状态发生变化,需要对路由器的静态路由信息进行大范围修改,工作复杂度高。
问题二:网络发生故障时,不能重选路由,很可能使路由失败。
为了解决这些问题,动态路由协议就出现了,路由器自动学习,自适应网络的变化,无需人工更改配置。
三、RIP用在哪里? RIP适用于中小型网络,因为RIP是基于距离矢量的算法(D-V算法)。由于其只能支持0-15跳,第十六跳会被标记成无限大或不可达。所以在整个网络中,只能有16个路由器相互成为rip邻居路由器,由于以上原因,所以RIP只能应用于中小型网络。
四、RIP协议的工作原理 如下图,分别有RTA、RTB、RTC三个路由器,每个路由器首先学习到己的直连路由,形成路由表。
然后我们在路由器上配置RIP协议,配置完成后路由器每隔30s就会向他的直连路由通告自己的路由表。比如RTB会将自己的路由表发给RTC,RTC会将自己表中没有的20.0.0.0网段添加进去,记住下一跳,并标记跳数为1。
在经过第一个30s的更新之后,这3个路由器的路由表如下图:
路由器的第二个更新周期到来,路由器将会再次向邻居发送路由表。RTA发送路由表给RTB,但是RTB已经不需要学习了。
不用学习的原因:RTB的路由表中包含RTA的所有网段。
RTB将自己的路由表发送给RTA,RTA会将40.0.0.0这个网段加到自己的路由表中,添加下一跳地址标志为20.0.0.2(因为是通过这个端口收到的),并添加距离标记为2。RTC也会同样更新自己的路由表。最后的路由表如下图:
五、总结 RIP是一种出现较早的路由协议,通过简单的距离矢量算法来计算到达目的网络的最佳路径,实现和维护起来都比较容易,能够满足早期小型网络的需求,但RIP的扩展性受到转发跳数的限制,且RIP每次进行路由更新都会占用大量带宽,链路故障后需要花费较长时间才能实现收敛,所以相比于后面出现的OSPF等路由协议,在路由收敛速度上存在明显不足,无法用在一些现代的大型复杂网络中。
文章目录 1. 文件描述符1.1 前言1.2 理解文件1.3 文件描述附表1.4 打开文件时1.5 默认打开的三个文件 2. 重定向2.1 瞅瞅2.2 dup22.3 实现原理 3. 一切皆文件 1. 文件描述符 1.1 前言 环境:Linux 2.6
在 Linux 中,有句话叫做「一切皆文件」,指的是在 Linux 中的设备,资源等几乎一切资源都抽象成了文件,然后只需要提供对文件进行操作的接口,就可以让我们用统一的方式来读取,写入等各种操作,从而来管理 Linux 中的各种资源和数据。这种设计模式不仅简化了 Linux 架构,还简化了开发人员对资源的操作
1.2 理解文件 当进程打开一个文件的时候,操作系统会为其分配一个文件描述符(先了解,下文讲),当我们获取这个文件描述符之后,就可以对这个文件进行读写等各种操作了
并且这个文件被打开后,在操作系统内核中会为其创建一个结构体 struct file 来进行管理(这和 C 语言的 FILE 结构体不一样),它记录了文件的状态,读写位置等文件信息,它是在内核空间中的,而 C 语言的 struct FILE 是在用户空间中的
并且在 struct file 中存在一个指向缓冲区的指针,可以将数据暂存在缓冲区中,而文件通常会被划分成若干个页(4KB),在打开文件 / 读取文件的时候,操作系统会读取相应的块到该文件的缓冲区中
1.3 文件描述附表 在 Linux 中,进程被描述成 task_struct 进行管理(PCB),而task_struct 中有个指针 struct files_struct* files,该指针负责描述该进程的文件相关数据信息 struct task_struct { volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */ void *stack; .
环境:vue3+setup语法
首先放官方文档的链接:
中文版本: vue.draggable.next 中文文档 - itxst.com (民间翻译)
英文版本:GitHub - SortableJS/vue.draggable.next: Vue 3 compatible drag-and-drop component based on Sortable.js
因为自己写的过程中,官方文档和网上的资料都非常不明,使用版本各不相同,极易踩坑,自己写完后就总结一下,与诸位共勉。
(一)首先,明确需求: 做一个可重复拖拽生成的表格设计器,效果图如下:
(二)搭一个基本的可互相拖拽的框架 (1)在终端使用npm命令下载插件
npm i -S vuedraggable@next //导入 import draggable from 'vuedraggable' (2)拖拽插件大致可分为两种使用方式——分组拖拽与单组拖拽
单组拖拽为只有一组数据,而拖拽是交换此组数据内部的位置,如下图所示:
而互相拖拽是有两组数据,两组数据可以各自内部换顺序,可以相互拖拽到对方的数组中。
本文需求只用到了互相拖拽,互相拖拽的代码形式如下:
//需要克隆的数据,A组 <draggable :list="dragList" ghost-class="ghost" :force-fallback="true" :group="{ name: 'list', pull: 'clone' }" :sort="false" itemKey="id"> <template #item="{ element }"> <div class="item move"> <label class="move">{{ element.name }}</label> </div> </template> </draggable> //拖拽的结果,B组 <draggable :list="widgetList" ghost-class="ghost" itemKey="id" :force-fallback="
无意中发现了一个巨牛的人工智能教程,忍不住分享一下给大家。教程不仅是零基础,通俗易懂,而且非常风趣幽默,像看小说一样!觉得太牛了,所以分享给大家。点这里可以跳转到教程。人工智能教程
本篇文章将介绍基于Keras深度学习的多变量时间序列预测的LSTM模型。
项目名称:空气污染预测
一、主要内容:
如何将原始数据集转换为可用于时间序列预测的内容。 如何准备数据并使LSTM适合多变量时间序列预测问题。 如何进行预测并将结果重新缩放为原始单位。 二、数据下载
在本教程中,我们将使用空气质量数据集。该数据集报告了美国驻中国大使馆五年来每小时的天气和污染水平。数据包括日期时间,称为PM2.5浓度的污染以及包括露点,温度,压力,风向,风速和雪雨累计小时数的天气信息。原始数据中的完整功能列表如下:
否:行号 年:此行中的数据年份 month:此行中数据的月份 日期:此行中的数据日期 hour:该行中的数据小时 pm2.5:PM2.5浓度 露点:露点 TEMP:温度 PRES:压力 cbwd:组合风向 Iws:累计风速 是:累计下雪时间 Ir:累计下雨时间 我们可以使用这些数据来构建预测问题,在此情况下,鉴于前几个小时的天气条件和污染,我们可以预测下一个小时的污染。
数据下载地址
下载数据集并将其命名为 raw.csv
三、数据处理
第一步,将零散的日期时间信息整合为一个单一的日期时间,以便我们可以将其用作 Pandas 的索引。
快速检查第一天的 pm2.5 的 NA 值。因此,我们需要删除第一行数据。在数据集中还有几个零散的「NA」值,我们现在可以用 0 值标记它们。
以下脚本用于加载原始数据集,并将日期时间信息解析为 Pandas DataFrame 索引。「No」列被删除,每列被指定更加清晰的名称。最后,将 NA 值替换为「0」值,并删除前一天的数据。
# -*- coding: utf-8 -*- from pandas import * # 定义字符串转换为日期数据 def parse(x): return datetime.strptime(x, '%Y %m %d %H') # 数据存放路径设置 data_path=r'D:\深度学习\数据集\raw.csv' # 读取数据 dataset = read_csv(data_path,sep=',', parse_dates = [['year', 'month', 'day', 'hour']], index_col=0, date_parser=parse) # 删除NO列 dataset.
业务场景1:一个日期选择的是2023-03 其实含义是2023-03-31 另一个年月日不能早于这个日期 比如:2023-03-15 就不行 所以比较的时候 应该把2023-03 转成月末那一天 。
使用day.js
dayjs(new Date()).endOf('month').format('YYYY-MM-DD') 业务场景2:比如说之前我用年月控件 现在是6月 之前的校验是比较月份 选择6月不报错 但业务是不能选择6月 只能选择最早前1月。
dayjs(new Date()).subtract(1, 'month').format('YYYY-MM')
2022年3月截止,编程语言比例(市场份额)中,JAVA跟CPP(C++)共同占据半壁江山。两者的占比也是平分秋色。其他紧随其后的是javascript、python、C#……
市场份额
工资概况
上面表格清晰列出了当下编程领域的薪资分布情况,市场需求情况。可以看出,拿的最高薪资的是rust,但需求的人才不多。需求量最多的还是java跟Python。上面统计数据供同学们参考把握。
总之,IT行业是目前时代社会发展的领军行业、高薪行业,随着计算机的发展和人工智能的普及,必将给IT行业人带来越来越多的机遇和挑战。坚定自己的信念,合理地选择自己的编程语言,一路无畏前行!
最后免费分享给大家一份Python全套学习资料,包含视频、源码,课件,希望能帮到那些不满现状,想提升自己却又没有方向的朋友。
关于Python技术储备 学好 Python 不论是就业还是做副业赚钱都不错,但要学会 Python 还是要有一个学习规划。最后大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!
一、Python所有方向的学习路线 Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
二、Python必备开发工具 三、Python视频合集 观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。 四、实战案例 光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。 五、Python练习题 检查学习结果。 六、面试资料 我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。 这份完整版的Python全套学习资料已经打包好,需要的小伙伴可以戳下方链接免费领取
读者福利《Python全套学习资料》,戳这里免费领取!!!
OSI网络分层及TCP
TCP/IP体系结构
首先简单说一下OSI参考模型,OSI将网络分为七层,自下而上分别是物理层、数据链路层、网络层、传输层、会话层、表示层、应用层,而TCP/IP体系结构则将网络分为四层,自下而上分别是网络接口层、网络层、传输层、应用层。为了将每一层讲明白,我们讲网络接口层拆分为物理层和数据链路层,我在《图解TCP/IP》上面找了一张OSI参考模型和TCP/IP体系结构的对照图,大家可以看一下:
绍了了TCP/IP有哪几层后,再来说一说每一层的大概功能。计算机的世界很奇妙,它里面有很多东西和现实世界都是一一对应的,这也可能是计算机设计者们有意而为之的吧。我先来说一下一个数据包在网络中的传输过程,再来用物流的例子对照着解释一遍,你就应该能够明白每一层的作用了。
看上面的图,发送端想要发送数据到接收端。首先应用层准备好要发送的数据,然后给了传输层,传输层的主要作用就是为发送端和接收端提供可靠的连接服务,传输层将数据处理完后就给了网络层。网络层的功能就是管理网络,其中一个核心的功能就是路径的选择(路由),从发送端到接收端有很多条路,网络层就负责管理下一步数据应该到哪个路由器。选择好了路径之后,数据就来到了数据链路层,这一层就是负责将数据从一个路由器送到另一个路由器。然后就是物理层了,可以简单的理解,物理层就是网线一类的最基础的设备。
可能有很多同学看到我上面的一段话后还是一知半解,没关系,我再用物流的例子解释一遍你就明白了:
小明住在上海市长江路幸福小区5#666,现在小明在京东上面买了一部小米10Pro。京东在接到小米的订单后,工作人员从仓库中找到一部小米10Pro(应用层)。工作人员将手机打包好, 交给了京东物流(传输层)。接下来手机就到了转运中心(路由器),转运中心根据时间,成本等一系列因素决定下一步该发往哪一个转运中心(网络层)。决定好接下来发往哪一个转运中心后就开始用货车运输了,那么运输的过程就是数据链路层了,链路层负责将数据从一个端点送到另一个端点。那么货车行驶的道路就是物理层。几经周转,手机安全地送到了小明手上。
TCP协议 先来看一下百度百科对于TCP协议的定义:传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。这段文字是什么意思呢,我们再接着说上面一个例子。
发货之前工作人员首先得要确认一下路是不是通吧,比如现在是过年,物流全部停运不就是路不通吗,那还发什么货呀。要是没什么问题,物流全部正常运作就发货呗。手机到达小明家后,小明先拆开看看手机在运输途中有没有损坏,有损坏就联系客服处理,没问题就确认收货。再回到上面的定义中,面向连接指的是先建立连接再发送数据,也就是先确认路可以走得通再发货。可靠就是如果货物在运输过程中有损坏或者丢失就让京东重新发货,确保小明收到的手机是没有任何问题的。基于字节流的意思就是比如小明买了手机又买了手机配件,分开发货,几件物品不是在一个包裹里,一个一个发。在这个例子中,京东的工作人员和小明充当了TCP协议的角色,他们两个共同确保了货物的完整性。
TC 用于模拟丢包和延时
注:命令中eth0是需要模拟弱网的网卡,可通过ifconfig查看。
查看规则信息
tc -s qdisc ls dev eth0 tc qdisc show 删除规则
tc qdisc del dev eth0 root 丢包率
tc qdisc add dev eth0 root netem loss 10% : 丢包率为10%tc qdisc add dev eth0 root netem loss 10% 30% : 丢包率为范围(10%- 30%) 延时
# 廷时100ms tc qdisc add dev eth0 root netem delay 100ms # 廷时100ms ± 10ms tc qdisc add dev eth0 root netem delay 100ms 10ms # 廷时100ms 25%概率以±10ms波动延迟 tc qdisc add dev eth0 root netem delay 100ms 10ms 25% 最大带宽1Mbit
一、以太网简介 以太网(Ethernet)是当今最通用的通信协议标准,他规定了包括物理层的连线、电子信号、介质访问协议的内容。
优点:成本低、通信速率高、抗干扰性强
标准以太网:10Mbit/S 快速以太网:100Mbit/S 千兆以太网:1000Mbit/S 1.1、以太网接口 引脚编号引脚名称说明Pin1TX+发送数据+ (发送差分信号:+)Pin2TX-发送数据- (发送差分信号:-)Pin3RX+接收信号+ (接收差分信号:+)Pin4NC未使用Pin5NC未使用Pin6RX-接收信号- (接收差分信号:-)Pin7NC未使用Pin8NC未使用 1.2、PHY芯片 PHY芯片在发送数据时,首先将MAC(主机:单片机或者FPGA)发送过来的并行数据转化成串行数据,按照物理层的编码规则把数据编码转换为模拟信号,通过网口发送出去。
PHY芯片在接收数据时,首先将网络上(RJ45接口)发送过来的模拟信号转化成数据,再通过通信协议(MII、RMII、SMI)发送给MAC(主机单片机或者FPGA)。
当网卡接入网线时,PHY芯片不断发出脉冲信号来检测对端是否有设备,他们互相协商并确定连接速度、双工模式、是否采用流控制等,这个过程叫做“自动协商”。
总结:PHY芯片在网络通信中的作用是:主芯片 和网络设备 之间的 模拟信号 与 数字信号 的相互转换。
1.3、MII接口 MII即媒体独立接口,也叫介质无关接口。它是IEEE-802.3定义的以太网行业标准。它包括一个数据接口,以及一个MAC和PHY之间的管理接口。
名称说明ETH_RXC该信号提供进行RX(主芯片接收)数据传输时的参考时序ETH_RXDVRX(主芯片接收)数据有效信号ETH_RXD[3:0] 数据接收信号。该信号是 4 个一组的数据信号,由 PHY 同步驱动,在MII_RXDV 信号有效时才为有效信号(有效数据)。MII_RXD[0] 为最低有效位,
MII_RXD[3] 为最高有效位。
当 MII_RX_DV 禁止、MII_RX_ER 使能时,特定的MII_RXD[3:0] 值用于传输来自 PHY 的特定信息。
ETH_TXC该信号由主芯片提供,是主芯片TX发送数据传输时的参考时序ETH_TXEN发送数据使能信号ETH_RXD[3:0] 数据发送信号。该信号是 4 个一组的数据信号,由 MAC 子层同步驱动,在MII_TXEN 信号有效时才为有效信号(有效数据)
MII_TXD[0] 为最低有效位
MII_TXD[3] 为最高有效位。
禁止MII_TXEN 时,发送数据不会对 PHY 产生任何影响
ETH_RESETPHY芯片复位信号ETH _MDC 数据线,数据输入/输出比特流,用于通过MDC 时钟信号向/从PHY 设备同步传输状态信息。
(主芯片访问PHY芯片寄存器的接口)
ETH _MDIO 时钟线,周期性时钟,提供以最大频率2.5 MHz 传输数据时的参考时序。
MDC的最短高电平时间和最短低电平时间必须均为160 ns。MDC的最小周期必须为400 ns。在空闲状态下,SMI管理接口将 MDC时钟信号驱动为低电平。
Ubuntu18.04:gnutls_handshake() failed: Error in the pull function.
克隆GitHub仓库
git clone https://github.com/trekhleb/javascript-algorithms.git --depth=1 出现错误
fatal: unable to access 'https://github.com/trekhleb/javascript-algorithms.git/': gnutls_handshake() failed: Error in the pull function. 错误原因分析:
git使用了libcurl4-gnutls-dev,而在ubuntu18中该库作出了修改,导致git无法使用SSL进行连接。
解决方案:安装依赖包
sudo apt-get -y install build-essential nghttp2 libnghttp2-dev libssl-dev
# React学习--day01 ## 一、React简要介绍和学习路线
### 1、React是什么?
React官方解释是用于构建用户界面的JavaScript库
目前对于前端开发来说,几乎很少直接使用原生的JavaScript来开发应用程序,而是选择一个JavaScript库(框架)
在过去的很长时间内,jQuery是被使用最多的JavaScript库;
在过去的一份调查中显示,全球前10,000个访问最高的网站中,有65%使用了jQuery,是当时最受欢迎的JavaScript库;
但是,目前甚至已经处于淘汰的边缘了;
### 2、如何学习React?
1)官方文档阅读网址:https://zh-hans.reactjs.org/
2)开源项目,eg:And Design
个人路线:还是跟着coderwhy先把基础学扎实了,再看开源
### 3、React课程体系(coderwhy)
更正:三、Rudex==>Redux
## 二、邂逅React开发
### 1、React的介绍和特点
1)**介绍:**React:用于构建用户界面的JavaScript库(网址:https://zh-hans.reactjs.org/)
2)**特点:**
**声明式编程**:
声明式编程是目前整个大[前端开发](https://so.csdn.net/so/search?q=前端开发&spm=1001.2101.3001.7020)的模式:Vue、React、Flutter、SwiftUI;
它允许我们只需要维护自己的状态,当状态改变时,React可以根据最新的状态去渲染我们的UI界面;
**组件化开发:**
组件化开发页面目前前端的流行趋势,我们会将复杂的界面拆分成一个个小的组件;
如何合理的进行组件的划分和设计也是后面我会讲到的一个重点;
**多平台适配:**
2013年,React发布之初主要是开发Web页面;
2015年,Facebook推出了ReactNative,用于开发移动端跨平台;(虽然目前Flutter非常火爆,但是还是有很多公司在使用 ReactNative);
2017年,Facebook推出ReactVR,用于开发虚拟现实Web应用程序;(VR也会是一个火爆的应用场景);
### 2、Hello React案例说明
需求:在界面上显示一个文本:Hello world;点击文本下方按钮,点击后文本改为Hello React
### 3、React的开发依赖
在编写react代码前,需引入依赖库:
react:包含react所必须的核心代码
kibana和elasticsearch-head安装手册 0 安装包下载 组件安装包下载地址kibanakibana-8.5.2-linux-x86_64.tar.gzelastic官网:https://www.elastic.co/cn/downloads/past-releases#kibana elastic中文社区:https://elasticsearch.cn/download/nodenode-v14.5.0-linux-x64.tar.gzhttps://nodejs.org/dist/v14.5.0/grunt需要联网和npm,无网环境可以通过虚拟机安装npm,再移植npm解决。也可以使用我打包的npm.tar.gz,解压到/home/es目录下。npm install -g grunt-clielasticsearch-headelasticsearch-head-master.zip(需要联网和npm,无网环境可以通过虚拟机安装elasticsearch-head-master,再通过移植elasticsearch-head-master解决。也可以使用我打包的elasticsearch-head-master.tar.gz,解压到/home/es/software目录下)https://github.com/mobz/elasticsearch-head针对没网的机器打包了我的安装包,可以直接从这里获取使用。链接: https://pan.baidu.com/s/14KfV_Vuz1W9l0r7Ox622Zg?pwd=xhi3 提取码: xhi3 1 软件部署 1.1 创建es用户及用户组 root用户操作
groupadd es -g 750 && useradd -g es -u 750 es 1.2 配置用户环境变量 cd /home/es echo 'export ES_HOME=/home/es/software/elasticsearch' >> .bashrc echo 'export ES_TMPDIR=/home/es/logs/tmp' >> .bashrc echo 'export JAVA_HOME=/home/es/software/java' >> .bashrc echo 'export NODE_HOME=/home/es/software/node' >> .bashrc echo 'export NODE_PATH=$NODE_HOME/lib/node_modules' >> .bashrc echo 'export PATH=$JAVA_HOME/bin:$ES_HOME/bin::$NODE_HOME/bin:$PATH' >> .bashrc 1.3 创建相关目录 软件目录
su - es -c "mkdir /home/es/software"
一、问题描述 docker中有的时候需要从容器内向外网环境进行访问,这个时候我边出现了一个诡异的问题,从容器的宿主机直接通过curl命令使用域名可以正常的访问并返回正确的解决,但是从容器中向外调用外网环境的这个域名的时候,curl命令会被卡住,一直到超时都没有任何返回数据,但是一个很神奇的事情是,如果将该域名换成对应的IP的时候,从容器内向外调用外网环境的这个IP的时候,这个时候就可以正确的返回结果
调用正常:
调用无响应:
二、问题根因 出现了上面的问题,通过查看调用命令返回的结果,发现出现该问题的主要原因是由于在域名调用的过程中会出现在容器内域名无法解析的问题.
三、解决办法 3.1 查看docker容器的虚拟网桥配置
docker network ls 如果是通过run命令来启动容器的话,只需要增加 --net=host这个参数,具体命令如下所示:
docker run -d --net=host --name nginx-1 nginx:latest 下面我们来讲解一下上面的这个启动命令中增加 –net=host这个配置参数的作用,该配置的作用主要是表明该容器不会虚拟自己的网卡,配置自己的IP,而是使用宿主机的IP和端口,所以使用这个命令的时候,docker run命令中的 -p也会失效,因为它本来就使用的是宿主机的IP和端口,根本无需进行端口映射,通过上面的配置,我们便可以从容器内通过域名正常的访问外网环境啦
四、知识点补充 通过上面碰到的这个问题,我们知道了docker容器网络模式相关的一些东西,接下来我们就来拓展一下docker网络模式的详细内容。
docker自身有四种网络模式,还有一些自定义的网络模式,我们今天主要来了解一下自身的四种网络模式
Host:容器使用宿主机的网卡是IP端口,不会虚拟自己的网卡,也不会配置自己的IP;设置命令如下: docker run --net=host Container:容器不会虚拟自己的网卡,也不会配置自己的IP,而是和一个指定容器共享IP和端口范围。 docker run --net=container:containerName/containerId None:关闭容器网络功能。 docker run --net=none Bridge:该模式会为每一个容器虚拟网卡并设置IP,并将容器连接到宿主机中创建好的docker0虚拟网桥,通过docker0网桥以及Iptables nat表配置与宿主机通信 docker run --net=bridge 在启动容器的时候,我们可以通过 –net 参数来指定使用哪种网络模式,默认docker容器会使用 bridge 网络模式
通过下面的几个命令,我们可以查看每一种网络往事的详细信息:
查看 bridge 网络模式详情
docker network inspect bridge
文章目录 VirtualBox使用教程安装教程:获取 CentOS 及版本选择在虚拟机上安装CentOS 在虚拟机中允许linux系统卡的原因*配置CentOS安装图形界面系统(X Window System)安装图形界面程序(GNOME)设置默认启动图形界面程序重启虚拟机安装中文输入法及设置合适编程的字体安装VirtualBox增强工具及共享文件夹设置安装 GCC 编译器安装python环境设置VIM编辑器安装Git安装QQ如何选择安装包如何安装?如何卸载? 参考&其他VirtualBox快捷键在终端中显示 Linux 系统信息Vim快捷键Vim入门教程*.tar.gz文件解压缩命令Vim配置教程ununtu镜像Virtual Box安装Ubuntu教程 CSDN的文本编辑简直跟shit一样。
虚拟机(Virtual Machine,简称 VM)是一种软件模拟的计算机系统,它可以在一台物理计算机上运行多个虚拟计算机,并使它们相互独立,就像它们是在不同的计算机上一样。虚拟机可以模拟一台完整的计算机系统,包括 CPU、内存、硬盘、网络接口等硬件设备,以及操作系统和应用程序等软件环境。
虚拟机技术可以帮助用户在同一台计算机上运行多个操作系统和应用程序,从而提高计算机资源的利用率和效率。例如,可以在一台 Windows 计算机上运行 Linux 操作系统和应用程序,或者在一台 Mac 计算机上运行 Windows 操作系统和应用程序。虚拟机还可以用于开发、测试、部署和维护软件系统等方面。
总的来说,虚拟机是一种软件模拟的计算机系统,可以在一台物理计算机上运行多个虚拟计算机,帮助用户实现多个操作系统和应用程序的独立运行和管理。
以下是一些常用的虚拟机软件:
VirtualBox:由 Oracle 公司开发的免费虚拟机软件,支持多种操作系统和虚拟硬件。VMware Workstation:由 VMware 公司开发的虚拟机软件,支持多种操作系统和虚拟硬件,包括高级功能如快照和克隆等。Hyper-V:由 Microsoft 公司开发的虚拟化技术,内置于 Windows 操作系统中,可以在 Windows Server 和 Windows 10 中使用。Parallels Desktop:由 Parallels 公司开发的虚拟机软件,专为 macOS 设计,可以在 macOS 上运行 Windows 和其他操作系统。QEMU:一个开源的虚拟机软件,支持多种硬件模拟和多种操作系统。Xen:一个开源的虚拟化平台,可以运行多个虚拟机,并支持多种操作系统。KVM:一个开源的虚拟化平台,可以在 Linux 操作系统中运行,支持多种操作系统和硬件。
总的来说,虚拟机软件提供了一种在同一台计算机上运行多个操作系统的解决方案,可以帮助用户进行开发、测试和学习等工作。可以根据自己的需求选择合适的虚拟机软件。 VirtualBox使用教程 为什么使用VirtualBox:
免费:VirtualBox是一款开源软件,完全免费。跨平台:VirtualBox支持在Windows、MacOS、Linux等多个操作系统上运行。易于使用:VirtualBox具有直观的用户界面,易于安装和使用。多功能:VirtualBox支持多种操作系统和应用程序的运行,包括Windows、Linux、MacOS、Solaris等。灵活性:VirtualBox支持多种虚拟机配置选项,包括网络设置、存储配置等。安全性:使用VirtualBox可以隔离虚拟机和物理机之间的环境,从而提高安全性。易于备份和恢复:VirtualBox支持虚拟机的备份和恢复,方便快捷。 安装教程: 下载安装包:从 VirtualBox 官网下载适合您操作系统的安装包。
在左侧的Downloads下载。
打开安装包:双击下载的安装包,打开安装向导。
点击“下一步”:按照安装向导提示,点击“下一步”按钮。
选择安装类型:选择您想要安装的 VirtualBox 组件。通常情况下,您可以选择默认的安装选项。
通过键盘输入电文,如输入一个字符串“zero”,存储到字符数组中;定义加密函数encrypt (),电文加密的原则分为4种情况:
第一种:如果字符为小写字母z直接变换成为a;
第二种:如果字符为大写字母Z变换成为A
第三种:小写字母a ~y与大写字母A~Y转换成其直接后继字母,如: d变换成为e,B变换成C;
第四种: 电文中的非字母字符不变。
输出加密后的电文。
#include <iostream> using namespace std; void encrypt(char dta[10]) { for (int i = 0; i < 10; i++) { if (dta[i] == 'z') { dta[i] = 'a'; continue; } if (dta[i] == 'Z') { dta[i] = 'A'; continue; } if (dta[i] >= 'a' && dta[i] <= 'y') { dta[i] += 1; continue; } if (dta[i] >= 'A' && dta[i] <= 'Y') { dta[i] += 1; continue; } } } int main() { char dta[10]; cout << "
超参数优化方法 https://en.wikipedia.org/wiki/Hyperparameter_optimization
深度学习模型超参数优化是指通过调整模型的超参数(即不由模型自身学习的参数)来改善模型的性能和泛化能力。超参数包括学习率、批次大小、层的数量和大小、正则化参数等。
超参数优化可以被视为在超参数空间中搜索最优解的过程。超参数空间由各种超参数的取值范围组成,搜索的目标是找到最佳的超参数组合,使得模型在给定任务和数据集上达到最佳性能。
此外超参数优化是一个迭代的过程,目标是找到一组最佳的超参数配置,以最大程度地提高模型的性能。以下是一些常见的超参数优化方法:
网格搜索(Grid Search):遍历预定义的超参数组合,通过交叉验证或验证集上的性能评估来确定最佳组合。这种方法适用于超参数空间较小的情况,但当超参数数量增加时,计算成本会急剧增加。
随机搜索(Random Search):随机选择一组超参数组合,并通过性能评估来选择最佳组合。相对于网格搜索,随机搜索可以更好地处理超参数空间较大的情况,并且通常具有更高的效率。
贝叶斯优化(Bayesian Optimization):使用贝叶斯方法建立超参数与模型性能之间的函数关系,通过不断选择具有最大期望改进的超参数进行迭代优化。贝叶斯优化通常能够在相对较少的迭代次数内找到更好的超参数组合。
梯度优化(Gradient-based Optimization):将超参数优化问题转化为梯度优化问题,通过计算超参数对模型性能的梯度来更新超参数。这种方法需要模型性能关于超参数的梯度信息,通常需要更复杂的推导和计算。
自动机器学习(AutoML):使用自动化工具和算法搜索超参数空间,以找到最佳的超参数组合。AutoML方法结合了以上的方法,并引入了自动化的流程来加速超参数搜索和模型选择过程。
遗传算法(Evolutionary optimization):将超参数组合看作是个体,并通过遗传算法的操作(如选择、交叉和变异)来模拟进化过程。初始时,随机生成一组超参数组合作为种群,并通过交叉和变异等操作生成新的个体。
早停法(Early stopping-based):根据验证集上的性能指标(如验证误差或准确率)来监控模型的训练过程。训练过程中,如果验证集上的性能指标在一定轮次内不再改善或开始出现下降趋势,就可以停止训练,避免过拟合。
YOLO V5 超参数 https://raw.githubusercontent.com/ultralytics/yolov5/master/train.py
weights:初始权重路径,指定用于模型初始化的权重文件的路径。
cfg:模型配置文件的路径,指定用于定义模型结构的配置文件。
data:数据集配置文件的路径,指定用于加载训练和验证数据的配置文件。
hyp:超参数文件的路径,指定包含训练过程中的超参数设置的文件。
epochs:总的训练轮数,指定要执行的训练迭代次数。
batch-size:每个批次的图像数量,指定每个训练批次中要使用的图像数目。
imgsz:训练和验证图像的尺寸(像素),指定用于训练和验证的图像的大小。
rect:是否进行矩形训练,如果启用,则在训练过程中将图像调整为固定的矩形尺寸。
resume:是否恢复最近的训练,如果设置为True,则会自动加载最近的训练检查点并继续训练。
nosave:是否只保存最终的检查点,如果启用,则只保存最后一个训练轮次的模型检查点。
noval:是否只验证最终的训练轮次,如果启用,则只在最后一个训练轮次进行验证。
noautoanchor:是否禁用自动锚框的计算。
noplots:是否保存不生成任何图表文件。
evolve:进化超参数的代数数目,指定要对超参数进行进化优化的代数数目。
bucket:gsutil存储桶的名称,指定要将训练结果上传到的存储桶。
cache:图像缓存方式,指定训练过程中使用的图像缓存方式(ram或disk)。
image-weights:是否在训练中使用加权图像选择。
device:设备选择,指定要在哪个设备上进行训练(cuda设备或CPU)。
multi-scale:是否在训练过程中使用多尺度数据增强。
single-cls:是否将多类别数据训练为单类别。
optimizer:优化器选择,指定要使用的优化器(SGD、Adam或AdamW)。
sync-bn:是否使用同步批归一化,在DDP模式下可用。
workers:最大数据加载器工作线程数目(DDP模式下每个RANK的最大工作线程数)。
project:保存路径的项目名称,指定保存训练结果的项目名称。
name:保存路径的实验名称,指定保存训练结果的实验名称。
exist-ok:是否允许使用已存在的项目和实验名称,如果启用,则不会增加新的编号。
quad:是否使用四通道数据加载器。
cos-lr:是否使用余弦学习率调度程序。
label-smoothing:标签平滑的ε值,指定用于标签平滑的ε值。
patience:EarlyStopping的等待次数(未改进的训练轮次数)。
freeze:冻结层的索引列表,指定要冻结的网络层。
save-period:每隔多少轮保存一次检查点(如果小于1,则禁用保存)。
seed:全局训练种子,指定用于训练的随机种子。
local_rank:自动DDP多GPU参数,不要修改。
YOLO V5 训练建议 https://docs.ultralytics.com/yolov5/tutorials/tips_for_best_training_results/
如果数据集足够大且标注良好,那么在不改变模型或训练设置的情况下,通常可以获得良好的结果。如果一开始没有获得良好的结果,则可以采取一些措施来改善,但始终建议用户首先使用默认YOLO V5设置进行训练,然后再考虑是否进行任何更改。这有助于建立性能基线并找出改进的方向。
如果对训练结果有疑问,建议从结果图表(训练损失、验证损失、P、R、mAP)、PR曲线、混淆矩阵、训练集合成图像、测试结果以及数据集统计图像中寻找答案。
数据集 每类图像:推荐每类至少1500张图像。
每类实例:推荐每类至少10000个实例(有标签的对象)。
图像的多样性:对于真实世界的使用情况,建议使用不同时间、不同季节、不同天气、不同光照、不同角度、不同来源(在线获取、本地采集、不同相机)的图像等。
标签一致性:所有图像中所有类别的实例必须都有标签。部分标注将无法工作。
标签准确性:标签必须紧密包围每个对象。对象与其边界框之间不应有空白。没有对象应该缺少标签。
在Windows系统上使用WSL和Docker 文章目录 在Windows系统上使用WSL和DockerWindows的Linux子系统(WSL)WSL安装教程在WSL上运行Linux GUI应用 Docker的使用Docker的安装Docker创建Linux容器 参考&其他WSL怎么更新su: Authentication failure问题docker常用指令镜像相关容器相关网络相关数据卷相关其他常见指令 Linux命令大全文件和目录操作命令:文件内容和搜索、排序,压缩命令:系统管理命令:网络管理命令:用户和权限管理命令:环境变量:setterm控制终端属性命令Linux终止指令 Linux的bash终端中的~号和/号是什么Linux 基础知识 /bin,/sbin,/usr/sbin,/usr/bin 目录 区别详解Linux终端新建/删除用户Linux终端新建/删除用户 Windows的Linux子系统(WSL) Windows 的 Linux 子系统(Windows Subsystem for Linux,简称 WSL)是一种 Windows 10 操作系统的特性,它允许用户在 Windows 系统中运行 Linux 应用程序。WSL 实际上是一个兼容层,可以在 Windows 系统上运行 Linux 应用程序,包括命令行工具、脚本和应用程序。WSL 提供了一个 Linux 内核 API 的实现,这个实现可以在 Windows 中运行 Linux 应用程序而无需虚拟化或模拟 Linux 环境。WSL 支持多个 Linux 发行版,包括 Ubuntu、SUSE、Debian 等,用户可以从 Microsoft Store 中下载并安装所需的 Linux 发行版。
WSL 有许多优点,例如:
可以在 Windows 系统中运行 Linux 应用程序,无需双重启动或切换操作系统。可以访问 Windows 文件系统,包括文件和目录。可以与 Windows 应用程序集成,例如可以在 Windows 命令行中运行 Linux 命令。可以使用 Windows 的网络和安全特性,例如可以使用 Windows 防火墙和代理服务器。
1 使用常规方法将cv::Mat转换为unsigned char数组或者float数组 通常情况下,在同一个opencv项目传递cv::Mat可直接通过const cv::Mat& img这种方式传递,但是如果需要进行跨语言传递,比如C++传递到C#或者C#传递到C++,那么通常这种情况下需要将cv::Mat转换为内存指针比如unsigned char指针或者float指针进行传递。
1.1 cv::Mat转换为unsigned char数组、unsigned char数组转换为cv::Mat #include <iostream> #include "opencv/cv.h" #include "opencv2/opencv.hpp" void ConvertOpencvMatToArray() { cv::Mat img = cv::imread("demo.png"); int img_length = img.total() * img.channels(); unsigned char* image_array_ptr = new unsigned char[img_length](); std::memcpy(image_array_ptr, img.ptr<unsigned char>(0), img_length * sizeof(unsigned char)); // 从unsigned char* 再转换为cv::Mat,验证转换是否正确 cv::Mat a = cv::Mat(img.rows, img.cols, img.type(), image_array_ptr); cv::imwrite("a.jpg", a); delete[] image_array_ptr; } int main() { ConvertOpencvMatToArray(); getchar(); return 0; } 1.2 cv::Mat转换为float数组、float数组转换为cv::Mat #include <iostream> #include "
1、什么是JavaWeb? Servlet 是 JavaEE 规范之一。规范就是接口 Servlet 就 JavaWeb 三大组件之一。三大组件分别是:Servlet 程序、Filter 过滤器、Listener 监听器。 Servlet 是运行在服务器上的一个 java 小程序,它可以接收客户端发送过来的请求,并响应数据给客户端。 2、第一个Servlet程序 2.1 实现步骤 实现一个简单的Servlet程序的步骤:
编写一个类去实现 Servlet 接口或者Servlet接口的子类实现 service 方法,处理请求,并响应数据 到 web.xml 中去配置 servlet 程序的访问地址 2.2 继承Servlet接口并实现service方法 public class HelloServlet implements Servlet { /** * service 方法是专门用来处理请求和响应的 * @param servletRequest 客户端的请求 * @param servletResponse 服务器的响应 */ @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { System.out.println("Hello Servlet"); } } 2.3 配置web.xml <?xml version="
文章目录 1.RPN部分的代码1.1 rpn_head.forward_train的代码(base_dense_head.py)1.2 self.loss的代码(rotated_rpn_head.py)1.2.1 get_anchors的代码(anchor_head.py)1.2.1.1 grid_priors的代码(anchor_generator.py)1.2.1.2 single_level_grid_priors的代码(anchor_generator.py)1.2.1.3 gen_single_level_base_anchors(anchor_generator.py) 1.2.2 get_targets的代码(rotated_rpn_head.py)1.2.2.1 _get_targets_single函数的代码(rotated_rpn_head.py) 1.2.3 loss_single函数的代码(rotated_rpn_head.py) 1.3 get_bboxes的代码(rotated_rpn_head.py)1.3.1 _get_bboxes_single的代码(rotated_rpn_head.py) 2. ROI部分的代码2.1 _bbox_forward_train的代码(rotate_standard_roi_head.py)2.1.1 bbox2roi的代码(transformer.py)2.1.2 _bbox_forward的代码(rotate_standard_roi_head.py)2.1.3 bbox_head.get_targets的代码(rotated_bbox_head.py)2.1.3.1 _get_target_single的代码(rotated_bbox_head.py) 1.RPN部分的代码 我们首先定位到RPN部分代码的forward_train部分,位于two_stage.py文件下
经历了Resnet50和FPN两部分的操作后,我们得到了如下的向量:
下面我们要对特征向量进行RPN操作。
if self.with_rpn: proposal_cfg = self.train_cfg.get('rpn_proposal', self.test_cfg.rpn) rpn_losses, proposal_list = self.rpn_head.forward_train( x, img_metas, gt_bboxes, gt_labels=None, gt_bboxes_ignore=gt_bboxes_ignore, proposal_cfg=proposal_cfg, **kwargs) losses.update(rpn_losses) else: proposal_list = proposals 1.1 rpn_head.forward_train的代码(base_dense_head.py) 可以发现,主要代码位于self.rpn_head.forward_train这个函数,我们来看其定义,位于base_dense_head.py文件下
def forward_train(self, x, img_metas, gt_bboxes, gt_labels=None, gt_bboxes_ignore=None, proposal_cfg=None, **kwargs): """ Args: x (list[Tensor]): Features from FPN. img_metas (list[dict]): Meta information of each image, e.
【关键内容】
1.将opencv编译为能在arm上运行的库,直接获取编译后的成果物见:
armv7:https://download.csdn.net/download/u012824853/87867650
armv8:https://download.csdn.net/download/u012824853/87867658
2.在没有板子的情况下,仿真验证opencv库
1.将opencv编译为能在arm上运行的库 1.在下方链接中选择某个版本
Releases - OpenCVhttps://opencv.org/releases/点击“Sources”即可开始下载,得到opencv-3.4.1.zip:
2.解压,得到opencv-3.4.1到/home/ubuntu/opencv/opencv-3.4.1/
unzip opencv-3.4.1.zip 3.打开cmake-gui:
cd opencv-3.4.1 mkdir build cd build cmake-gui& 4.
where is the source code:刚下载解压后的opencv-3.4.1的路径
where to build the binaries:刚下载解压后的opencv-3.4.1的路径中的build
然后点击Configure
5.Operation System必须为Linux,Processor必须为arm
Compilers的C为自己PC/服务器中的C交叉编译工具链所在位置
Compilers的C++为自己PC/服务器中的C++交叉编译工具链所在位置
Target Root为自己PC/服务器公用头文件所在位置
Include Mode为Search only in Target Root
点击Finish
6.等到Configuring done
勾选BUILD_JPEG和BUILD_PNG
另外CMAKE_INSTALL_PREFIX也重新选择一下:
7.再次点击Configure,等待Configuring done,点击Generate,等待Generating done,可以关闭cmake-gui了
8.在/home/ubuntu/opencv/opencv-3.4.1/build中运行make -j32,等待100%,然后执行sudo make install,无报错即完成opencv arm交叉编译,所有的编程成果物都在刚才设置好的CMAKE_INSTALL_PREFIX中
2.仿真验证 1.在没有arm板的情况下,在PC/服务器上做仿真验证:
sudo apt-get install qemu
编写main.cpp
#include "opencv2/core.hpp" #include "opencv2/imgproc.hpp" #include "
前言 下面为大家整合了一些Java在线编程的的网站,个人认为都是挺好用的,整合不易,希望大家能顺手留下点赞和收藏!
废话少说,我们直接进入正题:
1、菜鸟工具 菜鸟工具的这个在线编程工具页面很为简洁,写代码的区域和结果输出的区域很清晰,可以下载当前编辑的文件,也可以从外部导入文件,同时除了Java在线编辑的功能之外,还支持其他语言的在线编辑,只需要选择切换即可 网页链接:https://c.runoob.com/compile/10/
2、http://Json.cn 页面同样比较的简洁,但是在做的相比菜鸟工具细致一点,可以设置自动运行,支持其他语言的切换,但缺点是没有导出的功能 网页链接:https://www.json.cn/runcode/run_java/
3、ideone ideone对Java的支持不错,但是在代码的运行速度方面比较一般,不过它的有点在于报错的信息很详细也很全面,同时也支持其他语言的切换 网页链接:https://ideone.com
4、tool 支持切换其他语言,同时登陆后可以保存你所写的代码,也可以与tool的博客连接 网页链接:https://tool.lu/coderunner/
5、compilejava compilejava的布局与我们使用的编译器默认的布局比较像,支持导出文件网址、下载文件、改变网页背景主题 网页链接:https://www.compilejava.net
6、JSrun JSrun功能较多,同时不会因此而让人觉得繁杂,运行效果很不错,此外它里面自带Java编程的手册,还有一个代码仓库,点击后可以直接看到他人分享出来的代码,籍此来学习事半功倍,非常推荐 网页链接:http://java.jsrun.net/
7、JDoodle 支持多文件在线编辑,实现项目式的管理,可以说是一个在线的IDE了,支持保存代码、下载代码、导入Maven库、创建Project,缺点是由于是国外的网站有时候容易卡顿 网页链接:https://www.jdoodle.com/online-java-compilerhttps://www.jdoodle.com/online-java-compiler/
如果可以的话,可以给一个点赞收藏吗~
样式:主要是使用 el-popover和el-tabs
html:由于业务需求,我所使用的是input作为触发组件,所以在在触发条件这里要使用自定义trigger="manual"
<el-popover :ref="obj.display_field" :key="index" placement="bottom" width="500" size="medium" trigger="manual" @show="afterEnter" :popper-options="{ boundariesElement: '.el-form', removeOnDestroy: true }"> <el-input v-model="basic[obj.display_field+'CN']" size="medium" readonly="true" :placeholder="'请选择'+obj.field_name" slot="reference" @focus="iptFocus(obj.display_field)" :title="basic[obj.display_field]"> <template slot=""> <span>{{basic[obj.display_field+index]}}</span> </template> </el-input> <template> <el-tabs v-model="selectBank" class="select_bank_list" v-if="isShow"> <el-tab-pane label="常用" name="tab1"> <el-row> <el-col v-for="(item) in commonBanks" :span="7" style="padding: 5px"> <a :class="'BK'+ item.def_bankcode" class="bankIcon"></a> <el-link @click="getbank(item,obj,index)"> <span v-if="item.simp_name!='中国银行'">中国</span>{{item.simp_name}} </el-link> </el-col> </el-row> </el-tab-pane> <el-tab-pane :label="item" v-for="(item) in bankCapitalName" > <el-row v-for="(v,k) in otherBanks[item]"> <el-row :span="
游戏效果图 类的组织(UML) 上图中的Recorder和EnemyTank的行动逻辑未实现,与实际代码有小小的出入
一些核心思路 接口与抽象类 接口Updatable和Redrawable 编写了接口Updatable和Redrawable,实现这两个接口的类是可更新且可重绘的,如GameUnit(游戏单元)
抽象类GameUnit 我设计在坦克大战这样的实时游戏中,一个游戏单元如坦克,子弹,墙等都应该是可随时间流逝而更新的,更新之后,便需要在面板上重绘;亦或者说更新是重绘的前提
游戏单元,既然可重绘,就应该可见,所以具有坐标属性(x和y)
tier(层级)是指游戏单元所含节点在面板(Pane)中的绘制层级,我想通过优先列表来实现不同类型的单元指定摆放次序,因为在BBTankPane中,是通过遍历游戏单元列表,进行重绘,来使各个单元可见的
survival是单元的存活状态,若一个单元已死亡,则会在它的update方法中通知主面板(BBTankPane)在其单元列表中进行删除,那么稍后,这个失去引用的对象便会被gc
类 类BBTankPane BBTankPane类承载了很多功能,本类采用了单例的设计模式,这是为了方便各游戏单元获取它的对象
gameUnitList是游戏单元列表,采用了线程安全的Vector来实现,这个实现没有符合前文对层级的需求
unitListAddT和unitListDelT是后来添加的,因为在使用迭代器遍历游戏单元列表时很难添加或删除游戏单元,所以采用这两个列表暂存要添加和删除的游戏单元们
BBTankPane类实现了Runnable接口,在它的run方法中,先遍历更新各游戏单元(指逻辑更新),再更新单元列表(批量添加和删除单元),最后遍历重绘各游戏单元;这样可以确保在首先的逻辑更新中被判定死亡的游戏单元不会在紧随的重绘阶段被无意义地再次绘制
项目代码 import javafx.application.Platform; import javafx.scene.input.KeyCode; import javafx.scene.layout.Background; import javafx.scene.layout.BackgroundFill; import javafx.scene.layout.Pane; import javafx.scene.paint.Color; import java.util.ArrayList; import java.util.List; import java.util.Vector; /** * @Date 2023/2/27 13:00 * @Created by 邦邦拒绝魔抗 * @Description 绘制背景和各单元(坦克、子弹、爆炸等),处理事件 */ public class BBTankPane extends Pane implements Runnable { private static BBTankPane instance = new BBTankPane(); private List<GameUnit> gameUnitList;//游戏单元列表 private List<GameUnit> unitListAddT;//单元添加暂存 private List<GameUnit> unitListDelT;//单元删除暂存 private HeroTank heroA;//玩家坦克A private HeroTank heroB;//玩家坦克B private boolean needRun = true;//是否仍需运行 public List<GameUnit> getGameUnitList() { return gameUnitList; } public static BBTankPane getInstance() { return instance; } private BBTankPane() { //背景 setBackground(new Background(new BackgroundFill( Color.
为什么Idea只对@Autowired警告?
使用IDEA开发的时候有没有注意到过一个提示,在字段上使用Spring的依赖注入注解@Autowired后会出现如下警告 Field injection is not recommended (字段注入是不被推荐的) 但是使用@Resource却不会出现此提示
网上文章大部分都是介绍两者的区别,没有提到为什么,当时想了好久想出了可能的原因,今天来总结一下:
构造器注入 :利用构造方法的参数注入依赖
Setter注入 :调用Setter的方法注入依赖
字段注入 :在字段上使用@Autowired/Resource注解
事实上,他们的基本功能都是通过注解实现依赖注入 ,只不过@Autowired是Spring定义的,而@Resource是JSR-250定义的。大致功能基本相同,但是还有一些细节不同:
依赖识别方式 :@Autowired默认是byType 可以使用@Qualifier指定Name,@Resource默认ByName 如果找不到则ByType
适用对象 :@Autowired可以对构造器、方法、参数、字段 使用,@Resource只能对方法、字段 使用
提供方 :@Autowired是Spring 提供的,@Resource是JSR-250 提供的
参考Spring官方文档,建议了如下的使用场景:
构造器注入 :强依赖性 (即必须使用此依赖),不变性 (各依赖不会经常变动)
Setter注入 :可选 (没有此依赖也可以工作),可变 (依赖会经常变动)
Field注入 :大多数情况下尽量少使用 字段注入,一定要使用的话, @Resource相对@Autowired 对IoC容器的耦合更低
不能像构造器那样注入不可变的对象
依赖对外部不可见 ,外界可以看到构造器和setter,但无法看到私有字段,自然无法了解所需依赖
会导致组件与IoC容器紧耦合 (这是最重要的原因,离开了IoC容器去使用组件,在注入依赖时就会十分困难)
导致单元测试也必须使用IoC容器 ,原因同上
依赖过多时不够明显 ,比如我需要10个依赖,用构造器注入就会显得庞大,这时候应该考虑一下此组件是不是违反了单一职责原则
Field注入虽然有很多缺点,但它的好处也不可忽略:那就是太方便了 。使用构造器或者setter注入需要写更多业务无关的代码,十分麻烦,而字段注入大幅简化了它们。并且绝大多数情况下业务代码和框架就是强绑定的,完全松耦合只是一件理想上的事,牺牲了敏捷度去过度追求松耦合反而得不偿失。
那么问题来了,为什么IDEA只对@Autowired警告,却对@Resource视而不见呢? 个人认为 ,就像我们前面提到过的:@Autowired 是Spring 提供的,它是特定IoC提供的特定注解 ,这就导致了应用与框架的强绑定 ,一旦换用了其他的IoC框架,是不能够支持注入 的。
而 @Resource 是JSR-250 提供的,它是Java标准 ,我们使用的IoC容器应当去兼容它,这样即使更换容器,也可以正常工作。
目标检测是计算机视觉中一个非常重要的基础任务,与常见的的图像分类 / 识别任务不同,目标检测需要模型在给出目标的类别之上,进一步给出目标的位置和大小信息,在 CV 三大任务(识别、检测、分割)中处于承上启下的关键地位。
当前大火的多模态 GPT-4 在视觉能力上只具备目标识别的能力,还无法完成更高难度的目标检测任务。而识别出图像或视频中物体的类别、位置和大小信息,是现实生产中众多人工智能应用的关键,例如自动驾驶中的行人车辆识别、安防监控应用中的人脸锁定、医学图像分析中的肿瘤定位等等。
已有的目标检测方法如 YOLO 系列、R-CNN 系列等目标检测算法在科研人员的不断努力下已经具备很高的目标检测精度与效率,但由于现有方法需要在模型训练前就定义好待检测目标的集合(闭集),导致它们无法检测训练集合之外的目标,比如一个被训练用于检测人脸的模型就不能用于检测车辆;另外,现有方法高度依赖人工标注的数据,当需要增加或者修改待检测的目标类别时,一方面需要对训练数据进行重新标注,另一方面需要对模型进行重新训练,既费时又费力。
一个可能的解决方案是,收集海量的图像,并人工标注 Box 信息与语义信息,但这将需要极高的标注成本,而且使用海量数据对检测模型进行训练也对科研工作者提出了严峻的挑战,如数据的长尾分布问题与人工标注的质量不稳定等因素都将影响检测模型的性能表现。
发表于 CVPR 2021 的文章 OVR-CNN [1] 提出了一种全新的目标检测范式:开放词集目标检测(Open-Vocabulary Detection,OVD,亦称为开放世界目标检测),来应对上文提到的问题,即面向开放世界未知物体的检测场景。
OVD 由于能够在无需人工扩充标注数据量的情形下识别并定位任意数量和类别目标的能力,自提出后吸引了学术界与工业界的持续关注,也为经典的目标检测任务带来了新的活力与新的挑战,有望成为目标检测的未来新范式。
具体地,OVD 技术不需要人工标注海量的图片来增强检测模型对未知类别的检测能力,而是通过将具有良好泛化性的无类别(class-agnostic)区域检测器与经过海量无标注数据训练的跨模态模型相结合,通过图像区域特征与待检测目标的描述性文字进行跨模态对齐来扩展目标检测模型对开放世界目标的理解能力。
跨模态和多模态大模型工作近期的发展非常迅速,如 CLIP [2]、ALIGN [3] 与 R2D2 [4] 等,而它们的发展也促进了 OVD 的诞生与 OVD 领域相关工作的快速迭代与进化。
OVD 技术涉及两大关键问题的解决:1)如何提升区域 (Region) 信息与跨模态大模型之间的适配;2)如何提升泛类别目标检测器对新类别的泛化能力。从这两个角度出发,下面将详细介绍一些 OVD 领域的相关工作。
OVD 的基础概念:OVD 的使用主要涉及到 few-shot 和 zero-shot 两大类场景,few-shot 是指有少量人工标注训练样本的目标类别,zero-shot 则是指不存在任何人工标注训练样本的目标类别。在常用的学术评测数据集 COCO、LVIS 上,数据集会被划分为 Base 类和 Novel 类,其中 Base 类对应 few-shot 场景,Novel 类对应 zero-shot 场景。如 COCO 数据集包含 65 种类别,常用的评测设定是 Base 集包含 48 种类别,few-shot 训练中只使用这 48 个类别。Novel 集包含 17 种类别,在训练时完全不可见。测试指标主要参考 Novel 类的 AP50 数值进行比较。
Python作为今天的互联网不可或缺的一门技能,可以成为自己的主业以外,其实它也还是可以成为副业的,那么学好python后可以从事的副业有哪些呢???
自学Python能干的副业
1、兼职处理数据,分析数据是很重要的一点,那么利用python 就能很好地解决
2、兼职查询资料,通过代码在网络上可以获得很多资料;
3、兼职P图,通过Python可以利用相关代码进行批量处理图片。
1 兼职处理数据 虽然说Excel整理数据的能力很强大了,但是在Python面前,还是小巫见大巫了。
因为Python在搜集整理分析数据的过程中会更加快捷。
如果你学会Python了,就可以从网上兼职赚钱啦。
2 兼职信息 学习python之后,通过代码很容易在网络上获得很多资源。对于Python零基础的同学,可以利用业余时间帮助个人或公司,通过Python收集和整理信息来赚取一些生活费,也是很不错的。
3 兼职查询资料 不管你是学生还是工作者,学会信息的搜集整理也是一项不错的技能。
如果你是学生,就可以利用它查询一些资料进行论文写作,如果你是职业工作者,可以通过它来进行网络查找行业信息、竞品消息、网络热点等等。
4.做兼职编程老师 少儿编程的重点是教育,特别是计算思维的教育;代码的世界,只要计算思维okay,用什么语言,只是因为受限于平台。你会看到很多人各种说编程才是重点
少儿编程教育 = 计算思维(核心)+ 教学法(途径)+编程(工具)
最后免费分享给大家一份Python全套学习资料,包含视频、源码,课件,希望能帮到那些不满现状,想提升自己却又没有方向的朋友。
关于Python技术储备 学好 Python 不论是就业还是做副业赚钱都不错,但要学会 Python 还是要有一个学习规划。最后大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!
一、Python所有方向的学习路线 Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
二、Python必备开发工具 三、Python视频合集 观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。 四、实战案例 光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。 五、Python练习题 检查学习结果。 六、面试资料 我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。 这份完整版的Python全套学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】
个人使用,仅供参考
音频文件按0.1s进行切割并保存音频文件 def loop_cutaudio(name,origin_signal,sample_rate): '''每个音频文件去按照0.1秒进行切割''' total_time = len(origin_signal)/sample_rate # 按照0.1的间隔去裁剪音频文件 for i in np.arange(0,total_time-0.1,0.1): filename = f'../car/audio/{name}_{i}.wav' # 写入文件 wavfile.write( filename, sample_rate, origin_signal[int(i*sample_rate):int((i+0.1)*sample_rate)] ) sample_rate ,origin_signal = wavfile.read(i) loop_cutaudio(name,origin_signal,sample_rate) butter滤波器 butter 属于IIR滤波器(无限长脉冲滤波相应器)
滤波器阶数越高,在阻频带振幅衰减速度越快。 # 有较长的过渡带,在过渡带上很容易造成失真。
# 这里假设采样频率为sample_rate,信号本身最大的频率为1000hz,要滤除300hz以下频率成分,则wn=2*300/sample_ratge b,a = signal.butter(N = 10, Wn = 300*2/sample_rate, btype='highpass') high_signal = signal.lfilter(b,a,single_signal) firwin滤波器 firwin 属于 FIR滤波器(有限长脉冲响应滤波器)
设计采用窗法。
num_taps = 128 # 滤波器阶数 cutoff_freq = 200/8000 # 截止频率 h = signal.firwin(num_taps, cutoff_freq) # FIR滤波器设计采用窗法。 high_signal2 = signal.
一、DMA的基本介绍 DMA,全称Direct Memory Access,即直接存储器访问。
DMA传输将数据从一个地址空间复制到另一个地址空间,提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。
我们知道CPU有转移数据、计算、控制程序转移等很多功能,系统运作的核心就是CPU,
CPU无时不刻的在处理着大量的事务,但有些事情却没有那么重要,比方说数据的复制和存储数据,如果我们把这部分的CPU资源拿出来,让CPU去处理其他的复杂计算事务,是不是能够更好的利用CPU的资源呢?
因此:转移数据(尤其是转移大量数据)是可以不需要CPU参与。比如希望外设A的数据拷贝到外设B,只要给两种外设提供一条数据通路,直接让数据由A拷贝到B 不经过CPU的处理。
DMA就是基于以上设想设计的,它的作用就是解决大量数据转移过度消耗CPU资源的问题。有了DMA使CPU更专注于更加实用的操作–计算、控制等。
二、DMA定义 DMA用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。无须CPU的干预,通过DMA数据可以快速地移动。这就节省了CPU的资源来做其他操作。
三、DMA传输方式 DMA的作用就是实现数据的直接传输,而去掉了传统数据传输需要CPU寄存器参与的环节,主要涉及四种情况的数据传输,但本质上是一样的,都是从内存的某一区域传输到内存的另一区域(外设的数据寄存器本质上就是内存的一个存储单元)。四种情况的数据传输如下:
外设到内存内存到外设内存到内存外设到外设 四、DMA传输参数 我们知道,数据传输,首先需要的是1 数据的源地址 2 数据传输位置的目标地址 ,3 传递数据多少的数据传输量 ,4 进行多少次传输的传输模式 DMA所需要的核心参数,便是这四个
当用户将参数设置好,主要涉及源地址、目标地址、传输数据量这三个,DMA控制器就会启动数据传输,当剩余传输数据量为0时 达到传输终点,结束DMA传输 ,当然,DMA 还有循环传输模式 当到达传输终点时会重新启动DMA传输。
也就是说只要剩余传输数据量不是0,而且DMA是启动状态,那么就会发生数据传输。
试验目录 1.配置寄存器的方式点亮一盏灯2.寄存器实现灯闪烁3.HAL库实现跑马灯4.按键控制LED灯5.代码编写,通过寄存器发送字符6.代码编写,通过寄存器发送字符串7.代码编写,通过寄存器设置接收字符8.代码编写,通过寄存器设置接收字符串(自己理解出现问题)9.串口编写,通过HAL库进行字符串发送10.重写printf11.重写scanf12.通过串口控制灯的亮灭13.驱动LED屏14.显示图片15.显示中文字符16.显示英文字符17.按键中断试验18.串口中断试验19.显示器时钟试验20.串口接收中断21.利用Systick实现每隔一秒打印一次“hello world”22.自己设计一款软件定时器(注意数据类型为uint32_t)23.通过软件定时器设置灯闪烁1s24.利用定时器实现1秒打印1个“HELLO WORLD”26.调节灯的亮度27.使用PWM方波调节占空比实现功能28.通过调节PWM占空比实现呼吸灯效果29.高低电平交替控制蜂鸣器30.使用PWM信号控制31.单通道单次转换:采集光照传感器的值32.多通道单次转换(在ADC_Settings中开启扫描模式)33.DMA_ADC单通道采集试验34.DMA_ADC多通道采集试验 1.配置寄存器的方式点亮一盏灯 RCC->IOPENR |=1<<1; //开启GPIOB的时钟 GPIOB->MODER &=~(0x03<<4); //将MODER2置为00 GPIOB->MODER |=1<<4; //将MODER2置为01;开启输出模式 GPIOB->OTYPER &=~(1<<2); //推挽输出模式 GPIOB->ODR&=~(1<<2); //设置GPIOB2输出低电平 2.寄存器实现灯闪烁 void Delay(){//自定义函数计数 for(int i =0;i<50;i++){ for(int j=0;j<60000;j++){ } } } void SetValue(){ //灭函数 GPIOB->ODR |=1<<2; } void ResetValue(){//亮函数 GPIOB->ODR &=~(1<<2); } //main函数 RCC->IOPENR |=1<<1; //开启GPIOB的时钟 GPIOB->MODER &=~(0x03<<4);//将MODER2置为00 GPIOB->MODER |=1<<4;//将MODER2置为01;开启输出模式 GPIOB->OTYPER &=~(1<<2);//推挽输出模式 GPIOB->ODR&=~(1<<2);//设置GPIOB2输出低电平 Delay(); /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ /* USER CODE BEGIN 2 */ /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { SetValue(); Delay(); ResetValue(); Delay(); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } 3.
责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它通过将请求的发送者和接收者解耦,使多个对象都有机会处理请求。在这个模式中,请求沿着一个处理链依次传递,直到有一个对象能够处理它为止。
本文将详细介绍责任链模式的概述、应用场景以及代码示例,来帮助读者更好地理解和应用这个模式。
1. 简介 模式概述 责任链模式的核心思想是将请求的发送者和接收者解耦,使得多个对象都有机会处理请求。在责任链模式中,请求会沿着一个处理链依次传递,每个处理者都有机会处理请求,如果一个处理者不能处理请求,则将请求传递给下一个处理者,直到有一个处理者能够处理它。
责任链模式包含以下几个角色:
抽象处理者(Handler):定义了处理请求的接口,通常包含一个指向下一个处理者的引用,用于将请求传递给下一个处理者。具体处理者(ConcreteHandler):实现了处理请求的接口,具体处理者可以决定是否处理请求,如果不能处理,则将请求传递给下一个处理者。客户端(Client):创建处理者对象并组成责任链的结构,负责将请求发送给第一个处理者。 优点与缺点 优点:
责任链模式可以实现请求的发送者和接收者之间的解耦。发送者只需要将请求发送给第一个处理者,无需关心具体是哪个处理者来处理。这样,系统的灵活性大大增强,可以随时增加或修改处理者的顺序。责任链模式能够避免请求的发送者和接收者之间的紧耦合。每个处理者只需要关心自己负责的请求类型,无需关心其他请求。这样,系统的可维护性也得到了提升。责任链模式可以灵活地动态添加或删除处理者。我们可以根据实际情况来调整责任链的结构,以满足不同的业务需求。 缺点:
复杂度会明显提升,如果责任链过长或者处理者之间的关系复杂,可能还会导致性能下降和调试困难。 应用场景 责任链模式在许多不同的应用场景中都有广泛的应用。下面列举了一些常见的应用场景:
请求处理链:当一个请求需要经过多个处理步骤或处理者进行处理时,可以使用责任链模式。每个处理者负责一部分逻辑,处理完后可以选择将请求传递给下一个处理者,从而形成一个处理链。日志记录:在日志系统中,可以使用责任链模式来记录日志。不同的处理者可以负责不同级别的日志记录,例如,一个处理者负责记录错误日志,另一个处理者负责记录调试日志,然后按照链式结构传递日志。身份验证和权限检查:在身份验证和权限检查系统中,可以使用责任链模式来验证用户的身份和权限。每个处理者可以检查特定的条件,例如用户名和密码的正确性、账户是否锁定等。如果一个处理者无法通过验证,可以将请求传递给下一个处理者。数据过滤和转换:在数据处理过程中,可以使用责任链模式来进行数据过滤和转换。每个处理者可以根据特定的条件过滤数据或对数据进行转换,然后将处理后的数据传递给下一个处理者。错误处理和异常处理:在错误处理和异常处理系统中,可以使用责任链模式来处理错误和异常。不同的处理者可以处理不同类型的错误或异常,并根据需要将错误或异常传递给下一个处理者进行进一步处理或记录。 2. Java 代码示例 在 Java 中实现责任链模式有多种方式,包括基于接口、基于抽象类、基于注解等。下面将详细介绍基于接口的常见实现方式。
基于接口的实现方式是通过定义一个处理请求的接口,每个处理者实现这个接口,并在自己的实现中决定是否处理请求和传递请求给下一个处理者。
首先,我们定义一个处理请求的接口 Handler 以及请求入参 Request:
public interface Handler { void handleRequest(Request request); } public class Request { private String type; // 省略getter、setter } 然后,我们创建3个具体的处理者类实现这个接口,在具体处理者类的实现中,首先判断自己是否能够处理请求,如果能够处理,则进行处理;否则将请求传递给下一个处理者。代码如下:
public class ConcreteHandlerA implements Handler { private Handler successor; public void setSuccessor(Handler successor) { this.successor = successor; } public void handleRequest(Request request) { if (request.
0. 前言 本文主要介绍flannel在k8s网络中作为网络插件通过UDP、VXLAN、HOST-GATEWAY三种模式来解决容器跨主机网络通信的,并通过手动实现这三种模式深入理解其原理。
1. flannel全局网络地址分配机制 每台节点上容器的IP地址是由所属节点自动分配的,那么会存在一个问题是,不同节点上的容器所分配的IP地址则可能会有重复的情况。
flannel设计了一种全局的网络地址分配机制,flannel会为每台节点申请一个独一无二的网段,并存储在etcd中,flannel会将该网段配置到各个节点上的Docker(或者其他容器工具),当前节点上的容器
只从分配的网段里中获取IP地址。
修改docker启动参数–bip来限制节点容器获得的IP范围。
2. UDP模式 2.1 简介 在Flannel的UDP模式中,每个节点都会启动一个UDP服务器,用于监听来自其他节点的数据包。当一个容器向另一个容器发送数据包时,它会将数据包发送到目标容器的IP地址和端口号。Flannel会将该数据包封装在一个UDP数据包中,并将其发送到目标节点的UDP服务器。目标节点的UDP服务器会解析该数据包,并将其传递给目标容器。
2.2 flannel实现UDP流程 flanneld启动后会通过打开/dev/net/tun的方式创建tun设备,名称为flannel0,该设备是用户空间与内核空间的数据包交互的通道。然后再将从tun设备获取的IP数据包封装到UDP数据包中通过物理网卡发送到其他节点中,内核通过UDP端口转发给flanneld然后解包,得到其中的IP数据包,然后再通过tun设备进入内核空间中,通过路由到达网桥,然后再到目的容器中。
flanneld在其中主要做了:
开启了udp服务,并对udp数据包封包和解包节点上路由表的动态更新,也就是从网桥出来的数据包目的IP为其他节点容器IP时,需要路由到flanneld中进行封包,并且在flanneld接收UDP包后解封出来的IP包需要通过路由到网桥docker0中 缺点很明显,仅一次网络传输的数据包经历了2次用户态与内核态的切换,而切换的效率是不高的,每一次的切换都是一次数据的复制。
2.3 手动模拟flannel实现udp实验 首先创建Network Namesapce net1用来模拟容器
ip netns add net1 然后创建一对veth pair网卡veth0和veth1,并将veth0放到net1中,拉起并设置veth0的ip地址为172.19.1.2/24
ip link add veth0 type veth peer name veth1 ip link set dev veth0 netns net1 ip netns exec net1 ip addr add 172.19.1.2/24 dev veth0 ip netns exec net1 ip link set veth0 up 创建网桥设备,拉起并设置ip地址为172.19.1.1/24,将veth1拉起并绑定到网桥bridge0中
# 添加网桥 ip link add bridge0 type bridge ip link set bridge0 up ip a add 172.
一、场景复现
一个经典的面试题
0.1 + 0.2 === 0.3 // false
为什么是false呢?
先看下面这个比喻
比如一个数 1÷3=0.33333333…
这是一个除不尽的运算,3会一直无限循环,数学可以表示,但是计算机要存储,方便下次再使用,但0.333333… 这个数无限循环,再大的内存它也存不下,所以不能存储一个相对于数学来说的值,只能存储一个近似值,这么存储后再取出时自然就出现精度丢失问题
二、浮点数
“浮点数”是一种表示数字的标准,整数也可以用浮点数的格式来存储
我们也可以理解成,浮点数就是小数
在JavaScript中,现在主流的数值类型是Number,而Number采用的是IEEE754规范中64位双精度浮点数编码
这样的存储结构优点是可以归一化处理整数和小数,节省存储空间
对于一个整数,可以很轻易转化成十进制或者二进制。但是对于一个浮点数来说,因为小数点的存在,小数点的位置不是固定的。解决思路就是使用科学计数法,这样小数点位置就固定了
而计算机只能用二进制(0或1)表示,二进制转换为科学记数法的公式如下:
其中,a的值为0或者1,e为小数点移动的位置
举个粟子:
27.0转化成二进制为11011.0 ,科学计数法表示为:
前面讲到,javaScript存储方式是双精度浮点数,其长度为8个字节,即64位比特
64位比特又可分为三个部分:
符号位S:第 1 位是正负数符号位(sign),0代表正数,1代表负数指数位E:中间的 11 位存储指数(exponent),用来表示次方数,可以为正负数。在双精度浮点数中,指数的固定偏移量为1023尾数位M:最后的 52 位是尾数(mantissa),超出的部分自动进一舍零 如下图:
二、问题分析
再回到问题上
0.1 + 0.2 === 0.3 // false
通过上面的学习,我们知道,在javascript语言中,0.1 和 0.2 都转化成二进制后再进行运算
// 0.1 和 0.2 都转化成二进制后再进行运算 0.00011001100110011001100110011001100110011001100110011010 + 0.0011001100110011001100110011001100110011001100110011010 = 0.0100110011001100110011001100110011001100110011001100111 // 转成十进制正好是 0.30000000000000004 所以输出false
再来一个问题,那么为什么x=0.1得到0.1?
主要是存储二进制时小数点的偏移量最大为52位,最多可以表达的位数是2^53=9007199254740992,对应科学计数尾数是 9.007199254740992,这也是 JS 最多能表示的精度
它的长度是 16,所以可以使用 toPrecision(16) 来做精度运算,超过的精度会自动做凑整处理
文章目录 前言文章一研究背景主要方法部分实验结果总结与思考参考资料 文章二研究背景主要方法部分实验结果总结与思考 前言 人类的视觉神经系统对于真实世界的视觉刺激有着非凡的感知与理解能力,比如我们能够准确地识别物体距离和三维几何关系等,这是当前人工智能难以比拟的能力。在人类视觉感知系统中,外部视觉刺激会经过神经编码为神经信号,而神经解码就是根据神经信号得到相对应的视觉刺激,通过研究这个编解码过程能够帮助我们进一步去理解大脑不同区域的功能。
根据不同任务的复杂性和具体目标,这类研究可以分为刺激分类(stimuli classification)、刺激识别(stimuli recognition)和刺激重建(stimuli reconstruction)。比如刺激分类就是根据大脑活动信息去区分视觉刺激中包含的物体类别,刺激识别就是从一组已知的图像中识别特定的视觉刺激,而刺激重构就是直接生成图像。
这篇博文将介绍今年两个比较新的根据人脑活动信号直接生成视觉刺激图像的工作,具体地说,就是根据观测图像时生成的脑补fMRI信号去重建观测图像。
文章一 研究背景 本文要做的一个任务就是根据人脑活动重建视觉图像,更具体地说就是根据人脑的功能性磁共振成像(functional magnetic resonance imaging, fMRI)来重建其观测到的图像。如上图所示,第一行是现有的图像(观测者看到的图像),第二行是模型根据其中一个观测者的fMRI重建得到的图像。
本文提出的方法主要基于Stable Diffusion模型,并且探讨了LDM(latent diffusion model)与人脑独特功能之间的联系,从神经科学的角度对LDM不同成分提供了一种的定量解释。
主要方法 Stable Diffusion
关于Stable Diffusion模型这里就不过多介绍了,感兴趣可以参考我这篇博客(一文速览扩散模型优化过程:从DDPM到条件生成模型Stable Diffusion),其模型结构大致如下所示:
其中z是原始图像输入编码器得到的潜在表征(latent representation),c是输入文本信息表征,数学公式: $ z_c $是去噪后得到的表征,其会送入解码器得到最终的生成图像。
本文直接用的其开源的代码与预训练参数(version 1.4).
解码过程:从fMRI重构图像
解码过程如下图所示,本论文主要要训练的只有两个线性模型(红色部分),其负责将fMRI信号转换成对应的潜在表征(z和c),而Stable Diffusion的其他参数不需要调整。
(i)首先第一步观测者早期视觉皮层(early visual cortex)对应的fMRI信号得到潜在表征z,然后送入解码器得到得到一个粗(coarse)解码图像 X z X_z Xz;
(ii) X z X_z Xz随后会被送入解码器,然后进行加噪过程(扩散模型的前向过程);
(iii)将观测者高层视觉皮层(higher visual cortex)的fMRI信号编码称为潜在的文本表征c,然后与加噪后的表征 z T z_T zT一起进行去噪过程(扩散模型的逆向过程)得到最终的生成图像 X z c X_{zc} Xzc.
线性模型使用的是L2正则化的线性回归,针对不同的观测者单独训练.
编码过程:全脑体素建模
为了去解释LDM模型与人脑活动之间的联系,本文构造了一个全脑体素(whole-brain voxel-wise)编码模型,如下图所示。其通过线性模型来构造Stable Diffusion中潜在表征与人脑体素之间的对应关系,分别对比了不同噪声条件下、不同扩散阶段、不同U-Net层的特征与大脑部位的对应关系。
这一部分就不详细介绍了,感兴趣的可以参见原文,主要是从生物神经学的角度分析了LDM的内在机理。
部分实验结果 上图展示了同一名受试者根据不同潜在表征生成的图像,可以发现:① 仅使用z重建的图像与原图像视觉一致(visually consistent),但语义内容不一致(个人认为这里的视觉一致指的就是整体的颜色与纹理结构);② 仅使用c生成的图像具有高度的语义保真度但视觉不一致;③ 从 z c z_c zc生成的图像同时具有高度语义保真度和视觉一致性。
Activity的作用 Activity是Android程序中的四大组件之一,为用户提供可视化界面及操作。一个应用程序通常包含多个Activity,每个Activity负责管理一个用户界面
Activity的创建 在应用程序已创建的情况下选中【File】->【New】->【Activity】->【Empty Activity】
会出现如下创建Activity的界面
Activity Name 是你要创建的Activity的名字,该项下面的Generate a Layout File 若勾选,则在创建该Activity时同时创建一个布局文件,并在该页面Layout Name处填写你要创建的布局文件的名字;若你创建的Activity不需要布局文件,则可选择不勾选此项。
Launcher Activity 勾选则设置该Activity为最先启动界面,一般选择默认不勾选即可。
Packge name 表示包名,默认即可。
Source Language表示编写该Activity所用编程语言,默认即可。
Activity的创建需要在清单文件AndroidManifest.xml文件中注册,使用上面方法创建的Activity,Android Studio 会自动帮你注册。而通过在源文件夹中创建Activity文件,则需要手动在清单文件中注册。
Activity 的生命周期 Activity的生命周期有:启动状态,运行状态,暂停状态,停止状态,销毁状态。
而生命周期主要涉及了7种方法:onCreate();onStart();onResume();onPause();onStop();onDestory();onRestar()
onCreate():在Activity创建时调用
onStart():在Activity创建或从后台回到前台时调用
onRestar():在Activity从后台回到前台时调用
onResume():在Activity从被覆盖或者从后台回到前台时调用
onPause():Activity被覆盖到下面或者锁屏时调用
onStop():退出当前Activity或者跳转到新Activity时被调用
onDestory():退出当前Activity时被调用,调用之后Activity就结束了
Activity 之间的跳转 Intent称为意图,不仅可以指定当前组件要执行的动作,还可以在不同组件之间进行数据传递。Intent分为显式意图和隐式意图
显式意图
Intent intent=new Intent(this , ShowActivity.class); //创建Intent对象,第一个参数表示当前Activity对象, //第二个参数为要启动的Activity startActivity(intent); //开启ShowActivity 隐式意图
Intent intent = new Intent(); //设置action动作,该动作需要与清单文件中设置的一样 intent.setAction("com.click.StarActivity"); startActivity(intent); 使用隐式意图需要在清单文件目标Activity中配置*<intent-filter>*,指定当前Activity能够响应的action和category
<intent-filter > <action android:name="com.click.StarActivity"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> 数据传递 从Activity1中传递数据到Activity2
Intent intent = new Intent(this,Activity2.
目录
1. 一个大模型开发项目将面临哪些难点?
2. 我需要训练一个100亿参数量的模型,怎么预估所需要的计算资源?
3. 训练过程中,存储梯度所需要的显存空间如何计算?
4. 训练大模型,将面临哪些难点?
5. 分布式训练都有哪些方案?
6. 多机多卡并行训练,机器和卡之间的梯度是如何融合的?
1. 一个大模型开发项目将面临哪些难点? 作为一个大型模型开发项目的技术负责人,你可能会面临以下一些挑战和难点:
数据获取和处理:在大型模型的开发过程中,获取大量高质量的数据是一项非常重要但又具有挑战性的任务。你需要确定数据来源,处理数据的隐私和安全问题,以及处理大数据的存储和处理能力问题。
模型设计和训练:选择和设计合适的模型结构,以及合理的模型参数是一个重要的步骤。此外,对于大型模型,训练时间可能会非常长,你需要有足够的计算资源以及合适的硬件设施。
过拟合和欠拟合:大型模型有时会面临过拟合问题,即模型在训练集上表现良好,但在验证集和测试集上表现不佳。欠拟合则是指模型在训练集上的表现也不佳。为了解决这些问题,你可能需要使用正则化技术、提前停止等方法。
模型解释性和透明性:大型模型往往像一个“黑箱”,很难理解它的内部工作原理。这可能会导致一些问题,比如模型的预测结果难以解释,或者模型在某些情况下的行为难以预测。
模型部署和维护:将训练好的模型部署到生产环境是一个具有挑战性的任务。你需要考虑模型的性能,以及如何将模型与现有的系统和架构集成。此外,你还需要定期维护和更新模型,以确保其持续的性能和准确性。
模型伦理和公平性问题:如果模型的训练数据存在偏见,那么模型的预测结果也可能存在偏见。因此,你需要确保模型的公平性,并且在处理数据时尊重用户的隐私。
资源管理:管理和调度计算资源(如GPUs、CPUs、内存等)以满足大型模型训练的需求是一项重要任务。此外,还需要考虑项目的时间表和预算。
团队协作:作为技术负责人,你需要协调和管理一个多学科的团队,包括数据科学家、工程师、产品经理等。有效的沟通和团队协作是项目成功的关键。
2. 我需要训练一个100亿参数量的模型,怎么预估所需要的计算资源? 预估训练一个100亿参数量模型所需的计算资源是一个复杂的问题,它需要考虑很多因素,如模型结构,训练数据集的大小,训练迭代的次数等。以下是一个大致的框架:
参数存储:首先,需要预估模型参数所需的存储空间。一般来说,每个参数通常用32位(即4字节)的浮点数表示。因此,100亿个参数大约需要40GB的存储空间。但是在训练过程中,你可能还需要存储额外的信息,如梯度、优化器状态等,所以实际所需的存储空间可能更大。
计算能力:预估所需的计算能力比较复杂,因为它取决于模型的结构和训练算法。你需要预估每个训练迭代的计算复杂性,然后乘以训练迭代的次数。对于某些模型,如Transformer,其复杂性与输入序列的长度平方成正比。对于其他一些模型,如卷积神经网络,其复杂性与输入的尺寸成正比。
训练时间:一旦你估计了每个训练迭代所需的计算能力,你可以通过将其乘以训练迭代的次数来预估总的训练时间。然后,你可以根据你的硬件设备的性能(例如,每秒浮点运算次数,FLOPS)来估计实际的训练时间。
内存:模型的参数和中间计算结果需要存储在内存中,这也需要大量的内存资源。你需要考虑模型的大小,批量大小,以及可能的内存优化技术(如梯度检查点)。
数据传输:如果你使用的是分布式训练,那么数据传输也可能是一个瓶颈。你需要考虑数据在不同设备之间的传输时间。
以上只是一个粗略的估计框架,实际的计算资源需求可能根据具体的硬件设备、软件工具、优化技术等因素有所不同。另外,预估过程中也可能需要一些实验来辅助。
3. 训练过程中,存储梯度所需要的显存空间如何计算? 在训练深度学习模型过程中,为了计算反向传播以更新参数,需要在内存中保存梯度信息。为每个参数保存一个梯度,这样就会需要和参数本身一样多的存储空间。
如果你的模型有100亿个参数,那么在理论上,你需要大约相同数量的存储空间来存储这些梯度。在实际操作中,由于各种原因(例如优化器状态、激活函数的中间输出等),实际的存储需求可能会更高。
具体来说,如果你正在使用32位浮点数(单精度浮点数,也就是float32),那么每个参数和每个梯度都会占用4字节的空间。因此,对于100亿个参数,你需要大约40GB的空间来存储参数,再加上40GB的空间来存储梯度,总共需要80GB的空间。
然而,这还只是保存参数和梯度的最低需求。如果你使用了具有额外状态的优化器,如Adam或RMSProp,那么可能还需要额外的存储空间。同样,如果你使用的训练策略需要保存中间的激活值(例如,如果你使用了标准的反向传播或某些类型的规则化),那么还需要额外的空间。
最后,如果显存不足,有一些策略可以帮助减少内存使用,如使用混合精度训练(mix-precision training),使用梯度检查点(gradient checkpointing),或者使用模型并行(model parallelism)。
4. 训练大模型,将面临哪些难点? 训练大型模型确实是一个复杂的挑战,这涉及到许多算法和工程方面的问题。以下是一些你可能会遇到的难点:
算法层面:
优化难题:大型模型有更多的参数,这会使优化变得更加困难。例如,你可能会遇到梯度消失或梯度爆炸的问题,这可能导致训练不稳定或无法收敛。
过拟合:大型模型有更大的容量,这使得它们更容易过拟合训练数据。虽然有一些技术可以防止过拟合,如正则化、早停、dropout等,但是这些方法可能并不总是有效。
泛化:大型模型可能更难泛化到新的数据。虽然大型模型能够很好地拟合训练数据,但是它们可能在新的、未见过的数据上表现不佳。
工程层面:
计算资源:训练大型模型需要大量的计算资源,包括CPU、GPU、内存和存储。这可能需要高性能的硬件设备和有效的资源管理。
存储和内存需求:大型模型需要更多的存储空间来保存模型参数,以及更多的内存空间来保存中间的计算结果。这可能会导致存储和内存成为瓶颈。
训练时间:由于大型模型的计算复杂性,训练时间可能会非常长。你可能需要使用分布式训练或者更高效的优化算法来加速训练。
稳定性和可靠性:大型模型的训练可能会涉及到大量的并行和分布式计算。这可能会导致稳定性和可靠性的问题,例如,硬件故障、网络问题等。
以上就是训练大型模型可能会遇到的一些难点。当然,这些难点并不是不能克服的。有许多研究和技术正在致力于解决这些问题,如更高效的优化算法、更强大的硬件设备、更智能的资源管理等。
5. 分布式训练都有哪些方案? 分布式训练是处理大规模数据和大型模型的一种重要方法,它可以显著减少训练时间。以下是一些主要的分布式训练方案,以及它们的思想、优点和缺点:
数据并行(Data Parallelism):这是最常用的分布式训练方法。在数据并行中,每个处理器都有模型的完整副本,并且每个处理器处理输入数据的不同部分。然后,每个处理器计算其数据的梯度,并将梯度汇总到所有处理器中。最后,每个处理器使用这个汇总的梯度来更新其模型的副本。
优点:简单易用,可以有效利用多个GPU或者CPU进行训练,可以直接减少训练时间。
缺点:由于每个处理器都需要有模型的完整副本,所以它可能受到处理器内存大小的限制。此外,在大规模分布式设置下,梯度通信可能成为瓶颈。
模型并行(Model Parallelism):在模型并行中,模型被划分成多个部分,并且每个处理器处理模型的一个部分。这种方法适用于单个模型太大,无法在一个处理器上完全加载的情况。
优点:允许训练大型模型,超过单个处理器内存的限制。
缺点:模型并行需要细粒度的模型分割和跨处理器的通信,这可能导致复杂性增加。此外,如果模型的各个部分不平衡,那么一些处理器可能会在等待其他处理器的过程中闲置,这会降低效率。
管道并行(Pipeline Parallelism):管道并行是模型并行的一种变体,其中模型的不同层在不同的处理器上处理。每个处理器完成一层的计算后,就将结果传递给下一个处理器。
文章目录 Tesseract库下载Qt版本选择安装步骤 VS2017安装MSVC调试器安装构建套件的导入文字识别功能的检测 最近在给之前Qt医疗管理系统项目添加一个文字识别功能,但是在其中遇到非常多坑,花费了我比较多的时间(查阅了很多文章),这篇文章主要用来整理这些坑(非常详细)。
Qt版本:Qt5.13
VS版本:VS2017
编译器(构建套件):Desktop Qt 5.13.0 MSVC2017 64bit
以上环境都必须保持一致,否则可能会出现意想不到的错误。
Tesseract库下载 我这里选择比较简单的获取库的方法,就是下载已经通过源码编译好的库,当然也可以在GitHub上找到Tesseract的开源项目下载源码自己编译。为什么不选择后者呢?容易出错!如果你是刚接触的小白,本人强烈推荐前者;如果你是大佬,那当我没说哈哈哈~
这个库我已经放到主页的资源下,需要的自取。下载之后解压缩看到以下3个文件夹就说明下载成功。
Qt版本选择 这里我Qt的版本选择的是Qt5.13,大家尽量保持一样,避免出现不必要的错误。
这是之前在官网下载的,但是最近去看好像没有这个版本可以下载了,如果在官网中没有找到这个版本可以通过下面微信名片添加我,找我发安装包。
安装步骤 (1)打开安装包,点击Next。
(2)登录自己的Qt账号,Next。(没有Qt账号的话注册一个即可)
(3)这里最好修改路径,放到D盘,毕竟Qt还是比较大的。然后Next。
(4)勾选以下选项,Next。
(5)Next后开始安装。
VS2017安装 实测VS2019和VS2022都运行不起来,只有VS2017,大家尽量选择VS2017安装,保持版本一致。最近在VS官网上好像也没有看到VS2017的安装包,有需要的可以到我的主页下的资源中选择下载。
(1)点击打开社区版的安装包。
(2)按照下面操作进行勾选。
(3)这里最好修改路径到D盘,毕竟VS也是比较大的。
至此,Tesseract、Qt以及VS2017都已经准备好了。
MSVC调试器安装 虽然我们在安装Qt的时候,有选择MSVC版本,但是这里只会显示MinGW(也就是windows模拟器版本),这时候我们就需要安装一个MSVC调试器。
可以在我的主页资源中找到这个工具下载。
(1)解压后点击安装包,这里路径可以修改成D盘,Next。
(2)选择No,Next。
(3)只需要勾选这个,Install。
构建套件的导入 (1)安装完之后,打开Qt就可以发现MSVC版本的编译器就会自动加载进去。
(2)此时只需要在构建套件中按照红色框中的选,Apply,OK即可。
这样,就成功地将各种环境配置好了。
文字识别功能的检测 (1)新建一个工程,在.pro文件中添加这四个语句,+=后的路径是刚才下载Tesseract库存放的路径,按照我写的这个定位即可。
INCLUDEPATH += D:\QtProject\tesseracte_lib\tesseract_x64-windows\include\tesseract LIBS+= D:\QtProject\tesseracte_lib\tesseract_x64-windows\lib\tesseract41.lib INCLUDEPATH += D:\QtProject\tesseracte_lib\leptonica_x64-windows\include\leptonica LIBS+= D:\QtProject\tesseracte_lib\leptonica_x64-windows\lib\leptonica-1.78.0.lib (2)导入头文件(最重要的是最下面的两个<tesseract/baseapi.h> 和<tesseract/strngs.h>)。使用刚才下载的路径导入即可。
#include <QDebug> #include <QFileDialog> #include <QTextCodec> #include <iostream> #include <memory> #include <allheaders.h> #include <D:/QtProject/tesseracte_lib/tesseract_x64-windows/include/tesseract/baseapi.h> // tesseract提供的关于C++的接口 #include <D:/QtProject/tesseracte_lib/tesseract_x64-windows/include/tesseract/strngs.
最近敲代码时,需要调用其他服务的接口,主要是通过HttpClient去调用接口,这里记录调用时的方法以及中文乱码问题解决。
配置方法 话不多说,直接上代码
public static String doPostJson(String url, String jsonstr, String charset) { HttpClient httpClient = null; HttpPost httpPost = null; String result = null; try { httpClient = new SSLClient(); httpPost = new HttpPost(url); httpPost.addHeader("Content-Type", "application/json"); StringEntity se = new StringEntity(jsonstr,"UTF-8"); se.setContentType("text/json"); se.setContentEncoding(new BasicHeader("Content-Type", "application/json")); httpPost.setEntity(se); HttpResponse response = httpClient.execute(httpPost); if (response != null) { HttpEntity resEntity = response.getEntity(); if (resEntity != null) { result = EntityUtils.toString(resEntity, charset); } } } catch (Exception ex) { ex.
🧑💻CSDN主页:夏志121的主页
📋专栏地址:Java基础+进阶+核心技术专栏
目录
🍛 一、创建JAR文件
🍜 二、安装和使用清单文件
🍝 三、创建可执行的JAR文件
🍠 四、多版本的jar文件
Java中Jar文件是一种归档文件格式,通常用于将许多Java程序组件存储在单个文件中。它可以包含Java类(.class文件)、资源文件和任何其他支持文件。创建Jar文件有助于打包和分发您的应用程序。 🍛 一、创建JAR文件 可以使用jar工具制作JAR文件(在默认的JDK安装中,这个工具位于jdk/bin目录下)
要创建Jar文件,您需要按照以下步骤进行操作:
a. 将所有“ .class”文件放入一个目录中。
b. 打开命令行或终端并导航到该目录。
c. 运行以下命令以创建Jar文件:
jar cvf jar-file-name.jar *.class d. 完成后你会得到一个名为"jar-file-name.jar"的jar文件,其中包含了所有.class文件。
🍜 二、安装和使用清单文件 清单文件是指定Jar文件的元信息文件,包括版本信息、依赖项等。它必须包含在每个Jar文件的META-INF目录中,并命名为MANIFEST.MF。
以下示例演示如何添加自定义Manifes文件到JAR文
javac main.java echo Main-Class: Main >manifest.txt jar cvfm MyJarName.jar manifest.txt *.class 要想编辑清单文件,需要将希望添加到清单文件中的行放到文本文件中,然后运行:
jar cfm jarFileName manifestFileName ... 例如:
jar cfm MyArchive.jar manifest.mf com/mycompany/mypkg/*.class 要想更新一个已有的JAR文件的清单,则需要将增加的部分放置到一个文本文件中,然后执行以下命令:
jar ufm MyArchive.jar manifest-additions.mf 🍝 三、创建可执行的JAR文件 要创建可执行Jar文件,您需要再次按照以下步骤操作:
a. 创建一个命名Main-Class属性的 MANIFEST.MF 文件。例如:
Manifest-Version: 1.
1.DHT11基本知识 (1)单总线 DHT11器件采用简化的单总线通信。单总线即只有一根数据线,系统中的数据交换、控制均由单总线完成。设备(主机或从机)通过一个漏极开路或三态端口连至该数据线,以允许设备在不发送数据时能够释放总线,而让其它设备使用总线;单总线通常要求外接一个约4.7kΩ的上拉电阻,这样,当总线闲置时,其状态为高电平。由于它们是主从结构,只有主机呼叫从机时,从机才能应答,因此主机访问器件都必须严格遵循单总线序列,如果出现序列混乱,器件将不响应主机。
DATA用于微处理器与DHT11之间的通讯和同步,采用单总线数据格式,一次传送40位数据,高位先出。
(2)数据格式 8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据+8bit校验位
data[39:32]+data[31:24]+data[23:16]+data[15:8]=data[7:0]
2.画时序图 由datasheet可知,一次完整的读取过程大致分为:INIT(初始化,即主机唤醒从机,从机响应),READ(40个bit数据的读取),WAIT(每次读取时间间隔需大于2秒,同时这两秒也包含了数据处理)。
首先在INIT初始状态时,主机需要先主动拉低约18ms,因此传输data的i/o口应该定义为inout;
模块框图如下:
首先,因为datasheet里最低的处理时间单位是us,而fpga使用了50MHz时钟,所以要先定义出时间计数器:
当计数到相应的时间主机开始拉低,
拉低的时间要求根据datasheet设定
在主机释放总线后,之后总线被从机接管,从机按照规定时序向主机发送数据;
从机的响应时间应根据datasheet设定;
如何从INIT状态跳转到READ状态呢?
我选择的条件是:cnt_ms==Tbe + 1 && cnt_us == Tgo+Trel+Treh 时,图中其实多计数了1us,但是不影响,而且这些数值也不是绝对的,需要不断去调试才能确定选哪个数值最好,一切以实际测试为主。
根据个人习惯,我先定义了一个读使能信号 read_en,用来协助cnt_h信号,cnt_h是在READ状态下对data的高电平计数,目的就是来区分数据“0”和‘“1”,
当cnt_h计数了23-27us表示“0”’,计数了68us-74us表示“1”;为什么要对data的高电平计数,而不是直接对单个bit数据计数呢,因为“0”和“1”不等长,所以 无法判断单个bit的长度。
那如何取出cnt_h的数值呢,因为无法去定义一个数使得cnt_h等于这个数时将数值取出。
我选择将信号打一拍然后做对比:
这样取出来的数就可以判断是落在23us-27us之间还是68us-74us之间,从而判断出0和1;
将这样的步骤完成40次,基本上就完成了数据的读取;
如何从READ状态跳转到WAIT状态呢?那就可以定义一个cnt_bit信号,当cnt_bit完成计数40次后转到WAIT状态;
3.总结 WAIT状态至少要2秒,这两秒可以用来检查校验码,并且完成温湿度输出或者其他操作,我的很多信号其实没必要生成,我只是为了自己过段时间不忘,不过定义了也并不会占用很多资源,因为不定义这些综合器也会有可能生成类似的资源,一切以实际为主,我的并不是最优解。
资料以及代码:https://pan.baidu.com/s/1_j2y37xk94G0EmKF-rAfjw 提取码:8z0r
(一)实验类型:设计性
(二)实验目的:
1. 掌握Java语言的集合类;
2. 掌握程序调试的常用方法,培养良好的Java编程习惯。
(三)实验内容:
1. 编写一个学生管理程序,选择集合类存储学生的学号、姓名和期末考试各科的成绩(课程名+成绩,假设只包括数学、语文和英语三门课程)。实现如下功能:
(1)学生信息(学号+姓名)录入;
(2)学生成绩录入(课程+得分);
(3)根据姓名查找学号。
(4)根据学号查找姓名。
(5)根据学号查找成绩。
(6)根据学号和课程名查找学生的成绩。
(7)根据学号计算平均分,并屏幕输出。
(8)根据平均分对班级学生成绩排序,按从高到低的顺序输出姓名和平均成绩。
import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Scanner; class Stu { private String id; private String name; private String classChe,classMath,classEng;//课程名 private int che,math,eng;//成绩 public Stu(String id,String name, String classChe,String classMath,String classEng,int che,int math,int eng) { this.id=id; this.name=name; this.classChe=classChe; this.classMath=classMath; this.classEng=classEng; this.che=che; this.math=math; this.eng=eng; }//构造方法直接插入数据 //构造方法不需要写类型!因为不需要返回值 //创建set就是为了存储数据到类中,get就是为了得到单个变量的值 //如果用了重载类储存数据也可不写set,更简洁。 //因为class是动态的,不是静态就不能直接stu[i].che这样获取值 //必须要写一个函数如get实现return来获取值 public String getId(){ return id; } public String getName(){ return name; } public int getEng(){ return eng; } public int getMath(){ return math; } public int getChe(){ return che; } public String getClassEng(){ return classEng; } public String getClassMath(){ return classMath; } public String getClassChe(){ return classChe; } public String find1(String name,int len,Stu[] stu) //写方法的时候表明是对象数组即可 { for (int i = 0; i < len; i++) if (stu[i].
一。去除状态栏
以下是Android去除状态栏的代码示例:
1. 在Activity的onCreate()方法中添加以下代码:
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
2. 在AndroidManifest.xml文件中的Activity节点中添加以下属性:
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
注意:这种方法会移除整个状态栏,包括时间、电量等信息。如果只想隐藏状态栏而不影响其他信息,可以使用以下代码:
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
ActionBar actionBar = getActionBar();
if (actionBar != null) {
actionBar.hide();
}
这个方法只会隐藏状态栏,而其他信息(如时间、电量等)仍然会显示。
二。导航栏的去除方式
第一种方式:
1. 在Activity的onCreate()方法中添加以下代码:
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
2. 在AndroidManifest.xml文件中的Activity节点中添加以下属性:
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
注意:这种方法会移除整个导航栏,包括返回键、菜单键等。如果只想隐藏导航栏而不影响其他功能,可以使用以下代码:
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
ActionBar actionBar = getActionBar();
if (actionBar != null) {
actionBar.hide();
}
这个方法只会隐藏导航栏,而其他功能(如返回键、菜单键等)仍然会显示。
第二种方式:
在onCreate方法的super.onCreate(savedInstanceState)前面添加getSupportActionBar().hide();就可以了。
文章目录 1. 下载安装包2. 安装3. 打开网易云音乐 Ubuntu 版本:Ubuntu 20.04.3 LTS
1. 下载安装包 登录网易云音乐官网,点击网页上方的“下载客户端”栏目
再点击“其他操作系统客户端”,下载 Linux 版
下载下来的安装包是一个 deb 文件,这种文件是 Ubuntu 等系统使用的一种安装包格式
2. 安装 通过快捷键 Ctrl + Alt + T ,打开 Ubuntu 的终端,进入对应安装包的目录
执行以下命令进行安装
sudo dpkg -i 软件名.deb 3. 打开网易云音乐 安装完后,可以通过在 Ubuntu 终端输入如下命令打开网易云音乐
netease-cloud-music 或者点击左下角的“Show Applications”图标打开
网易云音乐打开了,可以在 Ubuntu 系统上顺便享受下音乐了 -_-
Overview Problem How can we test Spring MVC Web Controllers?How can we create HTTP requests and send to the controller?How can we verify the response? status_code, view_name, model_attributes. Spring Testing support Mock object support for web, REST APIs etc.For testing controller, we can use MockMvc.Provides Spring MVC processing of request/response.There is no need to run a server(embadded or external). Development process Add annotation @AutoConfigureMockMvcInject the MockMvcPerform web requestDefine expectionsAssert results
下载链接:下载
下载apk,打开是要求输入flag,随便输入一个
载入jadx,进入程序入口
可以发现show方法中有刚才的关键字符“wrong”,要想输入great所以参数要传入1,所以JNI.getResult返回结果要是1,跟进这个方法
发现加载动态链接库,解压.apk文件找到里面的.so文件载入IDA。找到JNI_getResult。
首先进行初始化v5,v6,v7,然后对v5,v6,v7进行变化,先看init函数
int __fastcall Init(int _v5, char *_v6, char *_v7, const char *_v4, int a5) { int v5; // r5 int v6; // r10 int v7; // r6 if ( a5 < 1 ) // 15>1 { v6 = 0; } else { v5 = 0; v6 = 0; do // 取余的不同值,进行不同操作 { v7 = v5 % 3; if ( v5 % 3 == 2 ) { _v7[v5 / 3u] = _v4[v5]; } else if ( v7 == 1 ) { _v6[v5 / 3u] = _v4[v5]; } else if ( !
1、摘要 本文主要讲解:BP-LSTM-Attention-transformer,含数据,可直接运行,TensorFlow
主要思路:
使用bp神经网络做多分类使用cnn-lstm-attention做时间序列预测使用transformer做时间序列预测 2、数据介绍 bp的数据有八个类别,每个类别里有不同的特征的数据
lstm+attention的数据是时间序列数据,蓄电池按时间的寿命数据
transformer数据是温度值跟pue的关系
3、文件介绍 4、完整代码和步骤 此代码的依赖环境如下:
tensorflow==2.5.0 keras==2.6.0 numpy==1.19.5 matplotlib==3.5.2 torch==1.8.0 opencv-python==4.2.0.32 pandas==1.1.5 scikit-learn==0.22.1 代码输出如下:
主运行程序入口
import math import os import time import csv import numpy as np import pandas as pd import torch import torch.nn as nn import matplotlib.pyplot as plt from sklearn import metrics from sklearn import preprocessing # 导入库 from sklearn.feature_selection import SelectKBest, f_regression from sklearn.metrics import mean_squared_error from sklearn.model_selection import train_test_split from sklearn.