Category: ICT-Information and Communication Technology

  • 量子计算简要介绍

    量子计算是当前前言的科技创新研发领域,相关的计算概念和理论和传统的计算机差异较大,理解起来也挺有难度。今天有机会了解了一下量子计算的最基础的基础部分,加以记录,后面有机会学习更深入的部分的时候也可以回过头来看一些基础的内容,也是作为知识储备能更快的学习后面的内容。技术发展日新月异,终身学习既是时代的需求,也是自我不断成长和进步的要求。 一、布洛赫球 (Bloch sphere)。和经典计算机的比特位不同,量子计算机的信息表示方式为量子位(quantum bit,qubit),其是0和1的叠加态(具体的表示方式可以参考引文),用公式来理解为其是0和1两个状态的线性组合,需要注意的是,这里的线性因子是复数(两个复数因子有归一化约束,即其模的平方和为1)。 经过欧拉方程和global phase等公式和概念的引入和推导,最后得出如下的公式 用布洛赫球 (Bloch sphere)表示为如下的示意结果。 二、单量子比特上的量子操作,量子操作 (Quantum operations)将量子系统的状态转换成一个新的状态,我们通常也称它们为量子门 (Qubit gates),可以用泡利矩阵的形式来表达,双量子态和多量子态的内容后面有机会再详细介绍,具体也可以参考引文1中的相关内容。上面的两点内容只从数学上进行了阐述,其实际的计算和量子力学等关键的物理背景知识是息息相关的,这方面希望后续有机会要多多了解一下。量子比特的叠加态(Superposition State)是量子计算中一个重要的概念,它允许量子比特同时处于多个状态的线性组合。这使得量子计算在某些情况下能够处理并行计算,与经典计算有着显著的区别。(和传统计算机基于经典比特和晶体管数字逻辑电路属于不同的计算范式) 三、量子计算机的物理实现也有多种,有基于超导量子的实现,也有基于光电子的量子计算机的实现,具体实现方式根据技术差异可能比较大。 四、量子算法有对应的软件模拟,如Qiskit是基于python的面向量子计算的开源软件开发框架,由IBM量子计算团队开发和维护,可以构建、 模拟、执行量子电路。 五、量子力学和信息科技的融合发展出现了量子计算,量子通信和量子精密测量等先进技术,也是当前发展的前沿技术,后面由机会也可以多了解一下。 今天是交通大学128周年校庆,我和交大有挺深的渊源,在这里祝贺交大128岁生日快乐,祝愿交大在未来的科教兴国的征程上硕果累累,创造更大的辉煌! References

  • 回溯算法示例数独问题求解

    回溯(backtracking)是遍历整个求解空间的一种常见的方式,一些有名的小游戏如数独的解法,八皇后游戏等都可以通过回溯的方法去求解。回溯的思想基本是通过递归进行的实现。这里以一个数独的场景为例向大家介绍一下实现的思路。 首先对数独的尚未填上数字的格子依次从左到右,从上到下的顺序进行填数字尝试,每填写当前的格子,可以按照条件首先筛选出可能的数字,并尝试将这些数字依次进行尝试填到格子里,当可以填写一个候选时,就跳到下一个还未填写数字的格子。如果后来发现下一个未填写的格子没有解(填写数字不能满足数独条件),则尝试下一个候选,如果所有候选都尝试后整个过程还是无解,则返回上一个格子的下一个候选再进行类似的尝试过程。 回溯过程也可以将看成时一个树的搜索过程,比如在数独场景,第一层节点可以看成是第一个格子的所有候选数字节点,回溯的过程是一个动态扩展这棵树的深度优先遍历的过程。如下示例代码显示了其过程,通过递归进行的实现,如果当前填写满足条件则继续下一个格子的填写,如果不满足则当前格子不填(撤回填写的数字)并考虑下一个候选,如果所有的候选都不满足,则退回到上一层搜索的状态继续搜索树的动态构建。 完整示例代码可以参考如下链接。data-structures-algorithms/backtracking at main · kindlytree/data-structures-algorithms (github.com)

  • 深度学习框架中自动微分的实现

    自动微分的实现为深度学习的框架的梯度回传的计算提供了很大的便捷,我们只需定义好算子(operator),搭建好整个深度神经网络的网络结构后,就可以通过拓扑序构建好(具体拓扑排序方法可以参考引文中的深度优先搜索方法DFS)计算图,然后就可以根据偏微分的链式法则,就可以依次反向计算节点的数值结果,参数梯度等数值了。 在不同的深度学习的框架中,神经网络反向传播的算法实现会存在着一些差异,以早期的比较有影响力的caffe举例说明,caffe的实现中没有算子,而是blob(tensor)和layer,Net三种粒度的结构,各种不同的计算方法的layer(类似于各种不同的operator,如加减乘除)中计算前向和反向的结果,layer的输入为bottom blob,输出为top blob(也有可能存在着inplace的操作)其计算流图的关系是通过Net类中的相关函数进行静态计算的(Init函数)。 深度学习框架经过技术的发展,早期的caffe已经淡出了研发者的视线,不过在当时(还没有出现tensorflow,caffe2,以及pytorch)是相当有影响力的,其中的设计思想也是比较优秀的,有兴趣的读者可以阅读某些layer的forward,backward函数(基于cpu和gpu(cublas库)的矩阵计算)的实现都可以具体阅读源码加以具体深入的理解。不过由于其python的接口支持不是特别丰富,一些特殊的层的自定义实现和框架的重编译门槛比较高,相比pytorch要繁琐很多。 现在基于pytorch的深度学习框架由于其简洁易用而广受欢迎,其网络的定义也更加自由灵活(代码定义网络结构也很方便),基于pytorch的深度学习应用框架也有很多,纷繁多样,比如openmmlab等等。 Reference

  • WordPress本地备份重部署方法

    WordPress作为最有名的开源博客系统之一,由于其便捷的部署方式和丰富的样式和插件,使得其在个人博客,中小型内容管理系统(CMS,content management system)中广受欢迎。这篇博客将记录部署和维护wordpress的一些细节方法和技巧,后续有更多的会继续在文章后面进行补充。 1、部署,docker技术可以使得部署wordpress系统非常便捷,wordpress基本依赖两个docker镜像,mysql和wordpress。部署方式可以通过下面的两个脚本命令启动相关容器进行。在公有云如阿里华为上部署时一般还要配置nginx的conf,购买SSL证书并进行签名部署等操作,一般公有云上也会有相关文档说明,这里不做特别说明。 2、备份,这里用比较笨拙的全量备份到本地并进行本地部署的方式进行介绍。环境为windows10/11和WSL的ubuntu18.04。1、首先通过scp将在服务器上的mysql目录和wordpress的目录全量拷贝到本地。2、拉取两个docker镜像,wordpress和mysql:5.7。3、启动对应的两个docker容器,启动方式为上述的启动脚本示例。 3、进入mysql容器内部(docker exec -it containerid bash),登录到sql服务器(mysql -uroot -ppassword),选择数据库(use databasename),通过sql指令更新本地定义的域名。 4、配置SSL和本地域名解析。具体方法为:1、在WSL的ubuntu环境中生成本地ssl证书,2、检查WSL中的ip;3、在windows原生系统中添加一行本地域名解析(C:\Windows\System32\drivers\etc目录下的hosts文件),格式为:wsl ip:new_domain。其中前两点的CLI(command line interface)命令如下: 5、在WSL中安装配置nginx,conf的配置方法和云平台中的配置方法类似,阿里云华为云上也有相关的配置说明,这里不做赘述。配置好后,通过命令nginx -s reload更新配置属性。然后就可以在windows系统的浏览器的状态栏中输入https://new_domain就可以访问备份的博客系统了。 References

  • Windows系统上安装配置docker环境

    Docker 使用 Google 公司推出的 Go 语言 进行开发实现,基于 Linux 内核的 cgroup,namespace,以及 AUFS 类的 Union FS 等技术,对进程进行封装隔离,属于操作系统层面的虚拟化技术。Docker 在容器的基础上,进行了进一步的封装,从文件系统、网络互联到进程隔离等等,极大的简化了容器的创建和维护。使得 Docker 技术比虚拟机技术更为轻便、快捷。 docker的应用场景挺多,比如一般的AI云平台都是基于docker镜像提供的系统环境,一般的软件开发也会基于docker软件编译和运行环境(如apollo系统的编译运行环境就是基于docker的)。 docker是对于开发者非常友好的工具,从个人经验来看,在docker环境下做开发和部署有如下的好处和便捷:1、docker镜像的开发环境和机器原生系统隔离,机器本身的软件环境不受影响;2、不同的开发环境比如依赖库等可以构建不同的docker镜像来进行隔离(有点类似于anaconda的虚拟环境);3、镜像一次构建后很容易分发共享,如通过docker hub进行push和pull就可以推送本地镜像和远程拉取所需的镜像。这样的镜像机制也同时方便团队合作以及系统生产环境的部署。 在linux系统如ubuntu或其他发行版本上使用docker相对比较容易,而我们平时用windows机器的场景也挺多,本文将记录在windows平台上构建docker开发环境的方法。 1、首先在windows10/11上安装WSL(windows subsystem for linux)环境,由底层虚拟机平台所支持,因此需要开启相关服务。方法为:在桌面底部的搜索栏输入“控制面板”后选择程序-》启用或关闭windows功能后勾选两项:1、适用于Linux的Windows子系统;2、虚拟机平台;3、开启虚拟机服务平台,执行此命令行后继续进行相关的操作。dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart和wsl –set-default-version 2。中间可能需要重启系统以更新相关服务。 2、在桌面底部状态栏中输入“store”选择Windows Store中搜索ubuntu 18.04。然后选择下载,下载完成后即可运行。 3、下载docker desktop for windows程序并安装后既可以通过启动图标来启动docker engine。然后就可以在windows上的Ubuntu系统里使用docker命令了。 Reference

  • 几个基本的线代知识点

    这篇文章简要介绍一下线性代数的相关概念知识,如行列式,特征值,特征向量以及特征值分解,SVD分解等。在这里顺便记录一下以便后续查阅。 1、行列式(determinant),矩阵对应一个特定的值,一般记为det(A),余子式(minor)m_{i,j}一般记为当前矩阵去除i行j列后形成的行列式(由此也可以理解为行列式为递归定义),代数余子式(cofactor)需要在m_{i,j}的基础上再乘上一个因子(-1)^{i+j}形成c_{i,j}。同时有伴随矩阵(adjoint matrix)的概念也是基于代数余子式进行定义的。需要注意,行列式只针对于方阵。 基于伴随矩阵就比较容易计算矩阵的逆。如下所示,也可以看出矩阵的逆要求其行列式不为0。 2、特征值特征向量(也是方阵,对于非方阵来说,是不存在特征值的,但是会存在条件数):满足特征方程(characteristic equatation)det(A-lamda I)=0的lambda的值即为矩阵的特征值。实对称矩阵的特征向量相互正交。特征值有其对应的代数重数(Algebraic multiplicity),每个特征值有其对应的几何重数(Geometric multiplicity,即为其对应的线性无关的特征向量的个数)。缺陷特征值(defective eigenvalue)指的是存在这个特征值的几何重数比代数重数要小的特征值。关于代数重数大于等于几何重数的相关证明,可以参考引文的链接。 3、特征值分解和SVD分解,可以参考引文3和引文4,其中特征值分解满足方阵,实对称矩阵的特征向量线性无关且为相互正交,PCA就用到了这个特性,SVD分解可以解决不是方阵的情况,但是可以通过转化为特征值分解的方法去进行求解,具体的方法可以参考引文3。特征值的计算方法可以用QR分解来进行。 References

  • 交互式VR在视觉增强方面可能的应用

    人类个人的感知,认知和创造性都是有限制的,这里仅从视觉感知增强的方面来说一说元宇宙相关技术的作用。所描述的场景和应用只是一些可能的案例,实际上会有更多丰富的场景,但也有待去更好的在技术产品上落地实现,在实际中得以很好的应用。 人类在感知上存在着较大局限,比如仅从视觉上来讲,人的眼睛只能感受波长较窄的一段可见光,看不清微观世界运行的细节,也看不清大的宏观宇宙的全貌,人的视角也很有限制,不能同时看到360度周视全貌,以及遮挡视线部分的内容。感知是认知的基础,人类首先能够看得见听得着,才能不断积累对世界的认识并代代相传,智慧才能不断升级。 人类感知能力的局限可以由现在科技的发展进行拓展和增强,人们越来越会制造高级的工具来延申我们的视觉感知,听觉感知以及行动力等等。就拿VR来说,可以应用的场景很多,特别在小的微观细节和大的宏观全貌的交互式可视化上将能够大有所为。这里就简要的来说一说。 比如生物化学这些领域,一些分子结构的交互动态可视化,DNA双螺旋到底长成什么样子,一些生物医药,特别对于生物学和医学的同学,如果能够通过VR技术来可视化很多生物微观的细节结构和动态行为,那这里的学习和理解将更加的直观和深刻。 再比如大的宏观结构,数字孪生地球,太阳系和银河系等等,都是非常有教育价值的场景,通过数字地球,未来我们甚至可以随时云上游览地球的任何一个地方,我们可以通过缩放来了解地月的运行方式,太阳系的行星和卫星,以及可能的太阳系带着自己的行星卫星和星云在银河系中飞奔的场景。 还有很多的场景可以用到,如展示栩栩如生的已经灭绝的古生物,中小学语文课历史课等内容都可以制作设计精良的交互可视化内容。以后VR,AR和AI相结合的元宇宙产品,有更多的内容期待着大家发挥神奇的想象力,期待后面这些方面也能有所实践。

  • Apollo 粗粒度结构及系统启动流程简介

    Apollo系统是智能驾驶领域很有影响力的开源系统,本篇文章从粗粒度上介绍Apollo系统的结构,并分析其其启动流程。后续有机会再介绍细节,不正确的地方欢迎批评指正。 Apollo系统是个比较复杂的系统应用,首先其实现了通信及任务调度的中间件CyberRT(在代码仓的apollo\cyber目录下),也称为Apollo系统的运行时环境(RT即为Runtime),Apollo系统的各个业务逻辑模块,包括感知perception,规划planning,控制control等等各上层的模块,都是基于CyberRT的基础上进行构建的。CyberRT提供了两个核心的运行时功能,1为任务调度,基于协程,多线程实现的不同任务可以按照智能驾驶的业务逻辑编排成高效的执行模式运行,2为通信模式,借鉴了ROS里边的node发布订阅模式,实现了进程内(intra),shm(共享内存单机多进程间通信),rtsp(实时发布订阅协议,多个host之间的网络通信协议),以及hybrid(混合模式,基于component之间通信的物理状态动态选择上述三种模式以达高效通信)。在CyberRT的实现里,一个任务以component为载体,里边的业务处理逻辑通过协程来实现,同时其有对应node,实现了reader和writer,也就是可以接收和发送消息(不同的消息以channel来区分,类似于ros里的topic)。关于通信的实现可以参考apollo\cyber\transport目录下面的代码,引文2中也有相关的介绍。 CyberRT可以理解为在底层操作系统之上构建的一个RTOS,在Apollo的源码仓里,系统的各个模块的逻辑实现依赖于CyberRT提供的接口,这些模块的代码在目录apollo\modules里。具体阅读相关代码实现。 这里以一个模块的启动为例进行说明,一般来说,每一个模块都有一个启动的文件(dag有向无环图文件),如下面的路径为摄像头bev感知模块的dag文件:apollo\modules\perception\camera_detection_bev\dag\camera_detection_bev.dag。一般通过mainboard程序启动一个module。mainboard即为cyberrt运行时编译后生成的可执行文件,会加载CyberRT运行时环境,load相应模块的so文件(一个module可以由多个component组成)。而整个新系统将会是很多个module组成的大系统,因此会有很多个mainboard程序启动,整个智能驾驶系统将是一个多进程程序(不同进程有可能会跨不同的主机host)。具体的启动方式的介绍在引文3中有详细介绍,在此不做赘述。 References

  • Apollo CyberRT的两种任务调度策略实现代码简要说明

    Apollo CyberRT为智能驾驶的中间件(middle ware),提供了类似于ROS概念(并优于ROS平台)的机器人运行时环境。CyberRT在任务的调度上进行了优化的设计,提供了经典调度模式和编排调度模式,使得系统的诸多任务可以按照任务之间的逻辑拓扑结构来进行编排,从而在执行性能上得到很好的保证。同时CyberRT在通信上也做了很好的支持,在单机内部,多机之间的不同component都能够进行高效的通信。这里主要就任务调度方式来做一下说明,也是加以记录以备后面查阅,不正确的地方欢迎批评指正。 首先,在CyberRT实现里,Processor类对应着线程的封装,CRoutine类是对协程的封装,Component类对应着组件(任务)的封装,在Component类里,会创建协程来处理任务。 经典调度模式(ClassicContext):在经典调度模式下,可以将任务进行分组,分组的目的主要是在基于NUMA架构的计算环境上,实现资源的隔离,在同一个组的任务会安排在同一个NUMA节点下运行,这样保证了同一组的任务之间的通信不会由于跨NUMA节点而带来更多的资源消耗和计算时长。而且每一个组下面维护一个多优先级的协程(CRoutine)队列,每一个优先级下面维护一个协程的数组。ClassicContext类对经典调度模式的上下文进行了建模,而且在CyberRT实现里,每一个Processor对应着一个ClassicContext,并且任务(component,以协程的方式实现)的优先级队列作为ClassicContext类成员的静态变量,在不同的线程里边实现共享。ClassicContext调度任务时,会从高优先级的任务里优先调度。在这里补充说明一下,CRoutine的同一个实例可以在不同的线程里调度,CRoutine类里有thread_local类型的相关变量,保证了同一个协程在不同的线程里有对应的相关变量的副本。 编排调度模式(ChoreographyContext):在编排调度模式下,一个Processor对应着一个ChoreographyContext,并且封装了一个multimap类型的变量,key为协程的优先级,value为协程,保证了可以支持同等的优先级下的多个协程。而且这个变量不是静态变量,在多个线程(Processor)之间不共享,保证了执行的协程任务的CPU亲和性(不会在多个cpu之间调度同一个协程),可以基于此通过配置文件来实现任务的编排(如定义某些任务在某些cpu上执行)。 更多的代码细节建议阅读官方开源的代码仓的关键部分,如apollo\cyber\scheduler,apollo\cyber\croutine,apollo\cyber\component等,上述的文字说明都可以在这几个目录的代码里找到实现。 References

  • QR分解及用其求矩阵特征值方法简介

    QR分解是一种特殊的矩阵分解,将矩阵A(m,n)分解为标准正交矩阵Q(m,n)和上三角矩阵R(n,n)的乘积,QR分解可以用来求矩阵的特征值等应用。 首先解释一下施密特正交化的方法,施密特正交化将n个线性无关的向量转化为标准正交向量,其转化的步骤是首选选一个向量,然后在计算第二个向量时,将原始的第二个向量可以分解为第一个向量和垂直于第一个向量的两个向量的和。而可以利用在同一个方向上的两个向量的内积之比值即为两个向量长度的比值等特性求出第二个向量(和第一个向量垂直),以此同样的类似方法求得第三个向量,第四个向量等等。从而得出施密特正交法的公式。具体公式可以参考引文。 经过施密特正交化的方法可以得出n个标准正交的列向量,而且原始的每一个列向量都可以表示为这n个标准正交列向量的线性组合,根据施密特正交向量的生成特点,原始的列向量的线性组合的线性因子刚好符合上三角矩阵的形式。 第二种算法为Householder transformation,其依次利用列向量和标准正交基形成镜像对称的特征去找到变换的Q的关系,得出Q的特性(对称正交),具体算法请参考引文链接。 QR分解的一个用处就是用来计算矩阵的特征值,具体的原理不做特别说明,如有兴趣可以参考引文链接。下图说明了怎么用numpy基于QR分解去计算矩阵的特征值。 References