• [技术干货] 可信隐私计算:破解数据密态时代技术困局
    0  引言数据流通对于国家信息化进程、产业数字化转型是必不可缺的。以前,为了便利数据生产加工和导入导出,许多应用系统常常直接基于明文数据进行开发和流通。在这个过程中,数据流过的每一家机构都有可能会拷贝一份明文数据。随着传播路径的扩散,拥有这份数据的机构越来越多。任何一个机构出现数据滥用或者泄露,都会产生严重影响。可见,明文流通有着显著危害。《中华人民共和国网络安全法》(简称《网络安全法》)、《中华人民共和国数据安全法》(简称《数据安全法》)、《中华人民共和国个人信息保护法》(简称《个人信息保护法》)须要确保所持有的数据安全,并且对数据的使用进行了严格的限制。在大部分场景下,除了匿名化之后的数据或者已经取得用户授权的数据,数据是不允许任意流通的。在这种情况下,密态流通无疑是最好的选择,能够更好地控制数据的使用和流通范围。在数据要素行业发展、安全、法规等多种因素的作用下,密态数据流通会成为未来数据流通的主要形式,促进各行各业安全合规的蓬勃发展,并最终迎来密态时代。当前密态时代才刚刚开启,未来涉及到的场景、处理的数据规模、模型的复杂程度都将远远大于现在。在底层支撑的数据密态技术,一定要达到作为广泛性业务基础设施的技术门槛。(1)性能足够高。在全场景覆盖、大数据、复杂模型的需求下,密态计算的性能要足够高。理想情况下,对于树模型这类中等复杂度的机器学习训练问题,性能要达到每小时处理亿级数据。(2)稳定性足够强。在全场景覆盖、实时场景的需求下,密态计算要足够的稳定,要能够达到和其他基础设施一样的稳定性,在关键应用领域至少能够达到99.99%,甚至更高。(3)成本足够低。为了不对现有计算资源和网络资源造成严重冲击,密态计算相对明文计算的成本增长最好控制在一个数量级以内。(4)适用性足够广。在全场景覆盖的情况下,密态计算要能够支持任意的处理逻辑,尤其是灵活地支持不同数量的参与方。(5)安全性足够高且达成行业共识。密态计算的安全性要足够高,客观上要能够抵御潜在的攻击。另外,在满足安全需求的情况下应选择性价比最高的方案,且该方案要能够得到行业共识。1  密态时代所需的关键技术现状匿名化技术和隐私计算技术是密态时代的基础技术。密态时代对这两项技术的需求也超过以往的任何时刻。匿名化,是指个人信息经过处理无法识别特定自然人且不能复原的过程[1]。匿名化之后的信息在流通的时候,即便泄露也不会泄露个人信息。个人的隐私权可以得到保障,也不会因为信息泄露导致诈骗等。隐私计算技术是指多个参与方在不泄露自己数据的情况下进行联合计算的技术。相比于匿名化只是保护身份信息,隐私计算技术则保护所有的数据信息,能够有效地阻止因数据流通带来的信息泄露风险,并且能够充分保证数据所有者的权益。1.1  绝对匿名化会损失数据价值匿名化的过程通常是对数据进行模糊处理,比如添加噪声或者区间化。一些匿名化后的数据,看似与个人信息无关,但是通过深入的数学分析仍能定位出个人信息。2015年的《科学》杂志载文称,MIT研究人员[2]发现,利用4笔匿名信用卡的交易信息,就可以识别出90%的信用卡持有者的真实身份。2006年,视频网站Netflix公布了用户的匿名化信息,但研究人员发现,通过8部电影的评分信息,就可以唯一标识数据库中99%的用户[3]。可以从信息熵的角度解释为什么匿名化总是失效。全球有80 亿人口,有33 bit的熵就可以唯一定位一个人(233=80 亿)。假设公布了33个特征,每个特征有1 bit有效信息,如果这些信息互不相关,就达到了33 bit的熵。但典型的机器学习使用几百个特征、每个特征几十个比特,远远超过了上述上限。也就是说,在开放的空间中(匿名化信息能够公开获取),匿名化和个体粒度的数据要素价值是两个不可调和的对立面。绝对匿名化的个体粒度信息实际上也不再具备使用价值。1.2  现有隐私计算技术在性能和稳定性上存在严重短板1.2.1  多方安全计算多方安全计算(Secure Muti-Party Computation,MPC)[4]是指基于密码协议达到隐私计算的目标,一般包括秘密分享、混淆电路、不经意传输等,并与加法同态等配合使用。MPC以基于模加的秘密分享最为常见[5]。例如,每个变量都被表示成两(多)个随机数的模加,x=x1+x2 mod 264。在这种表示下,计算加法是很容易的(对应的分量相加),但是计算乘法就困难得多。在不降低安全性的情况下,一般采用不经意传输或加法同态,尤其是后者。图1展示了“MPC+同态”下乘法的典型实现流程。甲、乙分别拥有敏感数据x、y,目标共同计算z=xy,输出z以秘密分享形式表示,即z=z1+z2。具体流程如下(对于维度适当的矩阵也适用)。图1  MPC+同态技术路线下的乘法示例(1)乙将自己的数据y加密后发送。 (2)甲生成一个用于掩盖的随机数r,并使用x、r、Enc(y)基于加法同态算法计算出Enc(xy+r)。 (3)乙解密获得xy+r。 (4)甲、乙拥有的z的分量为z1=-r、z2=xy+r。 上述过程中的消耗是非常大的,需要一系列的加法同态操作和一次公网传输。加法同态的计算量与非对称运算相当(如RSA、SM2),大约在ms级;公网往返耗时在10 ms级;公网传输耗时在100 us级(按1 000 bit传输量,10 Mbit/s 公网带宽估计)。虽然通过硬件加速、批处理等方式能够一定程度上减少或分摊计算消耗、公网往返耗时,但是公网传输耗时是无法通过这些方式减少的。相比于明文计算乘法只需要一个CPU时钟周期,约0.3 ns,两者的差距在5~7 个数量级(取决于批处理的量)。 乘法是整个计算生态的一个基础操作,占比很大,导致MPC技术路线的性能比明文要低5~7 个量级,并且这个差距的很大一部分来自于公网耗时,很难提升。 1.2.2  MPC+中心预计算 为了降低MPC技术的耗时,“MPC+中心预计算”采用中立第三方进行预计算[6]。具体地,引入一个中立第三方,在明文的形式下进行一些预计算,然后将预计算结果分发给MPC的参与方,MPC的参与方实时进行隐私乘法时就不再需要非对称运算等大的运算量。这种方式在安全性上有很大牺牲,如果中立第三方和其中一个参与方合谋,就可以获得其他参与方的数据。也就是说,一个参与方不能完全依靠技术手段保证自己的数据安全。虽然计算耗时很小,但本路线仍然像“MPC+同态”一样每(批)次乘法都需要公网交互,考虑公网传输量一般较后者小,所以与明文的耗时差距大概在4~7 个数量级(取决于批处理的量)。 1.2.3  联邦学习 联邦学习(Federated Learning,FL)的底层也是采用MPC、加法同态等密码协议,但是会把一些看似和原始数据无关的中间过程使用明文进行计算,目的是提升计算性能。这些算法在设计之初时往往没有进行过充分论证。要特别说明的是,这与一般的密码算法设计有很大不同,后者一般要大量密码专家进行长时间的论证。产生这种情况也是因为密态时代到来的太过迅速。过去公开的攻击已经表明[7-10],这种部分明文化的做法并不可靠,存在通过中间过程数据反推出原始信息的隐患。另外,该思路仍然有一部分计算过程需要使用多方安全计算、加法同态等,所以虽然性能比多方安全计算要快,但仍然在相似量级上,计算成本依然居高不下。 1.2.4  全同态 全同态[11-12]支持在密文上直接进行计算,效果等同于在明文上进行计算再加密。但是目前的性能比MPC低,并且数据膨胀效应非常显著,适用范围很小。 1.2.5  可信执行环境 可信执行环境(Trusted Execution Environment,TEE)能够基于硬件提供一个隔离的运行环境,其隔离性不受任何外部软硬件和人员的影响,各方可以将数据汇聚到TEE中进行融合计算。但是,TEE的安全性是依赖于技术体系设计和实现的正确性,受系统漏洞影响。目前,TEE的安全风险主要来自于侧信道攻击和供应链攻击[13-17]。尤其是一些供应链异常的情况会导致攻击者有机会在物理上接近TEE,进而可以实施更多的攻击手段。一旦攻击成功,就有机会窃取TEE内部的数据。 基于密码的隐私计算技术与常见的密码算法有很大不同,需要大量的公网交互,这些交互极大地限制了密码算法的性能。在性能的压力下,一些场景被迫采用有隐患的算法,即便如此,性能仍然严重受限于公网交互。TEE技术受供应链等安全隐患影响,也面临着显著挑战。 2  可信隐私计算技术 2.1  受控匿名化技术解决匿名化困境 在绝对匿名化会损失数据价值的情况下,相对匿名化逐渐成为公认的出路。相对匿名化指的是在不结合密钥、外部场景信息的情况下,无法恢复出个人身份的匿名化技术。受控匿名化技术是指将相对匿名化的数据限制在受控环境中,切断其与外部信息的关联,达到安全性近似绝对匿名化的效果。 在受控匿名化技术中,各个参与方需要在本地对用户身份进行去标识,同时在数据价值损失有限的前提下对属性信息进行模糊处理。上述处理之后的数据仍然要受到严格管控,禁止公开。为此,上述数据必须在受控环境中使用;并且该环境与外部的交互必须受到严格的管控,包括数据的存储、传输、计算、研发等。图2是受控匿名化技术典型的示例图。 图2  受控匿名化示例图(1)参与者对ID等身份信息进行去标识。为了防止攻击者建立去标识前后的对应关系,去标识过程应使用基于密钥的密码计算过程,比如HMAC或确定性加密算法,并且确保密钥的安全。建议将密钥存放在参与者本地的受控环境中,避免恶意的参与者获取密钥。 (2)参与者对用户属性信息进行一定程度的模糊处理,如区间化、加噪声等。在某些机器学习训练算法中,区间化和加噪声本来就是其中一个步骤。这些操作能够大幅增加通过属性追踪用户身份的难度。 (3)所有参与者将去标识之后的ID、模糊处理后的属性信息传输到受控环境中,在受控环境中进行碰撞和融合计算。 (4)对受控环境与外部交互的各个通道进行严格管控。例如,在研发过程中,对少量需要展示的数据进行k匿名或脱敏处理;对输出的结果,进行差分隐私、泛化/有效位截断(精度过高会推出哪些数据参与了运算)等。在受控环境的技术实现上,可信计算是非常好的一个选择,它能够提供可靠的隔离环境。另外,参与方还可以从远程确认数据的处理、输出方式,进一步确保数据安全可控。 • 受控匿名化的安全性:在参与方之外,只有相对匿名化后的信息在受控环境中出现。由于受控环境采用了可信计算等高安全保障的技术,一般不会发生大规模数据泄露。即便有少量数据泄露,因为这些数据都是经过相对匿名化处理的,对安全性影响不大。 • 受控匿名化的性能:首先,受控匿名化对身份信息、属性等数据价值损失不大,最大程度地保证了数据的价值;其次,整个过程没有大计算量的操作,整体性能非常高。 2.2  可信密态计算克服现有隐私计算技术的短板 经分析发现,决定隐私计算性能的关键是它属于同网密态技术还是跨网密态技术,即计算过程中是否需要频繁的公网交互。在这一思想的引导下,提出了一种新的隐私计算技术路线:可信密态计算(Trusted-Environment-Based Cryptographic Computing,TECC)。TECC通过在多个高速互联的可信执行环境中运行密码协议,将两者有机地结合在一起,可以显著解决这两项技术的主要缺陷。综合考虑性能、安全性、可靠性和成本等因素,TECC是最有希望满足密态时代要求的隐私计算技术。 TECC的一个主要特征是可信执行环境里运行的是密态数据。为了充足的安全余量,建议搭配全栈可信(TPM+外壳防拆)技术,形成全栈可信、TEE、密态程序三层防御。这三层不是简单地累加,TECC的安全特性可以克制全栈可信、TEE的主要缺陷。另一个主要特征是多个可信执行环境运行在高速网(内网)中。TECC因此成功地突破了其他技术都有的公网传输瓶颈,再结合其他优化技术,最终的性能远超现有隐私技术并接近明文。图3是TECC典型的示例图。 图3  可信密态计算示例图(1)数据提供者在本地将数据拆分成多个密态分量,并将每个分量传递给不同分区的可信计算节点。 (2)每个可信计算节点只有部分密态(分量)数据,多个节点分区通过密码协议完成目标计算。 (3)可信计算节点受TEE、TPM、全栈可信保护,运营者无法窥探。 (4)密码协议的同一个角色由一个节点分区集群承担,可以进行并行化加速。 2.2.1  TECC的安全性优势 研究者建议TECC与全栈可信技术(包括外壳防拆技术、基于TPM的可信启动技术等)配合使用。因为攻击TEE一般需要物理接触TEE或者攻入操作系统,全栈可信的防拆和软件链验证正好可以阻止这些行为。虽然全栈可信技术会增加一定的成本,但是对于隐私计算这么关键的任务是值得的。在使用全栈可信之后,TECC具备了全栈可信、TEE、密态程序三层防御,安全性远高于单独使用TEE。这三层防御并不是简单的叠加,TECC的安全能力可以克制全栈可信、TEE的主要安全缺陷。TEE历史上的安全漏洞[18]主要是由以下几个原因产生。 (1)因为TEE很难被直接攻破,侧信道攻击是最主要的攻击形式。根据攻击的关键对象,可以分为地址类侧信道攻击[19-22]和分支判断类侧信道攻击等[23-25]。前者指通过观测TEE访问了哪些缓存行或内存页等,获得TEE访问的地址信息,进而推断敏感信息;后者指通过观测能耗曲线、执行时间等,分析出TEE内部程序在分支判断的时候走的是哪个分支,进而推断敏感信息。 (2)因性能优化导致的瑕疵。性能是所有系统追求的指标之一,但是过度的性能优化会导致安全问题,主要包括侧信道攻击和预测执行攻击(幽灵攻击、Spectre)[26-28]。预测执行是TEE(CPU)的一个特性,TEE会根据历史运行情况猜测要跳转的分支,并提前执行,达到加速的效果。针对这一特性,攻击者通过反复操纵输入,最终让TEE猜测错误,并进一步完成攻击。 (3)设计实现疏忽导致的瑕疵。保障寄存器、内存等大的组件相对容易被正确设计和实现。但是一些细小组件的安全防护可能会被疏忽,如加载端口、行填充缓冲等。攻击者有可能以采样的方式从这些细小组件中读取到TEE运行数据碎片,如微体系结构数据采样(MDS)攻击[13][15][29-32]。 (4)供应链攻击。在一些异常的供应链流程中,攻击者有可能会物理接触TEE,进而可以实施更多的攻击手段。例如,在维修的过程中,TEE一般会关闭物理防护安全措施,攻击者就有机会注入硬件木马。全栈可信也有类似的问题,供应链攻击也是全栈可信最大的安全隐患。 从上面可以看出,历史上的漏洞对TEE的破坏一般不是颠覆性的,攻击者能够获取的信息非常有限,并且有很多前提条件。在TECC中,这些限制和前提条件基本不会被满足,最终使得攻击无法奏效。 • TECC中的TEE的内部数据都是密态数据(分量),这些数据是很长的随机数,不会作为地址或者地址偏移使用,所以地址类的侧信道攻击对TECC没有威胁。同样地,这些数据也不会作为分支判断的依据。实际上,密态程序因为不知道分支判断的值,所有可能的分支都会执行一遍。所以分支判断类的侧信道攻击对TECC也没有威胁。 • 预测执行攻击成立的前提条件是,攻击者能够操纵输入影响分支判断走向。在TECC中,参与方的输入都会被转换为密态数据,只用于计算,不会作为分支判断的条件,所以这种攻击对TECC无效。 • 在微体系结构数据采样攻击中,攻击者难以控制自己获得的具体是哪一条数据。这种情况下,攻击者从TECC的各个TEE中获取的密态数据(分量)很有可能不对应同一个明文,也就形不成攻击。尤其是当攻击者从单个TEE中获取的数据量非常少的时候,对应同一个明文的概率基本可以忽略。在微体系结构数据采样(Microarchitecture Data Sampling,MDS)攻击中,攻击者只能通过非常细小的组件获取数据,所以能够获得的数据量非常少。 • 对于来自异常供应链流程的TEE,如维修,可以将它们放到TECC的同一个分区。TECC的安全机制保证,即便同一个分区的TEE都被攻破了,也不会有安全问题。从表1可以看出,TECC能够克制TEE历史上出现过的大部分安全漏洞。由此推断,对于TEE未来可能会出现的漏洞,TECC大概率也可以抵御。即便不能完全抵御,在全栈可信、TEE、密态程序三层防御下,攻击者也很难成功。 表1  TECC克制TEE、全栈可信的主要隐患: 2.2.2  TECC的性能优势 TECC的一部分性能优势来自于内网交互,例如典型的公网带宽10 Mbit/s、内网带宽10 Gbit/s,就是1 000倍的差距。TECC的性能优势还来自于其特有的并行化能力。TECC中心可以为密码协议的每个角色分配多个TEE资源,把同一个角色的所有TEE叫做一个分区。图4展示了密码协议的三个分区,每个分区有t个TEE。来自不同分区的三个TEE组成一组,承担总任务中的一个子任务。所有组可以并行计算,大大加速整体的计算效率。大规模数据处理任务通常都是可以并行化的,所以这一措施非常有效。 图4  TECC并行化加速机制: 这一并行化的原理与常见的多线程相似,但对跨网密态技术并不成立。因为这些技术的瓶颈点在公网带宽上,即使采用类似的方式分组,多个组仍然要共享同一份公网带宽,性能提升十分有限。但是对于TECC来说,每一组内部的通信带宽近乎是“免费”的。从另一个角度来说,假设内网带宽10 Gbit/s,TEE组数为100 组,则执行密码协议的总带宽就高达1 000 Gbit/s,这是前述公网带宽的10 万倍。 为了把TECC的性能优势发挥到极限,TECC还需要选择计算量小的密码协议。通过安全性分析得知,只要满足TECC中的TEE内是密态数据,就能达到非常高的安全效果。因此,可以选择门限低的密码协议,其计算量膨胀非常小。这也是使用TEE带来的好处,单独使用这些协议安全强度有限。 在消除了网络瓶颈和计算瓶颈后,TECC的性能迎来了质的飞跃,远超TEE以外的隐私计算技术,并且在少量的资源膨胀下可以接近明文。 2.2.3  TECC的功能优势 TECC中的TEE之间可以通过执行MPC协议完成目标运算,所以MPC能够支持的功能TECC都可以支持。目前,MPC协议能够支持的功能已经非常完善了。图5展示了MPC功能层次关系。 图5  TECC功能层次图: (1)基础算子层包括算术运算、逻辑运算,以及它们之间的相互转化。常见的多方安全计算协议一般指的是这一层,如aby、spdz[32]、SWIFT[33]。 (2)对于一些高级算子,人们会去研究特定的高效实现算法[34],包括数学类函数和数据结构算法等。 (3)构建隐私应用一般不再需要特殊的协议或算法,与明文过程基本相同。隐私应用主要分为机器学习和数据分析两类。 相对于跨网密态计算技术,TECC的功能优势在于天然地支持任意多个参与方和任意的数据分割形式,数据分割形式指的是一个参与方拥有全部数据的哪一部分。在TECC中,多个参与方先将各自的数据密态拆分,上传合并后再计算。因此,参与方数量、数据分割形式对上述过程没有影响。但是对于跨网MPC来说,出于对性能、实现复杂度等方面的考虑,不同的参与方数量、不同的数据分割形式通常对应不同的算法,比如两方协议和多方协议、横向联邦和纵向联邦。这就导致TECC一个算法能够实现的功能,跨网MPC要使用多个算法。 2.2.4  TECC的稳定性和成本优势 跨网密态技术对公网严重依赖,例如一次两方密态机器学习训练需要的交互次数高达数万次。这给稳定性保障带来了极大的挑战。这一点与常规的网络应用很不同,后者一般只需要几次公网交互。TECC只有数据上传的时候需要公网交互,没有这方面的忧虑。同时,这也为TECC节省了大量的公网购买成本。TECC的计算节点采用集中部署的形式,参与方只需要使用轻量级SDK就可以接入,大大降低了接入成本。集中化的部署方式更有利于日常的功能巡检、应急演练和故障处理。 3  可信隐私计算行业生态 除了突破技术瓶颈,数据密态时代的发展还需要:一方面由法律法规确立用户的权益,数据行业基础的、合理的安全需求将成为强制要求;另一方面,标准和评测将为产业甄别不同产品的安全程度,并指导行业在不同的场景使用合适的技术。 3.1  密态时代合规的关键问题 合规是行业的基本保障。密态时代要做到合规,最关键的几点如下。 (1)专数专用,即数据不能随意跨主体、跨业务场景使用。首先,理清楚首次收集数据的主体、获得充分授权后数据的归属主体、各方的权利和责任;其次,需要根据业务场景2B和2C的授权情况来限定数据的合规使用范围。 (2)个人信息授权问题。《个人信息保护法》规定的27个同意形成了一道坚固的授权墙,任何业务场景必须按规定获得用户的授权。但是在某些情况下这一要求很难达到,例如恶意攻击者一定不会授权风控系统获取他的数据,但这一数据对模型训练很重要。目前,在法律许可下主要有两个解决路径,一是匿名化,二是执行合同的必须条件。在无授权场景下,要做好匿名化,在保证个人隐私权益的前提下发挥数据价值;在有授权场景下,要专数专用,保障这个场景获得的数据只在这个场景中使用。 (3)数据的使用和流通要做到可审计、可举证。隐私计算等技术在保护数据明文信息的同时也可能阻碍对数据实际使用范围的审计监控。在实际使用中,如果没有妥善的管控,同样可能导致侵犯用户隐私权益或者造成敏感信息泄露。因此,审计和固证是非常重要的作用。 3.2  标准、评测保证行业健康发展 隐私计算技术底层技术路线非常多,实际产品迫于性能压力可能还会舍弃部分安全性,一些新兴的思路可能会将多种技术相融合。这些因素导致在用的隐私计算技术路线非常多,安全性差异非常大,且社会对此认知比较模糊。为了产业的健康发展,对安全性给出准确评估至关重要。同时,必须承认客观上无法对产品的安全性给出形式化的证明。一个实际系统的安全必然涉及到密码学、代码安全、网络安全、AI算法安全等多个层面,其中大部分都无法得到形式化证明。甚至,密码学的部分内容也无法得到形式化证明。 在这种情况下,评测应回归到安全的基本原则。首先,安全的核心是对抗,对抗是多维度、持续的,承载着行业数据命脉的关键基础性技术,必须清晰地分析面对各种已知和潜在攻击的安全强度,这需要行业安全专家的广泛介入;其次,一定需要根据场景安全分类分级,不能用一个指标锁死各行各业不同业务的安全水位要求。 4  结束语 通过对密态时代所需的两项基本技术——匿名化和隐私计算进行分析,发现它们都存在一些难以克服的短板,密态时代陷入了“技术困局”。为此,本文提出了可信隐私计算技术,它融合了可信计算、密码等多项技术,在安全性、性能、可靠性、适用性和成本等方面均达到了非常高的水平,几乎是当前唯一能够全方位满足密态时代要求的技术。除了技术突破外,本文强调了合规、标准、评测等是保证行业健康发展的关键。有理由相信,可信隐私计算以其显著的综合性优势,必将能够帮助数据要素行业破解技术困局,迈入密态时代。 来源: 信息通信技术与政策
  • [其他] 浅学人工智能基础测验
    人工智能的发展史人工智能“研究,开发用于模拟延伸和扩展人的智能的理论方法及应用系统的一门新的综合性技术科学”人工智能由1956年(人工智能元年)约翰·麦卡锡提出定义“制造智能机器的科学与工程”,意义,在于重新定义生产力,重新定义人的价值机器学习“专门研究计算机怎么样,模拟或实现人类学习行为以获取新的知识或技能,重新组织已有的知识结构使之不断改善自己的技能”机器学习更多是处理结构话的数据并且有较好的数学理论支撑,主要包括决策树,随机森林,人工神经网络,贝叶斯学习,是人工智能的核心研究领域之一深度学习源于人工神经网络的研究,多层感知器就是一种深度学习结构,深度学习是机器学习研究中的一个新的领域它模仿人脑的机制来解释理解数据,图像,声音,文本等人工智能的三要素:数据,算法,算力测验(单选)人工智能的标准定义是由谁提出的?约翰·麦卡锡  √正确丹尼斯·里奇唐纳德·克努特爱德华·泰勒(单选)人工智能元年是?1955年1956年  √正确1957年1958年(单选)比较依赖调参人员的经验,被称为“炼丹术”的算法是?深度学习 √机器学习联邦学习不正确强化学习(单选)人工智能的三要素不包括?数据算法算力AI工程师  √正确(单选)人工智能的三大学派不包括?符号主义连接主义行为主义规则主义  √正确(单选)未来人工智能技术的突破方向可能是?非监督学习,知识推理  √正确监督学习,知识推理深度学习,非监督学习强化学习,监督学习(单选)人工智能中用什么技术可以解决数据隐私保护问题?联邦学习  √正确监督学习深度学习隐私学习(单选)当前世界在AI领域的研究主要集中在?计算机视觉  √正确语音自然语言理解数据挖掘(单选)自然语言处理研究的主题不包括?机器翻译情感分析语音合成  √正确文本挖掘(单选)阿西莫夫对人工智能和人的伦理关系最早的定义是?人工智能三定律人工智能与机器人三定律机器人三定律  √正确人工智能伦理论
  • [赛事资讯] 2022“域见杯”医检人工智能开发者大赛训练营火热来袭!
    【域见AI,医探到底】7月5日19:00~20:00,2022“域见杯”医检人工智能开发者大赛训练营火热来袭。想了解最新的赛事进展吗?想学习更多的赛题解读吗?想和其他选手一起在线battle吗?7月5日晚7点直播间不见不散!直播过程中还将抽取华为音响、移动充电宝、《ModelArts人工智能应用开发指南》等精美礼品哦,直通offer等你来拿。戳>>直播训练营<<或扫描以下海报二维码即可进入直播间观看直播与回放。
  • [技术干货] 数据目录——企业数据资产的一个有序清单
    简而言之,数据目录就是关于企业数据资产的一个有序清单。它可以使用元数据来帮助企业管理数据,帮助数据专业人员收集、组织、访问和充实元数据,从而为数据发现和治理提供支持。—  01  — 数据目录的定义和类比在上文我们简单介绍数据目录的定义,也就是使用元数据来帮助企业管理数据。接下来,我们使用图书馆作类比,带您详细了解数据目录。当您前往图书馆查找某一图书时,您可以使用图书目录来查找该图书是否存在,了解它的版本、位置以及相关描述。您可以使用所有这些信息来决定是否真的需要这本书,了解如何找到它。当今的许多对象存储、数据库和数据仓库就相当于一座座图书馆。我们再回到图书馆和图书目录。现在,我们对图书目录进行扩展,涵盖整个国家的所有图书馆。想象一下,这样您就可以在一个界面中查找整个国家中储藏了您所需图书的所有图书馆,查找关于您所需的每一本图书的所有详细信息。企业数据目录之于数据,正如图书目录之于图书。它可以为您提供一个整体视图,提供关于您所有数据的深度可见性,而不仅仅是一次只查看某一项数据。您为什么需要这样一个视图呢?—  02  — 数据目录可以解决哪些问题?与过去相比,想从如今前所未有的数据海洋中找到正确的数据更加困难。同时,关于数据的监管条例和法规(例如 GDPR)也比过去更多、更严格。在这一背景下,除了数据访问之外,数据治理也成为了一个严峻的挑战。您不仅要了解当前您所拥有数据的类型、哪些人在移动数据、数据的用途以及如何保护数据,还必须避免过多的数据层和封装,避免数据因太难使用而毫无用处。遗憾的是,很多企业和用户在查找和访问数据上面临着很多问题,包括: 需耗费大量时间和精力查找和访问数据数据湖变成了数据沼泽无通用业务词汇难以理解“黑暗数据”的结构和类别难以评估数据来源、质量和可靠性无法捕获部落知识或丢失的知识难以重用知识和数据资产需手动和临时进行数据准备 —  03  — 哪些用户应使用数据目录?数据工程师、数据科学家、数据管理员和首席数据官等用户无不受到以上数据管理问题的困扰,无不希望能够轻松访问可靠的数据。他们面临的一些常见的挑战包括: 数据工程师想知道任意更改将对整个系统产生哪些影响,他们可能会问:我们 CRM 应用中的模式变更将产生哪些影响?Peoplesoft 和 HCM 数据结构有何不同? 数据科学家希望能够轻松访问数据并进一步了解数据质量,他们想了解以下信息:从何处可以找到和查看一些地理位置数据?如何轻松访问数据湖中的数据? 数据管理员负责管理数据流程,关注概念、利益相关者间协议以及数据生命周期管理。他们希望了解:我们是否真的在改善运营数据质量?我们是否为重要的关键数据元素定义了标准?首席数据官关心哪些人在组织中做了哪些事,一般不使用数据目录。但是,他们仍然希望了解:哪些人可以访问客户的个人信息?我们是否为所有数据定义了保留策略?有了数据目录,这些问题就能迎刃而解。 —  04  — 数据目录使用场景 在过去几年中,随着需要管理和访问的数据的数量日益增长,数据目录这一概念开始流行起来。在这一切的背后,是云、大数据分析、人工智能和机器学习正逐渐改变人们查看、管理和使用数据的方式 — 不仅要管理数据,还要访问和充分利用数据。使用数据目录,您可以更好地使用数据,获得以下优势:节省成本提高运营效率增强竞争优势改善客户体验减少欺诈,降低风险等等这些只是数据目录的一部分使用场景。实际上,数据目录的使用方式多种多样。从根本上说,它的宗旨就是提供更广泛的数据可见性和更深入的数据访问支持。 1.自助分析 许多用户难以找到正确的数据,同时,除了查找数据外,他们还难以判断数据是否有用。例如,您可能会发现一个名为 customer_info.csv 的文件,而又恰好需要一个关于客户的文件。但这并不意味着它就是您需要的,它可能只是 50 个类似文件中的一个。同时,该文件可能包含许多字段,您可能并不了解所有这些数据元素代表什么。对此,您需要通过一种更简单的方法来查看数据的业务上下文,例如它是否是来自正确的数据存储的托管资源以及它与其他数据工件之间的关系。 数据发现还包括通过各种方式来理解数据的形态和特征,例如简单的值分布和统计信息,或者重要且复杂的个人身份信息 (PII) 或个人健康信息 (PHI)。2.审计、合规和变更管理随着关于数据的政府监管法规数量不断增长,企业经常需要证明数据的来源,例如特定数据工件的来源,或在实现最终目标之前进行了哪些数据转换;在查看表格、报告或文件时,数据用户通常也希望理解数据的具体来源以及数据通过各种方式在整个组织中的移动过程。同时,对于变更管理来说,一项重要任务就是查看数据管道中某部分的变更将如何影响系统的其他部分。这就是为什么客户希望详细了解数据沿袭的原因。 3.使用业务术语表增强数据治理 如今大多数企业都建立了一个所有人都认可的术语表,就业务概念达成了一致。通常,业务术语表记录在 Excel 工作簿中。其实,数据目录比 Excel 工作簿更适合存储和管理这一重要业务信息。 此外,数据目录还支持在业务术语之间建立链接,从而创建分类;可以记录业务术语与实物资产(例如表和列)之间的关系;可以帮助用户理解哪些业务概念与哪些技术工件相关;可以帮助用户按业务概念线对数据资产分类,随后直接使用业务概念(而不是技术名称)来进行数据搜索和发现。数据目录让用户可以看到与数据相关的所有内容,增强对所查看内容的信任度,为数据治理奠定一个绝佳的起点。 —  05  — 如何充分利用数据目录中的数据?许多人可能不熟悉元数据,我们有必要先介绍一些简单的概念。元数据是什么?元数据分为 3 类:技术元数据:模式、表、列、文件名、报告名 — 源系统中记录的所有信息业务元数据:通常指用户具备的关于组织资产的业务知识,包括业务描述、备注、注释、分类、适用性、评级等等。操作元数据:这一对象的刷新时间?它由哪一个 ETL 作业创建?表格被访问次数有多少?具体有哪些?在过去几年里,这些宝贵的元数据的使用方式发生了一次细微的变革。曾经,元数据仅用于审计、来历追溯和报告。如今,无服务器处理、图形数据库等技术创新,尤其是全新、更加便捷的 AI 和机器学习技术正在突破元数据的界限,带来新的可能。在今天,元数据可增强数据管理。从自助数据准备到角色和数据内容库访问控制,自动化数据打通,异常监视和警报,自动化资源供应和扩展等等,元数据可以全面增强所有这些功能。数据目录可以使用元数据帮助您实现比数据管理更强大的功能。—  06  — 数据目录应当具备哪些功能? 一个优秀的数据目录应当具备以下功能:①数据搜索和发现:数据目录应当具备灵活的搜索和过滤选项,从而赋能用户快速找到相关数据集,以实施数据科学、分析或数据工程;按照数据资产的技术层级来浏览元数据。此外,如支持用户输入技术信息、自定义标签或业务术语,数据目录可以进一步改善搜索功能。②从各种数据源收集元数据:请确保您的数据目录可以从各种互联数据资产中收集技术元数据,包括对象存储、自治驾驶数据库、本地部署系统等等。③元数据管理:数据目录应支持主题专家通过企业业务术语表、标签、关联、用户自定义注释、分类、评级等形式来贡献业务知识。④自动化和数据智能:对于大规模数据,人工智能和机器学习通常必不可少。因此,数据目录应利用 AI 和机器学习技术来处理所收集的元数据,让所有可以自动化的手动任务都实现自动化。此外,人工智能和机器学习还可以切实增强数据功能,例如为数据目录用户以及现代化数据平台上其他服务的用户提供数据建议。⑤企业级功能:您需要利用强大的企业级功能来正确使用您至关重要的数据资产,例如身份与访问管理功能以及基于 REST API 的重要功能。同时,这还意味着客户和合作伙伴可以贡献元数据(例如自定义收集器),通过 REST 公开其应用中的数据目录功能。除此之外,您的数据目录还应当成为事实上的系统目录,从而为所有持久层(例如对象存储、Hadoop、数据库和数据仓库)以及跨所有数据存储运行的查询服务提供抽象。正是因为如此,数据目录已不再仅仅是锦上添花,而是成为了一项必不可少的工具。来源:https://www.oracle.com/cn/big-data/data-catalog/what-is-a-data-catalog/
  • [其他] 浅谈k近邻算法
    K最近邻(k-Nearest Neighbor,KNN)分类算法,是一个理论上比较成熟的方法,也是最简单的机器学习算法之一。该方法的思路是:在特征空间中,如果一个样本附近的k个最近(即特征空间中最邻近)样本的大多数属于某一个类别,则该样本也属于这个类别。K近邻算法,即是给定一个训练数据集,对新的输入实例,在训练数据集中找到与该实例最邻近的K个实例(也就是上面所说的K个邻居), 这K个实例的多数属于某个类,就把该输入实例分类到这个类中。KNN 的模型表示就是整个训练数据集。对新数据点的预测结果是通过在整个训练集上搜索与该数据点最相似的 K 个实例(近邻)并且总结这 K 个实例的输出变量而得出的。对于回归问题来说,预测结果可能就是输出变量的均值;而对于分类问题来说,预测结果可能是众数(或最常见的)的类的值。关键之处在于如何判定数据实例之间的相似程度。如果你的数据特征尺度相同(例如,都以英寸为单位),那么最简单的度量技术就是使用欧几里得距离,你可以根据输入变量之间的差异直接计算出该值。KNN 算法本身简单有效,它是一种 lazy-learning 算法,分类器不需要使用训练集进行训练,训练时间复杂度为0。KNN 分类的计算复杂度和训练集中的文档数目成正比,也就是说,如果训练集中文档总数为 n,那么 KNN 的分类时间复杂度为O(n)。KNN方法虽然从原理上也依赖于极限定理,但在类别决策时,只与极少量的相邻样本有关。由于KNN方法主要靠周围有限的邻近的样本,而不是靠判别类域的方法来确定所属类别的,因此对于类域的交叉或重叠较多的待分样本集来说,KNN方法较其他方法更为适合。K 近邻算法使用的模型实际上对应于对特征空间的划分。K 值的选择,距离度量和分类决策规则是该算法的三个基本要素:    K 值的选择会对算法的结果产生重大影响。K值较小意味着只有与输入实例较近的训练实例才会对预测结果起作用,但容易发生过拟合;如果 K 值较大,优点是可以减少学习的估计误差,但缺点是学习的近似误差增大,这时与输入实例较远的训练实例也会对预测起作用,使预测发生错误。在实际应用中,K 值一般选择一个较小的数值,通常采用交叉验证的方法来选择最优的 K 值。随着训练实例数目趋向于无穷和 K=1 时,误差率不会超过贝叶斯误差率的2倍,如果K也趋向于无穷,则误差率趋向于贝叶斯误差率。    该算法中的分类决策规则往往是多数表决,即由输入实例的 K 个最临近的训练实例中的多数类决定输入实例的类别    距离度量一般采用 Lp 距离,当p=2时,即为欧氏距离,在度量之前,应该将每个属性的值规范化,这样有助于防止具有较大初始值域的属性比具有较小初始值域的属性的权重过大。
  • [DevKit] DevKit训练营---sudoku源码编译和调试作业
    DevKit训练营---sudoku源码编译和调试作业一、题目通过编译调试工具对一款数独棋盘游戏的源码进行编译调试。二、操作前提在鲲鹏社区申请远程实验室,操作系统选择OpenEuler。https://www.hikunpeng.com/zh/developer/devkit 三、准备工作1、服务器和操作系统正常运行。2、VSCode已经安装编译调试插件。(在本地PC机安装,过程很简单,此处省略)VS code 下载地址:https://code.visualstudio.com/ 3、远端服务器已经安装Cmake 3.12及以上版本(低版本无法正常编译)。(1)使用cmake –version 查询cmake版本。说明:申请的实验室默认的环境openeuler系统,没有安装Cmake,需要手动安装说明:如果cmake版本低于3.12,则需要更新camke版本,具体教程可参考。https://blog.csdn.net/ghpanxt/article/details/1193821954、从https://github.com/mayerui/sudoku.git下载获取待使用的项目源文件并打开。(1)使用clone或download zip。此处直接用 git clone命令下载sudoku,下载后的文件在root目录下,可以通过ls命令查询5、从https://github.com/mayerui/sudoku获取编译及测试用例的命令。 Tips: 测试用例cwd字段需要绝对路径:配置服务器时的workspace + 项目名称 + 测试用例路径。打开上面的网页,然后手动下载sudoku-master文件解压sudoku-master文件,然后通过VScode打开这个文件夹然后再VS code配置实验室的服务器在添加服务器的时候,带*号的选项必须要填,需要注意的是公钥和私钥,可以通过本机PC的cmd命令行,执行ssh-keygen -t rsa 会自动在C:\Users\用户名\.ssh生成rsa和rsa.pub其中,rsa是私钥,rsa.pub是公钥填写完毕后,点 配置,如果都正确的话,会提示:然后可以创建编译任务,再进行编译,第一次操作,我们需要同步并编译此处需要输入yes,继续执行编译以上编译就执行完毕了。然后再到linux系统里面复现一下由于之前在VS code指定的编译工程的路径是/root/workspace所以我们在OS里面看看是否有编译后的bin文件夹,如图:然后在bin文件夹下执行 ./sudoku效果如图:最后,我们在VS code执行编译测试用例演示任务名称可以自定义可执行程序就是./sudoku 命令程序路径就是sudoku执行文件的的绝对路径然后获取测试用例,并在远端执行最后我们可以对代码进行调试在调试界面点击run,然后看回显是否达到预期效果运行完毕,结束!
  • [技术干货] 人工智能如何用于静态生物特征验证[转载]
    静态生物特征验证是一种常用的 AI 功能,它可以实时捕捉人脸,并可以在不提示用户移动头部或面部的情况下确定人脸是否属于真人。通过这种方式,该服务有助于提供获得积极反馈的便捷用户体验。技术原理静态生物特征验证需要 RGB 摄像头,并且能够通过细节(例如莫尔图案或纸上的反射)区分真人的面部和欺骗攻击(例如面部和面罩的图像或屏幕截图)照片)在相机拍摄的图像中。该服务支持来自各种场景的数据,包括不同的照明条件、面部配饰、性别、发型和面具材料。该服务分析面部周围环境以检测可疑环境。静态生物特征验证模型采用轻量级卷积模块,在推理阶段通过重新参数化将线性计算转化为单个卷积模块或全连接层。MindSpore Lite 推理框架可用于模型部署,从而裁剪操作员。然后缩小模型的封装尺寸,使其更便于集成。应用场景活体检测通常在人脸验证之前使用。例如,当用户使用面部识别解锁手机时,活体检测首先确定捕获的面部是否真实。如果是,则人脸验证将检查人脸是否与系统中记录的人脸匹配。这两种技术相互补充,以保护用户的设备免受未经授权的访问。所以可以肯定地说,静态生物特征验证为应用程序提供了严格的保护,我在这里说明如何集成它。整合程序准备工作调用服务有两种模式:通话模式    活体检测过程    活体检测界面    功能默认查看模式    由 ML Kit 处理    提供的    确定一张脸是否真实。自定义查看模式    由 ML Kit 处理    自定义    确定一张脸是否真实。默认查看模式1.创建回调获​​取静态生物特征验证结果。private MLLivenessCapture.Callback callback = new MLLivenessCapture.Callback() {    @Override    public void onSuccess(MLLivenessCaptureResult result) {        // 验证成功时回调,结果表明面部是否为真人。    }    @Override    public void onFailure(int errorCode) {        // 验证失败时回调。例如,摄像头异常(CAMERA_ERROR)。 添加处理逻辑来处理失败。    }};2.创建静态生物特征验证实例并开始验证。MLLivenessCapture capture = MLLivenessCapture. getInstance();capture.startDetect(activity, callback);12自定义查看模式1.创建一个 MLLivenessDetectView 实例并将其加载到活动布局中。/*** 1. 将摄像头预览画面绑定到远程视图,设置活体检测区域。* 在相机预览流中,静态生物特征验证确定人脸是否在图像中间。 为提高通过率,建议将人脸框置于屏幕中间,并将活体检测区域设置为略大于人脸框。* 2. 设置是否检测掩码。* 3. 设置结果回调。* 4. 将 MLLivenessDetectView 加载到活动中。*/@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_liveness_custom_detection);    mPreviewContainer = findViewById(R.id.surface_layout);    // ObtainLLivenessDetectViewmlLivenessDetectView = new MLLivenessDetectView.Builder()        .setContext(this)        // 设置是否检测掩码。        .setOptions(MLLiveness DetectView.DETECT_MASK)        // 设置人脸框相对于 MLLivenessDetectView 的矩形。        .setFaceRect(new Rect(0, 0, 0, 200))        // 设置结果回调。        .setDetectCallback(new OnMLLivenessDetectCallback() {            @Override            public void onCompleted(MLLivenessCaptureResult result) {                // 验证完成时回调。            }            @Override            public void onError(int error) {                // 验证过程中发生错误时的回调。            }            @Override            public void onInfo(int infoCode, Bundle bundle) {                // 收到验证提示消息时回调。 此消息可以显示在 UI 上。                // if(infoCode==MLLivenessDetectInfo.NO_FACE_WAS_DETECTED){                     // No face is detected.                // }                // ...            }            @Override            public void onStateChange(int state, Bundle bundle) {                // 验证状态变化时回调。                // if(state==MLLivenessDetectStates.START_DETECT_FACE){                     // Start face detection.                // }                // ...            }        }).build();    mPreviewContainer.addView(mlInteractiveLivenessDetectView);    mlInteractiveLivenessDetectView.onCreate(savedInstanceState);}2.为MLLivenessDetectView设置生命周期监听器。@Overrideprotected void onDestroy() {    super.onDestroy();    mlLivenessDetectView.onDestroy();}@Overrideprotected void onPause() {    super.onPause();    mlLivenessDetectView.onPause();}@Overrideprotected void onResume() {    super.onResume();    mlLivenessDetectView.onResume();}@Overrideprotected void onStart() {    super.onStart();    mlLivenessDetectView.onStart();}@Overrideprotected void onStop() {    super.onStop();    mlLivenessDetectView.onStop();}参与评论送书本次送书 3 本,以后每周新文评论区至少抽三位朋友送书,大家可持续关注我:海拥内容简介人工智能被广泛应用和普及,极大地提高了人们学习和工作的效率。而要深入理解人工智能,必须全面理解底层各类机器学习算法的基本原理。只有全面掌握机器学习的基础知识,才能更好地理解、提高和驾驭人工智能的各种应用。本书内容系统、全面,理论知识覆盖面广,且保留了推导过程。实践案例中,深入浅出地讲解和展示了机器学习应用的具体流程。本书适合在各行业工作的数据科学家、在校学习人工智能和数据科学专业的学生、科技公司的管理者和决策者,以及人工智能的初学者和爱好者阅读。觉得自己抽不到,想自己买的也可以参考此链接:https://item.jd.com/13156145.html尾注:人工智能是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门新的技术科学。在这里,我们只讨论了人工智能的基本知识,想要获取更多人工智能相关的知识,或者就是想每周参与抽奖白嫖一本书,你可以私信我加入 CSDN官方人工智能交流群————————————————版权声明:本文为CSDN博主「海拥✘」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/qq_44273429/article/details/125409169
  • [其他] 浅谈决策树学习
    统计学,数据挖掘和机器学习中的决策树训练,使用决策树作为预测模型来预测样本的类标。这种决策树也称作分类树或回归树。在这些树的结构里,叶子节点给出类标而内部节点代表某个属性。在决策分析中,一棵决策树可以明确地表达决策的过程。在数据挖掘中,一棵决策树表达的是数据而不是决策。决策树的类型在数据挖掘中,决策树主要有两种类型:    分类树的输出是样本的类标。    回归树的输出是一个实数 (例如房子的价格,病人待在医院的时间等)。术语分类和回归树 (CART) 包含了上述两种决策树, 最先由Breiman 等提出。分类树和回归树有些共同点和不同点—例如处理在何处分裂的问题。有些集成的方法产生多棵树:    装袋算法(Bagging), 是一个早期的集成方法,用有放回抽样法来训练多棵决策树,最终结果用投票法产生。    随机森林(Random Forest) 使用多棵决策树来改进分类性能。    提升树(Boosting Tree) 可以用来做回归分析和分类决策。    旋转森林(Rotation forest) – 每棵树的训练首先使用主元分析法 (PCA)。还有其他很多决策树算法,常见的有:    ID3算法    C4.5算法    CHi-squared Automatic Interaction Detector (CHAID), 在生成树的过程中用多层分裂 。    MARS可以更好的处理数值型数据。决策树的优点与其他的数据挖掘算法相比,决策树有许多优点:    易于理解和解释 人们很容易理解决策树的意义。    只需很少的数据准备 其他技术往往需要数据归一化。    即可以处理数值型数据也可以处理类别型 数据。其他技术往往只能处理一种数据类型。例如关联规则只能处理类别型的而神经网络只能处理数值型的数据。    使用白箱 模型. 输出结果容易通过模型的结构来解释。而神经网络是黑箱模型,很难解释输出的结果。    可以通过测试集来验证模型的性能 。可以考虑模型的稳定性。    强健控制. 对噪声处理有好的强健性。    可以很好的处理大规模数据 。缺点    训练一棵最优的决策树是一个完全NP问题。因此, 实际应用时决策树的训练采用启发式搜索算法例如 贪心算法 来达到局部最优。这样的算法没办法得到最优的决策树。    决策树创建的过度复杂会导致无法很好的预测训练集之外的数据。这称作过拟合。 剪枝机制可以避免这种问题。    有些问题决策树没办法很好的解决,例如 异或问题。解决这种问题的时候,决策树会变得过大。 要解决这种问题,只能改变问题的领域或者使用其他更为耗时的学习算法 (例如统计关系学习 或者 归纳逻辑编程).    对那些有类别型属性的数据, 信息增益 会有一定的偏置。参考资料Induction of decisiontrees" Machine Learning An Exploratory Technque for Investigating Large Quantities of Categorical Data  Bias of ImportanceMeasures for Multi-valued Attributes and Solutions  A Survey of Evolutinary Algorithms for Decision-Tree Induction  
  • [其他] 联结主义人工智能的基本观点
    联结主义人工智能的基本观点是:人工智能必须能够模仿大脑的功能,更具体地强调机器应具有学习能力和认知能力,通过学习来解决问题。 联结主义人工能特指感知机、神经网络发展的机器学习,广泛意义上也可以包括强化学习以及其他机器学习方法。联结主义人工智能主要解决模式识别、聚类、分类、联想等非结构化同题。早在20世纪40年代,McCulloch和Walter开创了集成认知神经学、科学和数理逻辑计算的计算神经学,提出了最早的神经网络模型,给出了神经元的形式化数学描述和网络结构、证明了单个神经元能执行逻辑功能。 1958年,Frank将感知器建立在一个非线性神经元上,得到了神经元的Pitts模型。这是在计算机有限运算能力的条件下,基于硬件结构建立的第一个可进行模式识别的单层神经网络模型。但在此后的一段时间内,神经网络模型仍然无法测试,而且连比较基本的异或(XOR)的逻辑运算都不能实现,即便多层神经网络也不具有低复杂度,相关研究进人了长达20年的停滞状态。 1974年,哈佛大学的Paul首次提出误差反向传播算法,不仅解决了异或运算问题,而且大大提升了神经网络迭代计算效率。直到20世纪80年代,神经网络才再度迎来研究高潮。1982年,John提出了可用作联想存储器的互连网络模型,该模型是一种从输出到输人有反愦连接的循环神经网络。1986年,David等人在神经网络上应用了反向传播算法。1989年,Yann等人受日本学者福岛邦彦提出的仿生视觉皮层神经网络模型等的启发,构建了应用于计算机视觉问题的包含2个卷积层和2个全连接层的神经网络,正式提出了卷积神经网络,并于1998年构建更完备的卷积神经网络LeNet-5,成功用于解决手写识别问题。 2006年,Hinton等人发表文章,提出将预训练、自编码器与深度神经网络结合,开启了深度学习(深度神经网络)在学术界和工业界的研究与应用浪潮,相继在语音识别、图像识别等领域开展应用,显著降低了错误识别率。2011年后,深度学习开始将卷积层与最大池化层合并,并将其输出传递给几个全连接层,再传递给输出层。2013年4月,美国麻省理了学院(MIT)的《麻省理工科技评论》将深度学习列为2013年十大突破性技术之一。2014年,当时还在蒙特利尔大学读博上的Ian等人提出生成对抗网络溉念,使得神经网络系统不仅能够更好地生成图像与声音,还能识别它们,从而奠定了无监督自主学习算法框架的基础。2015年,谷歌DeepMind提出正式的Deep Q Networks系统。2016年,融合了深度学习、强化学习和蒙特卡罗树搜索方法的AlphaGo战胜了世界围棋高手李世石。这些研究让联结主义大放异彩,也是当前人工智能高潮形成的主因。 其他机器学习方向也在不断取得成果。早在1952年,IBM科学家Arthur开发了一个跳棋程序。该程序能够通过观察当前位置,并学习一个隐含的模型,为后续动作提供更好的指导。从1984年开始,Leo Breiman等人相继提出了适用于分类和连续输人(特征)/输出(预测)变量回归预测建模问题的决策树算法和多决策树组合的随机森林算法,后者属于集成学习范畴。1995年,由Corinna等人提出了支持向量机的溉念,通过Kernel的技巧将低维空间线性不可分或难分的样本数据点映射至高维空间使其线性可分,在解决小样本、非线性以及高维模式识别问题方面具有明显优势。
  • [干货汇总] 机器学习实践:基于支持向量机算法对鸢尾花进行分类
    【摘要】 @[toc] 一.前言 1.1 本文原理支持向量机(SVM)是一种二元分类模型。它的基本模型是在特征空间中定义最大区间的线性分类器,这使它不同于感知器;支持向量机还包括核技术,这使得它本质上是一个非线性分类器。支持向量机的学习策略是区间最大化,它可以形式化为求解凸二次规划的问题,等价于正则化铰链损失函数的最小化。支持向量机的学习算法是求解凸二次规划的优化算法。Scikit learn(skl...本文分享自华为云社区《支持向量机算法之鸢尾花特征分类【机器学习】》,作者:上进小菜猪。一.前言1.1 本文原理支持向量机(SVM)是一种二元分类模型。它的基本模型是在特征空间中定义最大区间的线性分类器,这使它不同于感知器;支持向量机还包括核技术,这使得它本质上是一个非线性分类器。支持向量机的学习策略是区间最大化,它可以形式化为求解凸二次规划的问题,等价于正则化铰链损失函数的最小化。支持向量机的学习算法是求解凸二次规划的优化算法。Scikit learn(sklearn)是机器学习中常见的第三方模块。它封装了常见的机器学习方法,包括回归、降维、分类、聚类等。1.2 本文目的List item使用scikit-learn机器学习包的支持向量机算法,使用全部特征对鸢尾花进行分类;使用scikit-learn机器学习包的支持向量机算法,设置SVM对象的参数,包括kernel、gamma和C,分别选择一个特征、两个特征、三个特征,写代码对鸢尾花进行分类;使用scikit-learn机器学习包的支持向量机算法,选择特征0和特征2对鸢尾花分类并画图,gamma参数分别设置为1、10、100,运行程序并截图,观察gamma参数对训练分数(score)的影响,请说明如果错误调整gamma参数会产生什么问题?二.实验过程2.1 支持向量机算法SVM实例的特征向量(以2D为例)映射到空间中的一些点,如下图中的实心点和空心点,它们属于两个不同的类别。支持向量机的目的是画一条线来“最好”区分这两类点,这样,如果将来有新的点,这条线也可以很好地进行分类。2.2List item使用scikit-learn机器学习包的支持向量机算法,使用全部特征对鸢尾花进行分类;首先引入向量机算法svm模块:from sklearn import svm还是老样子,使用load_iris模块,里面有150组鸢尾花特征数据,我们可以拿来进行学习特征分类。如下代码:from sklearn.datasets import load_iris iris = load_iris() X = iris.data print(X.shape, X) y = iris.target print(y.shape, y)下面使用sklearn.svm.SVC()函数。C-支持向量分类器如下:svm=svm.SVC(kernel='rbf',C=1,gamma='auto')使用全部特征对鸢尾花进行分类svm.fit(X[:,:4],y)输出训练得分:print("training score:",svm.score(X[:,:4],y)) print("predict: ",svm.predict([[7,5,2,0.5],[7.5,4,7,2]]))使用全部特征对鸢尾花进行分类训练得分如下:2.3 使用scikit-learn机器学习包的支持向量机算法,设置SVM对象的参数,包括kernel、gamma和C,分别选择一个特征、两个特征、三个特征,写代码对鸢尾花进行分类;2.3.1 使用一个特征对鸢尾花进行分类上面提过的基础就不再写了。如下代码:使用一个特征对鸢尾花进行分类,如下代码:svm=svm.SVC() svm.fit(X,y)输出训练得分:print("training score:",svm.score(X,y)) print("predict: ",svm.predict([[7,5,2,0.5],[7.5,4,7,2]]))使用一个特征对鸢尾花进行分类训练得分如下:2.3.2 使用两个特征对鸢尾花进行分类使用两个特征对鸢尾花进行分类,如下代码:svm=svm.SVC() svm.fit(X[:,:1],y)输出训练得分:print("training score:",svm.score(X[:,:1],y)) print("predict: ",svm.predict([[7],[7.5]]))使用两个特征对鸢尾花进行分类训练得分如下:2.3.3 使用三个特征对鸢尾花进行分类使用三个特征对鸢尾花进行分类,如下代码:svm=svm.SVC(kernel='rbf',C=1,gamma='auto') svm.fit(X[:,1:3],y)输出训练得分:print("training score:",svm.score(X[:,1:3],y)) print("predict: ",svm.predict([[7,5],[7.5,4]]))使用三个特征对鸢尾花进行分类训练得分如下:2.3.4 可视化三个特征分类结果使用plt.subplot()函数用于直接指定划分方式和位置进行绘图。x_min,x_max=X[:,1].min()-1,X[:,1].max()+1 v_min,v_max=X[:,2].min()-1,X[:,2].max()+1 h=(x_max/x_min)/100 xx,vy =np.meshgrid(np.arange(x_min,x_max,h),np.arange(v_min,v_max,h)) plt.subplot(1,1,1) Z=svm.predict(np.c_[xx.ravel(),vy.ravel()]) Z=Z.reshape(xx.shape)绘图,输出可视化。如下代码plt.contourf(xx,vy,Z,cmap=plt.cm.Paired,alpha=0.8) plt.scatter(X[:, 1], X[:, 2], c=y, cmap=plt.cm.Paired) plt.xlabel('Sepal width') plt.vlabel('Petal length') plt.xlim(xx.min(), xx.max()) plt.title('SVC with linear kernel') plt.show()可视化三个特征分类结果图:2.4使用scikit-learn机器学习包的支持向量机算法,选择特征0和特征2对鸢尾花分类并画图,gamma参数分别设置为1、10、100,运行程序并截图,观察gamma参数对训练分数(score)的影响,请说明如果错误调整gamma参数会产生什么问题?2.4.1当gamma为1时:讲上文的gamma='auto‘ 里的auto改为1,得如下代码:svm=svm.SVC(kernel='rbf',C=1,gamma='1') svm.fit(X[:,1:3],y)运行上文可视化代码,得如下结果:2.4.2当gamma为10时:讲上文的gamma='auto‘ 里的auto改为10,得如下代码:svm=svm.SVC(kernel='rbf',C=1,gamma='10') svm.fit(X[:,:3:2],y)运行上文可视化代码,得如下结果:2.4.3当gamma为100时:讲上文的gamma='auto‘ 里的auto改为100,得如下代码:svm=svm.SVC(kernel='rbf',C=1,gamma='100') svm.fit(X[:,:3:2],y)运行上文可视化代码,得如下结果:2.4.4 结论参数gamma主要是对低维的样本进行高度度映射,gamma值越大映射的维度越高,训练的结果越好,但是越容易引起过拟合,即泛化能力低。通过上面的图可以看出gamma值越大,分数(score)越高。错误使用gamma值可能会引起过拟合,太低可能训练的结果太差。
  • [其他] 浅谈贝叶斯分析方法
    贝叶斯分析方法(Bayesian Analysis)是贝叶斯学习的基础,它提供了一种计算假设概率的方法,这种方法是基于假设的先验概率、给定假设下观察到不同数据的概率以及观察到的数据本身而得出的。其方法为,将关于未知参数的先验信息与样本信息综合,再根据贝叶斯公式,得出后验信息,然后根据后验信息去推断未知参数的方法。计算后验分布期望的传统数值计算方法是数值积分、拉普莱斯近似计算和蒙特卡洛(Monte Carlo)重要抽样。MCMC方法,即马尔可夫链——蒙特卡罗(Markov chain Monte Carlo)方法已经变成了非常流行的贝叶斯计算方法。一方面是由于它处理非常复杂问题的效率,另一方面是因为它的编程方法相对容易。贝叶斯分析方法(Bayesian Analysis)提供了一种计算假设概率的方法,这种方法是基于假设的先验概率、给定假设下观察到不同数据的概率以及观察到的数据本身而得出的。其方法为,将关于未知参数的先验信息与样本信息综合,再根据贝叶斯公式,得出后验信息,然后根据后验信息去推断未知参数的方法。在贝叶斯统计理论中,统计推断中的相关量均作为随机量对待,而不考虑其是否产生随机值。概率被理解为基于给定信息下对相关量不完全了解的程度,对于具有相同可能性的随机事件认为具有相同的概率。在进行测量不确定度的贝叶斯评定时,与测量结果推断或不确是度评定相关的每一个物理量均被分配一个随机变量,分布宽度常用标准差表示,反映了对未知真值了解的程度。按照贝叶斯理论,与测量或相关评定工作有关的每一个物理量均被分配一个随机变量,尽管每一个估计量和它所表示的相关被测量是不相同的,但它是用来估计被测量的待定真值的。贝叶斯理论基础经典统计在对随机分布参数进行参数估计时,假定待估计参数是未知常数,并认定这些参数的信息仅由样本携带,于是通过对样本“毫无偏见”的加工来获得参数估计。由于估计量可能有不完善之处,估计误差在所难免,因此经典统计理论中用置信区间表示这些误差的大小。在对概率的理解上,经典统计认为概率就是频率的稳定值。一旦离开了重复试验,就谈不上去理解概率。因此要精确估计上述参数,必须保证有大量的数据样本,但在工程中实测数据毕竟有限。另外,统计抽样时所要求的样本独立同分布的条件也很难满足。贝叶斯统计理论在估计随机分布参数时,认为待估计参数是随机变量,存在概率分布。贝叶斯方法对概率的理解是人们对某些事件的一种信任程度,是对事物的不确定性的一种主观判断,与个人因素等有关,,故称之为主观概率。贝叶斯统计中的先验分布反映的就是人们对于待估计参数的主观概率。为了在小样本量下能获得较好的参数估计,就必须利用参数的历史资料或先验知识。在进行参数估计时,贝叶斯学派认为后验分布综合了先验和样本的知识,可以对参数作出较先验分布更合理的估计,故其参数估计都是建立在后验分布基础上的,该方法对研究除观测数据外还具备较多信息的情况特别有效。尽管贝叶斯方法与经典统计方法有很大的不同,但在大样本条件下,由这两种方法估计出的参数是一致的。而在小样本的情况下,贝叶斯方法可充分利用各种信息,结果更为可靠。贝叶斯方法的特点是能充分利用现有信息,如总体信息、经验信息和样本信息等,将统计推断建立在后验分布的基础上。这样不但可以减少因样本量小而带来的统计误差,而且在没有数据样本的情况下也可以进行推断。贝叶斯理论是贝叶斯分析的基本工具,是以全概率法则为依据建立的。
  • [其他] 浅谈EM算法
    最大期望算法(Expectation-Maximization algorithm, EM),或Dempster-Laird-Rubin算法,是一类通过迭代进行极大似然估计(Maximum Likelihood Estimation, MLE)的优化算法,通常作为牛顿迭代法(Newton-Raphson method)的替代用于对包含隐变量(latent variable)或缺失数据(incomplete-data)的概率模型进行参数估计。EM算法的标准计算框架由E步(Expectation-step)和M步(Maximization step)交替组成,算法的收敛性可以确保迭代至少逼近局部极大值 。EM算法是MM算法(Minorize-Maximization algorithm)的特例之一,有多个改进版本,包括使用了贝叶斯推断的EM算法、EM梯度算法、广义EM算法等。由于迭代规则容易实现并可以灵活考虑隐变量 ,EM算法被广泛应用于处理数据的缺测值,以及很多机器学习(machine learning)算法,包括高斯混合模型(Gaussian Mixture Model, GMM)和隐马尔可夫模型(Hidden Markov Model, HMM)的参数估计。对EM算法的研究起源于统计学的误差分析(error analysis)问题。1886年,美国数学家Simon Newcomb在使用高斯混合模型(Gaussian Mixture Model, GMM)解释观测误差的长尾效应时提出了类似EM算法的迭代求解技术 。在极大似然估计(Maximum Likelihood Estimation, MLE)方法出现后,英国学者Anderson McKendrick在1926年发展了Newcomb的理论并在医学样本中进行了应用。1956年,Michael Healy和Michael Westmacott提出了统计学试验中估计缺失数据的迭代方法 ,该方法被认为是EM算法的一个特例。1970年,B. J. N. Blight使用MLE对指数族分布的I型删失数据(Type I censored data)进行了讨论 。Rolf Sundberg在1971至1974年进一步发展了指数族分布样本的MLE并给出了迭代计算的完整推导。EM算法的正式提出来自美国数学家Arthur Dempster、Nan Laird和Donald Rubin,其在1977年发表的研究对先前出现的作为特例的EM算法进行了总结并给出了标准算法的计算步骤,EM算法也由此被称为Dempster-Laird-Rubin算法 。1983年,美国数学家吴建福(C.F. Jeff Wu)给出了EM算法在指数族分布以外的收敛性证明。此外,在二十世纪60-70年代对隐马尔可夫模型(Hidden Markov Model, HMM)的研究中,Leonard E. Baum提出的基于MLE的HMM参数估计方法,即Baum-Welch算法(Baum-Welch algorithm)也是EM算法的特例之一 。应用:数据分析,机器学习 在Python 3环境使用EM算法求解GMM的编程实现:12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788# 导入模块import numpy as npimport matplotlib.pyplot as pltfrom scipy.stats import multivariate_normal# 构建测试数据N = 200; pi1 = np.array([0.6, 0.3, 0.1])mu1 = np.array([[0,4], [-2,0], [3,-3]])sigma1 = np.array([[[3,0],[0,0.5]], [[1,0],[0,2]], [[.5,0],[0,.5]]])gen = [np.random.multivariate_normal(mu, sigma, int(pi*N)) for mu, sigma, pi in zip(mu1, sigma1, pi1)]X = np.concatenate(gen)# 初始化: mu, sigma, pi = 均值, 协方差矩阵, 混合系数theta = {}; param = {}theta['pi'] = [1/3, 1/3, 1/3]            # 均匀初始化theta['mu'] = np.random.random((3, 2))   # 随机初始化theta['sigma'] = np.array([np.eye(2)]*3) # 初始化为单位正定矩阵param['k'] = len(pi1); param['N'] = X.shape[0]; param['dim'] = X.shape[1]# 定义函数def GMM_component(X, theta, c):    '''    由联合正态分布计算GMM的单个成员    '''    return theta['pi'][c]*multivariate_normal(theta['mu'][c], theta['sigma'][c, ...]).pdf(X) def E_step(theta, param):    '''    E步:更新隐变量概率分布q(Z)。    '''    q = np.zeros((param['k'], param['N']))    for i in range(param['k']):        q[i, :] = GMM_component(X, theta, i)    q /= q.sum(axis=0)    return q def M_step(X, q, theta, param):    '''    M步:使用q(Z)更新GMM参数。    '''    pi_temp = q.sum(axis=1); pi_temp /= param['N'] # 计算pi    mu_temp = q.dot(X); mu_temp /= q.sum(axis=1)[:, None] # 计算mu    sigma_temp = np.zeros((param['k'], param['dim'], param['dim']))    for i in range(param['k']):        ys = X - mu_temp[i, :]        sigma_temp[i] = np.sum(q[i, :, None, None]*np.matmul(ys[..., None], ys[:, None, :]), axis=0)    sigma_temp /= np.sum(q, axis=1)[:, None, None] # 计算sigma    theta['pi'] = pi_temp; theta['mu'] = mu_temp; theta['sigma'] = sigma_temp    return theta def likelihood(X, theta):    '''    计算GMM的对数似然。    '''    ll = 0    for i in range(param['k']):        ll += GMM_component(X, theta, i)    ll = np.log(ll).sum()    return ll def EM_GMM(X, theta, param, eps=1e-5, max_iter=1000):    '''    高斯混合模型的EM算法求解        theta: GMM模型参数; param: 其它系数; eps: 计算精度; max_iter: 最大迭代次数        返回对数似然和参数theta,theta是包含pi、mu、sigma的Python字典    '''    for i in range(max_iter):        ll_old = 0        # E-step        q = E_step(theta, param)        # M-step        theta = M_step(X, q, theta, param)        ll_new = likelihood(X, theta)        if np.abs(ll_new - ll_old) < eps:            break;        else:            ll_old = ll_new    return ll_new, theta# EM算法求解GMM,最大迭代次数为1e5ll, theta2 = EM_GMM(X, theta, param, max_iter=10000)# 由theta计算联合正态分布的概率密度L = 100; Xlim = [-6, 6]; Ylim = [-6, 6]XGrid, YGrid = np.meshgrid(np.linspace(Xlim[0], Xlim[1], L), np.linspace(Ylim[0], Ylim[1], L))Xout = np.vstack([XGrid.ravel(), YGrid.ravel()]).TMVN = np.zeros(L*L)for i in range(param['k']):    MVN += GMM_component(Xout, theta, i)MVN = MVN.reshape((L, L))# 绘制结果plt.plot(X[:, 0], X[:, 1], 'x', c='gray', zorder=1)plt.contour(XGrid, YGrid, MVN, 5, colors=('k',), linewidths=(2,))
  • [技术干货] WeAutomate Studio【控件】【UI自动化—基于OCR的自动化—本地OCR】【Tesseract】
    一、【使用官方ocr模型】1. 自行下载Tesseract-OCR,安装包下载地址:https://digi.bib.uni-mannheim.de/tesseract/?C=M;O=D ,类似'tesseract-ocr-w64-setup-v5.1.0.20220510.exe';见图1;图12. 安装目录设置环境变量,比如Path中新增‘D:/Tesseract-OCR’;见图2;图23. 设置系统变量名TESSDATA_PREFIX,变量值为'D:/Tesseract-OCR/tessdata';见图3;图34. 默认只有英文语言包,所以下载需要的语言包放入到第3点中的目录下,语言包下载地址:https://github.com/tesseract-ocr/tessdata ,例如‘chi_sim.traineddata’就是中文语言包;见图4;图45. 若出现”no module named 'pytesseract'“,请到studio安装目录下的python文件夹下,进入cmd命令行黑窗口,输入python -m pip install pytesseract。见图5图5二、【自行训练模型】:1. 配置java环境,至少jdk-8及以上,下载地址:https://www.oracle.com/java/technologies/downloads/#jdk18-windows ;见图6;图62. 下载jTessBoxEditor软件:https://sourceforge.net/projects/vietocr/files/jTessBoxEditor/ ;见图7;图73.  修改环境变量:例如,需要将【使用官方ocr模型】的第2、3点中的路径分别改为‘D:\jTessBoxEditor\tesseract-ocr’和‘D:\jTessBoxEditor\tesseract-ocr\tessdata’;见图8、9;图8图94.  在安装目录中找到train.bat双击打开jTessBoxEditor;见图10;图105.  在jTessBoxEditor界面上的Trainer标签页,见图11;图11   (1)Tesseract Executables设置为例如‘D:\jTessBoxEditor\tesseract-ocr\tesseract.exe’;   (2)Training Data设置为需要识别的图片,png或jpg或tif等;   (3)Language自定义,代表训练的模型包名,例如‘chi_sim_new’,即chi_sim_new.traineddata文件名;   (4)Bootstrap Language指用什么语言模型来识别你的图片,例如此处为官方的‘chi_sim’中文训练模型名;            注意:默认只含有英文包eng.traineddata,需要自行下载中文包chi_sim.traineddata,请看上面第一大点【使用官方ocr模型】中第4点讲解。   (5)找到‘RTL’右侧的下拉框,选择‘Make Box File’,之后点击‘Run’;6. 在jTessBoxEditor界面上的Box Editor标签页,见图12;图12  (1)点击‘Open’打开需要识别的图片,即第5点(2)中设置的;  (2)在Box Editor标签下的Box View标签下,结合右侧操作界面,修改识别错误的字体。其中Character为待修改的字体,修改完记得回车;X,Y,W,H分別为字体周围绿色框的横纵坐标,宽高;Merge,Split,Insert,Delete分别代表合并、分离、插入、删除字体框;  (3)修改完后,点击‘Save’,并点击‘Reload’;7. 回到jTessBoxEditor界面上的Trainer标签页,见图13;图13(1)只需选择第5点(5)中的下拉框的值为‘Train with Existing Box’,再点击‘Run’(2)找到同图片路径下生成的tessdata文件夹下的.traineddata(自己训练的模型),例如此次设置的chi_sim_new.traineddata,把此文件放入此次假设的jTessBoxEditor软件安装目录相关路径中:‘D:\jTessBoxEditor\tesseract-ocr\tessdata’8. 控件中的‘识别语言类型’参数,输入此次训练的模型名,例如chi_sim_new,若想结合官方提供的训练模型一起识别图片,直接用+号连接,比如中文模型chi_sim,则可在参数中填入chi_sim+chi_sim_new,见图14;       【简单建议】:直接输入你自己训练的模型名,不要联合官方的,正确率更高,除非你训练模型的图片够多,够好;       【深入理由解释】:联合官方的模型,会导致你的模型过拟合,除非你训练模型的数据集够大够好。图14
  • [其他] 浅谈常见聚类算法
    K-means 聚类算法K-means 聚类算法 可能是大家最为熟悉的聚类算法。它在许多的工业级数据科学和机器学习课程中都有被讲解。并且容易理解和实现相应功能的代码 。    我们先确定要聚类的数量,并随机初始化它们各自的中心点。为了确定要聚类的数量,最好快速查看数据并尝试识别任何不同的分组。中心点是与每个数据点向量长度相同的向量,是上图中的“x”。通过计算当前点与每个组中心之间的距离,对每个数据点进行分类,然后归到与距离最近的中心的组中。基于迭代后的结果,计算每一类内,所有点的平均值,作为新簇中心。迭代重复这些步骤,或者直到组中心在迭代之间变化不大。您还可以选择随机初始化组中心几次,然后选择看起来提供最佳结果。Mean-Shift 聚类Mean-shift 聚类是一个基于滑窗的算法,尝试找到数据点密集的区域。它是一个基于质心的算法,也就是说他的目标是通过更新中心点候选者定位每个组或类的中心点,将中心点候选者更新为滑窗内点的均值。这些候选滑窗之后会在后处理阶段被过滤,来减少临近的重复点,最后形成了中心点的集合和他们对应的组。DBSCAN 笑脸聚类    DBSCAN 从一个任意的还没有被访问过的启动数据点开始。用一个距离 epsilon ε 将这个点的邻域提取出来(所有再距离 ε 内的点都视为邻居点)。如果在邻域内有足够数量的点(根据 minPoints) ,那么聚类过程开始,并且当前数据点变成新集群中的第一个点。否则,该点将被标记为噪声(之后这个噪声点可能会变成集群中的一部分)。在这两种情况中的点都被标记为”已访问“。对于这个新集群中的第一个点,在它 ε 距离邻域内的点已将变成相同集群中的一部分。这个让所有在 ε 邻域内的点都属于相同集群的过程在之后会一直被重复做,直到所有新点都被加进集群分组中。第 2,3 步的过程会一直重复直到集群内所有点都被确定,即所有在 ε 邻域内的点都被访问且被打上标签。我们在当前集群做完这些,一个新的未被访问的点会被提取并处理,从而会接着发现下一个集群或噪声。这个过程反复进行直到所有的点都被编辑为已访问。既然在最后所有的点都被访问,那么每个点都被标记为属于一个集群或者是噪声。基于高斯混合模型(GMM)的期望最大化(EM)聚类k-means的一个主要缺点是它简单地使用了集群中心的平均值。通过下面的图片,我们可以看到为什么这不是最好的方式。在左手边,人眼可以很明显地看到,有两个半径不同的圆形星团以相同的平均值为中心。k-means不能处理这个问题,因为不同簇的平均值非常接近。当簇不是圆形时,k均值也会失效,这也是将均值用作簇中心的后果。使用GMMs的EM聚类我们首先设定聚类簇的数量(如k-means),然后随机初始化每个集群的高斯分布参数。我们也可以通过快速查看数据来为初始参数提供一个很好的猜测。正如上图所示,这不是100%必要的,因为高斯操作开始时候是非常差的,但很快优化。给定每个簇的高斯分布,计算每个数据点属于特定簇的概率。一个点越靠近高斯中心,它就越可能属于该簇。这应该是直观的,因为对于高斯分布,我们假设大多数数据都靠近集群的中心。基于这些概率,我们为高斯分布计算了一组新的参数,这样我们就可以最大化群集中数据点的概率。我们使用数据点位置的加权和计算这些新参数,其中权重是属于特定集群的数据点的概率。为了以可视化的方式解释这一点,我们可以查看上面的图形,特别是以黄色集群为例。在第一次迭代中,分布是随机开始的,但是我们可以看到大多数黄点都在分布的右边。当我们计算一个由概率加权的和时,即使在中心附近有一些点,但大多数都在右边。因此,分布的平均值很自然地移近这些点集。我们还可以看到,大多数点是“从右上到左下”。因此,标准偏差会发生变化,以创建一个更适合这些点的椭圆,以便最大化概率加权的和。第2步和第3步重复进行,直到收敛,也就是在收敛过程中,迭代变化不大。凝聚层次聚类凝聚层次聚类算法实际上分为 2 类:自上而下或自下而上。自下而上算法在一开始将每个数据点当作一个单个集群对待,然后逐步的合并(或凝聚)成对的集群,直到所有的集群被合并到一个集群中,这个集群包含所有的点。自下而上层次聚类因此被叫做层次凝聚的聚类或者 HAC。这个聚类的层次被表示为一棵树(或者树状图)。树根是唯一的集群,他聚集了所有的样本,叶子是只有一个样本的集群。
  • [干货汇总] 基于华为云ModelArts的水表读数识别开发实践
    >【摘要】 这是水表读数识别项目,实现了如何端到端完成水表读数识别项目。涉及领域包括图像分类、语义分割、OCR文本检测、OCR文本识别。 本文分享自华为云社区《[基于华为云ModelArts的水表读数识别开发实践【华为云至简致远】](https://bbs.huaweicloud.com/blogs/358446)》,作者: Tianyi_Li 。 # 水表读数识别 **项目简介:** 这里实现了如何端到端完成水表读数识别项目。涉及领域包括图像分类、语义分割、OCR文本检测、OCR文本识别。 本案例提供的方法较多,涉及多个模型,但不需要运行所有的模型。如果都测试一遍,默认创建的5GB磁盘规格可能不够用。 **磁盘空间不够时可以将不需要的数据和模型文件删除,腾出空间;或者创建NoteBook时将磁盘规格增加到10GB。** **解决方案流程:** 一、使用语义分割或者OCR文本检测算法识别水表读数所在的四边形区域,并对四边形进行仿射变换转换成矩形,保存成新的图片数据。 二、如果文本区域的图片翻转严重,那第一步抠图生成的数据可能会有180度的翻转。因为文本识别的算法对翻转180度的场景效果不佳,所以再训练一个识别文本翻转的分类模型(本案例图片旋转角度微小,不需要此步骤,内容可供参考)。 三、利用步骤一中检测并抠图出来的文本数据训练OCR文本识别算法,识别图片中的文本内容,即数字。 数据集为华为云AI Gallery上提供的数据集。详情可参见本案例的关联资产。 **下载该项目依赖脚本:** ``` !wget --no-check-certificate https://modelarts-cnnorth4-market.obs.cn-north-4.myhuaweicloud.com/moxing-apps/notebooks/WaterMeter_Identification/deps.zip -O deps.zip !unzip -qo deps.zip !rm -f deps.zip !ls ``` ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/10/1654828290640769180.png) 该案例效果图如下 ``` import cv2 import matplotlib.pyplot as plt plt.figure(figsize=(10, 10)) plt.imshow(cv2.imread('./imgs/result1.PNG')) plt.show() ``` ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/10/1654828313147600490.png) # 1.准备环境 **请在本页面的右上角确认您所选择的kernel是PyTorch-1.4,选择的规格是GPU,如下图所示:** ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/10/1654830674303482240.png) 如果没有V100,也可以选择P100,如图所示,看看配置: ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/10/1654830683253159783.png) **运行时依赖** - moxing>=2.0.1 - torch>=1.4 - 1.4.0>mmcv-full>=1.3.8 (如果环境中没有mmcv-full,安装可能会消耗10几分钟) - tensorboard - 将环境中的pycocotools替换成mmpycocotools - 其他依赖安装 - lanms安装 ``` !pip uninstall -y moxing !pip install --upgrade pip !pip install "mmcv-full>=1.3.8,=1.4.0" -I !wget --no-check-certificate https://modelarts-cnnorth1-market-dataset.obs.cn-north-1.myhuaweicloud.com/moxing-apps/packages/moxing-2.0.1.rc0.7ce21509-py2.py3-none-any.whl -O moxing-2.0.1rc0-py2.py3-none-any.whl !pip install moxing-2.0.1rc0-py2.py3-none-any.whl !pip install future tensorboard !pip uninstall -y pycocotools !pip install mmpycocotools !pip install --upgrade opencv-python !pip install --ignore-installed imageio !pip install imgaug !pip install prettytable lmdb Polygon3 rapidfuzz pyclipper iopath yacs submitit ``` ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/10/1654830718296605112.png) lanms安装: ``` !wget http://repo.myhuaweicloud.com/repository/pypi/packages/96/c0/50dc2c857ed060e907adaef31184413a7706e475c322236d346382e45195/lanms-1.0.2.tar.gz !tar -zxf lanms-1.0.2.tar.gz # 解压到lanms-1.0.2文件夹 %cd lanms-1.0.2 #将Makefile文件第一行的内容修改为:CXXFLAGS = -I include -std=c++11 -O3 -I/home/ma-user/anaconda3/include/python3.6m/ with open('Makefile', "r+") as f: read_data = f.read() f.seek(0) f.truncate() #清空文件 f.write(read_data.replace('$(shell python3-config --cflags)', '-I/home/ma-user/anaconda3/include/python3.6m/')) !python setup.py install import sys sys.path.insert(0, '/home/ma-user/work/lanms-1.0.2') %cd ../ ``` # 2.准备数据 ## 2.1.数据下载 可以登录https://www.datafountain.cn/competitions/480/datasets进行下载(需要报名参赛才可以下载)。 或者使用备用下载地址下载并解压: ``` !wget https://modelarts-cnnorth1-market-dataset.obs.cn-north-1.myhuaweicloud.com/dataset-apps/water_meter/water_meter_from_DataFountain.zip -O ./data.zip !mkdir -p ./data/raw !unzip -qo data.zip -d ./data/raw !rm -f data.zip !ls ./data/raw ``` 数据格式如下(如果数据格式不一致,请处理成一致的格式,放入./data/raw目录下): ``` ./data/raw ├── train_imgs ------------------------ 训练集图片目录 │ ├── train_1.jpg │ ├── ... │ ├── train_1000.jpg ├── train_labels ---------------------- 训练集图片标签目录 │ ├── label说明.docx │ ├── labels │ │ ├── train_1.txt │ │ ├── ... │ │ ├── train_1000.txt ├── test_imgs -------------------------- 测试集图片目录 │ ├── test_1.jpg │ ├── ... │ ├── test_500.jpg ``` train_labels中的txt标签文件说明可参考./data/raw/train_labels/label说明.docx,如果notebook无法打开可以下载到本地再打开。 以其中一个文件内容为例: ``` 95 423 286 319 314 366 126 472 00093 00092 ``` 标签中前八个值,为水表表盘的四个角点(x1, y1, x2, y2, x3, y3, x4, y4),分别为:左上、右上、右下、左下。后面的值为表盘的数值,由于最后一位出现半字符的情况,所以有两个数值,如果没有半字符则只有一个数值。参考如下图片: ``` import cv2 import matplotlib.pyplot as plt plt.figure(figsize=(10, 10)) plt.imshow(cv2.imread('./imgs/label.png')) plt.show() ``` ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20226/10/1654830818840877236.png) ## 2.2.数据切分 为了方便训练模型时观察模型的训练效果,将数据集切分成训练集和验证集,默认切分比例 训练集:验证集=9:1,保存在./data/train.txt和./data/eval.txt。 ``` from util import split_data img_dir = './data/raw/train_imgs' # 原始图片路径 save_dir = './data/' # 切分结果保存路径 split_data(img_dir, save_dir) # 开始切分 print('Finished!') ``` ``` !ls ./data ``` # 3.文本检测 本案例尝试了两种算法识别度数区域。分别是语义分割算法deeplabv3和文本检测算法dbnet。对比之后分割算法结果更佳。 **分割算法和文本检测算法两者选择其一即可,推荐分割算法。** ## 3.1.分割算法(推荐) **与文本检测算法二选一即可。** ### 3.1.1.数据准备 分割算法的数据标签通常为单通道的PNG图片。所以我们需要通过原始的txt标签文件生成PNG图片。保存在./data/segmentation/labels目录下。 ``` from segmentation.data_util import create_labels img_dir = './data/raw/train_imgs/' # 原始图片路径 anno_dir = './data/raw/train_labels/labels' # 原始标注文件路径 save_dir = './data/segmentation/labels' # 分割标签保存路径 create_labels(img_dir, anno_dir, save_dir) # 生成标签 print('Finished!') ``` 标签可视化: ``` import cv2 import numpy as np import matplotlib.pyplot as plt def show(img_path, label_path): # 读取原始图片 img = cv2.imread(img_path) # 读取标签图片 label = cv2.imread(label_path) # 标注结果图片的背景像素值为0,物体的像素值为1,均显示为黑色。 # 为了可视化效果明显,突出物体的标注区域,这里将物体的像素值1(黑色)替换为255(白色)。 label[label==1] = 255 # 原始图片和标签图片像素融合 merge = img * 0.5 + label * 0.5 merge = merge.astype(np.uint8) images_to_observe = [img, label, merge] titles = ['原始图片','标签图片','原始图片+标签图片融合'] # 结果可视化 fig = plt.figure(figsize=(30, 30)) for i in range(len(images_to_observe)): fig.add_subplot(1, len(images_to_observe), i + 1).set_title(titles[i], fontsize=18, color='r') imgplot = plt.imshow(images_to_observe[i]) plt.show() if __name__ == '__main__': # 以其中一张图片为例 img_path = './data/raw/train_imgs/train_10.jpg' label_path = './data/segmentation/labels/train_10.png' show(img_path, label_path) ``` ### 3.1.2.下载预训练模型 执行以下命令下载预训练模型并保存到./pretrained_model/deeplabv3plus_r50-d8.pth: ``` !mkdir -p ./pretrained_model !wget --no-check-certificate https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_512x512_80k_ade20k/deeplabv3plus_r50-d8_512x512_80k_ade20k_20200614_185028-bf1400d8.pth -O ./pretrained_model/deeplabv3plus_r50-d8.pth ``` ### 3.1.3.训练 训练时加载预训练模型: ``` ./pretrained_model/deeplabv3plus_r50-d8.pth ``` 为了节省训练时间,默认训练1000步,每一步训练8个样本,每200步验证一次精度,每200步保存一次模型。如果要进一步提升精度,可以尝试修改./segmentation/train.py脚本中的配置参数,将训练步数增大。训练好的模型保存在./train_url/segmentation目录下。 训练时默认加载./data/train.txt和./data/eval.txt中保存的样本作为训练集和验证集。请参考./segmentation/train.py。 **单卡训练:** 单卡大约耗时15分钟左右。 ``` !python ./segmentation/train.py \ --num_classes=2 \ --data_url=./data/ \ --eval_data_url=./data/ \ --img_dir=raw/train_imgs \ --ann_dir=segmentation/labels \ --work_dir=./train_url/segmentation \ --load_from=./pretrained_model/deeplabv3plus_r50-d8.pth # num_classes:数据类别数 # data_url:训练集根目录 # eval_data_url:验证集根目录 # img_dir:根目录下存放图片的目录名称 # ann_dir:根目录下存放标签的目录名称 # work_dir:保存输出模型的路径 # load_from:预置模型文件路径 ``` 多卡训练: NoteBook创建多卡环境时可使用,用来加速。 ``` !python -m torch.distributed.launch \ --nproc_per_node=$(/usr/local/nvidia/bin/nvidia-smi -L | wc -l) \ --master_port=7000 \ ./segmentation/train.py \ --launcher=pytorch \ --num_classes=2 \ --data_url=./data \ --eval_data_url=./data \ --img_dir=raw/train_imgs \ --ann_dir=segmentation/labels \ --work_dir=./train_url/segmentation \ --load_from=./pretrained_model/deeplabv3plus_r50-d8.pth # nproc_per_node:每个节点启动的进程数(GPU数) # launcher:分布式启动方式 # num_classes:数据类别数 # data_url:训练集根目录 # eval_data_url:验证集根目录 # img_dir:根目录下存放图片的目录名称 # ann_dir:根目录下存放标签的目录名称 # work_dir:保存输出模型的路径 # load_from:预置模型文件路径 ``` ### 3.1.4.推理+四边形定位+矫正 训练完成后,使用训练好的分割模型对图片进行推理,分割模型返回的推理结果是个2维数组,保存了预测图片每个像素点的标签值。 然后对推理结果做四边形的定位,再将四边形矫正成矩形,最后将矩形区域保存成新的图片数据。这部分数据用来训练后面的文本识别算法。保存在./data/textrecog/images_from_seg路径下。 对原始图片./data/raw/train_imgs进行推理: ``` !python ./segmentation/infer_and_crop.py \ --num_classes=2 \ --img_path=./data/raw/train_imgs \ --checkpoint=./train_url/segmentation/latest.pth \ --save_dir=./data/textrecog/images_from_seg # num_classes:类别数 # img_path:要推理的图片目录 # checkpoint:模型文件 # save_path:推理结果保存路径 ``` 推理结果可视化: ``` from util import show_pair img_dir = './data/raw/train_imgs' # 训练集原始图片 result_dir = './data/textrecog/images_from_seg' # 训练集推理结果 show_pair(img_dir, result_dir, show_num=2) ``` ## 3.2.文本检测算法 与分割算法二选一即可。 ### 3.2.1.数据准备 将数据的元信息保存在json文件中。文本检测的标签默认只有一类text,只要对文本区域进行标注并训练,识别出文本区域即可,和分割算法一样,不需要识别文本中的内容。 训练文件保存在./data/textdet/instances_training.json,验证文件保存在./data/textdet/instances_test.json。 ``` import os from textdet.data_util import create_water_json base_dir = './data' annotation_dir = os.path.join(base_dir, 'raw/train_labels/labels') img_dir = os.path.join(base_dir, 'raw/train_imgs') # train create_water_json(img_dir=img_dir, # 图片路径 anno_dir=annotation_dir, # 标注文件路径 save_file=os.path.join(base_dir, 'textdet/instances_training.json'), # 训练文件保存路径 split=os.path.join(base_dir, 'train.txt')) # 保存训练样本的文件 # eval create_water_json(img_dir=img_dir, # 图片路径 anno_dir=annotation_dir, # 标注文件路径 save_file=os.path.join(base_dir, 'textdet/instances_test.json'), # 验证文件保存路径 split=os.path.join(base_dir, 'eval.txt')) # 保存验证样本的文件 ``` 生成的json文件格式如下: ``` { 'images': [{'file_name': 'train_1.jpg', 'height': 960, 'width': 540, 'segm_file': None, 'id': 0}, {'file_name': 'train_2.jpg', 'height': 540, 'width': 960, 'segm_file': None, 'id': 1}, ...]}, 'categories': [{'id': 1, 'name': 'text'}], 'annotations': [{'iscrowd': 0, 'category_id': 1, 'bbox': [126, 283, 241, 147], 'area': 13363, 'segmentation': [[126, 379, 345, 283, 367, 333, 144, 430]], 'image_id': 0, 'id': 0}, {'iscrowd': 0, 'category_id': 1, 'bbox': [430, 159, 204, 67], 'area': 10316, 'segmentation': [[445, 159, 634, 170, 630, 226, 430, 205]], 'image_id': 1, 'id': 1}, ...] } ``` images: - file_name:图片名称 - height: 图片的高 - width: 图片的宽 - id:图片的索引 categories: - id:标签的索引 - name:标签值 annotations: - iscrowd:默认值为0,segmentation使用polygon格式,。 - area: 四边形的面积。 - segmentation:四边形的四个角点的坐标。 - image_id:图片的索引。 - id:文本框的索引 ### 3.2.2.下载预训练模型 ``` !wget --no-check-certificate https://download.pytorch.org/models/resnet50-19c8e357.pth -O ./pretrained_model/resnet50-19c8e357.pth !wget --no-check-certificate https://download.openmmlab.com/mmocr/textdet/dbnet/dbnet_r50dcnv2_fpnc_sbn_2e_synthtext_20210325-aa96e477.pth -O ./pretrained_model/dbnet_r50dcnv2_fpnc_sbn_2e_synthtext.pth ``` ### 3.2.3.训练 训练的数据集、模型、优化器等均已保存在配置文件./textdet/water_meter_textdet_config.py和./textdet/base_config.py中。 base_config.py文件是基础配置,可不必改动。 water_meter_textdet_config.py文件是针对该案例的配置,例如数据路径、预训练模型路径、epoch数、学习率等可直接在此文件中修改。 为了节省时间,默认训练10个epoch,每2个epoch验证一次,保存一次模型。如果精度不够,可以修改water_meter_textdet_config.py中的训练参数。将epoch数调大,可调至30-100之间,epoch越大,训练时间越久。训练的模型保存在./train_url/textdet路径下。 **单卡训练:** 单卡训练较慢,大约耗时15分钟左右。 ``` !python textdet/train.py ./textdet/water_meter_textdet_config.py --work-dir=./train_url/textdet ``` 多卡训练: NoteBook创建多卡环境时可使用,可加速训练。 ``` !python -m torch.distributed.launch \ --nproc_per_node=$(/usr/local/nvidia/bin/nvidia-smi -L | wc -l) \ --master_port=7000 \ textdet/train.py \ ./textdet/water_meter_textdet_config.py \ --launcher=pytorch \ --work-dir=./train_url/textdet # nproc_per_node:每个节点启动的进程数(GPU数) # launcher:分布式启动方式 # work-dir:模型保存的路径 ``` ### 3.2.4.推理 推理生成的结果保存在./data/textdet/results路径下,该路径下包含两个文件夹out_vis_dir和out_txt_dir。 out_vis_dir目录下存放每张图片推理的可视化结果,保存为jpg文件。out_txt_dir目录下存放每张图片推理出的四边形区域的坐标值,保存为txt文件。 ``` !python textdet/infer.py \ ./data/raw/train_imgs \ ./textdet/water_meter_textdet_config.py \ ./train_url/textdet/latest.pth \ --out-dir=./data/textdet/results # 第1个参数: 推理的图片路径 # 第2个参数: 模型的配置文件 # 第3个参数: 训练好的模型文件 # 第4个参数: 推理结果保存路径 ``` out_txt_dir目录下txt文件的内容如下: ``` 393,180,615,177,616,241,394,244,1 ``` 393,180,615,177,616,241,394,244:代表4个角点的坐标,分别是左上角,右上角,右下角,左下角。 1:标签索引,1代表是文本区域。 out_vis_dir目录下为图片,可直接进入./data/textdet/results/out_vis_dir目录下打开图片查看,或者使用下面的可视化接口查看: ``` from util import show img_dir = './data/textdet/results/out_vis_dir' show(img_dir, show_num=3) ``` ### 3.2.5.抠图 根据上面的推理结果,将文本区域抠出来保存成新的图片,用于训练文本识别模型。保存路径为./data/textrecog/images_from_textdet。 ``` from textdet.data_util import cutout img_dir = './data/raw/train_imgs' # 推理时的原始图片路径 cutout(img_dir, ann_dir='./data/textdet/results/out_txt_dir/', # 推理结果txt文件 save_dir='./data/textrecog/images_from_textdet' # 抠图结果保存路径 ) print('Finished') ``` 抠图结果可视化: ``` from util import show_pair img_dir = './data/raw/train_imgs' # 训练集原始图片 result_dir = './data/textrecog/images_from_textdet' # 训练集推理结果 show_pair(img_dir, result_dir, show_num=2) ``` # 4.文本翻转检测(可选) 本案例数据集物体倾斜角度较小,不需要进行翻转识别,如果遇到随机翻转严重的数据集可以参考这部分代码训练一个识别翻转的模型。 文本检测算法中已经将需要识别的文本区域抠图并保存。接下来利用这部分数据训练一个文本识别算法。因为文本区域做了角度的矫正。但是无法区分翻转0度和180度的图片,而文本识别的算法对翻转180度的场景效果不佳。所以我们又训练了一个专门识别翻转的模型。用来做180度翻转的矫正。 ## 4.1.数据准备 可将文本检测抠出来的图片做180度翻转的离线扩充。根据文本检测抠出的图片以及离线扩充后的数据进行人工标注正常或翻转。 **但是本案例图片倾斜角度较小,抠图的结果均为正向,不需要人工标注。原始图片均为正向0度翻转,离线扩充进行180度翻转后的均为180度翻转的图片。** **离线扩充:** 分割模型的精度较高,结果较准确,我们使用分割模型的推理结果进行离线扩充 ``` import os from PIL import Image import moxing as mox def flip_upside_down(img_dir, save_dir): mox.file.make_dirs(save_dir) imgs_list = os.listdir(img_dir) for img_name in imgs_list: img = Image.open(os.path.join(img_dir, img_name)) img.rotate(180).save(os.path.join(save_dir, img_name)) # 图片旋转180度并保存 if __name__ == '__main__': img_dir = './data/textrecog/images_from_seg' flip_save_dir = './data/detect_180/flip_180' # 翻转数据的保存路径,保存在./data/detect_180目录下 flip_upside_down(img_dir, flip_save_dir) # 进行翻转处理 mox.file.copy_parallel(img_dir, './data/detect_180/normal') # 将正常数据拷贝一份到./data/detect_180目录下,用于训练翻转模型 print('Finished!') ``` 离线结果可视化: ``` from util import show img_dir = './data/detect_180/flip_180' show(img_dir, show_num=5) ``` ## 4.2.下载预训练模型 执行以下命令下载模型,模型保存到./pretrained_model/mobilenet_v2.pth。 ``` !wget --no-check-certificate https://download.openmmlab.com/mmclassification/v0/mobilenet_v2/mobilenet_v2_batch256_imagenet_20200708-3b2dc3af.pth -O ./pretrained_model/mobilenet_v2.pth ``` ## 4.3.训练 识别图片翻转可以使用小点的模型,这里我们以mobilenet_v2为例,如果精度不够可以换稍大点的模型。 使用前面下载的预训练模型,./pretrained_model/mobilenet_v2.pth。 为了节省时间,默认训练25个epoch,每一步训练64个样本,每2个epoch验证一次精度,每2个epoch保存一次模型。大约耗时2-3分钟左右。如果想要更高的精度,可以修改./code/detect_180/train.py脚本中的配置参数。或者换大点的模型。模型较小,使用单卡训练即可。多卡训练可参考其他模型的多卡训练。 这里没有将数据切分成训练集和验证集,可自行切分,指定eval_data_url。 ``` !python ./detect_180/train.py \ --num_classes=2 \ --data_url=./data/detect_180 \ --work_dir=./train_url/detect_180 \ --load_from=./pretrained_model/mobilenet_v2.pth #--eval_data_url=./data/detect_180 # num_classes:数据类别数 # data_url:训练集存放路径 # eval_data_url:验证集存放路径 # work_dir:保存输出模型的路径 # load_from:预置模型文件路径 ``` ## 4.4.推理 训练的模型保存在./train_url/detect_180路径下,加载该路径下的模型进行推理。就以训练集路径下的翻转图片为例。 ``` !python ./detect_180/infer.py \ --num_classes=2 \ --img_path=./data/detect_180/flip_180 \ --checkpoint=./train_url/detect_180/latest.pth ``` # 5.文本识别 ## 5.1.数据准备 根据文本检测后的抠图数据和原始的txt标注文件创建文本内容识别的标签文件。 水表中有的度数转到一半,会同时出现两个数字。原始标注文件中也标注了多个label,从实际情况出发,我们选择符合实际情况的标签(如果转到一半,选择小的那个度数)。有一些特殊的图片,需要人工过滤一下:例如train_19.jpg这张图片。 ``` import cv2 import matplotlib.pyplot as plt imgplot = plt.imshow(cv2.imread('./data/raw/train_imgs/train_19.jpg')) plt.show() ``` 该图片的原始标签有四个['00069', '00070', '00060', '00079'],但从实际情况出发,符合条件的应该是00069和 00070。我们选择度数小的那个作为标签值,即00069。 还有几张图片的标注格式与其他标注文件不同,例如train_140.jpg这张图片标注的标签格式是00470.00479,其他文件都是空格分隔00470 00479。这种图片只有几张我们也进行人工过滤。 下面根据原始的标注文件生成文本识别需要的标注文件格式。 ``` from textrecog.data_util import gen_label_file ann_dir = './data/raw/train_labels/labels' # train train_split_path = './data/train.txt' train_save_path = './data/textrecog/train_label.txt' gen_label_file(train_split_path, ann_dir, train_save_path) # eval eval_split_path = './data/eval.txt' eval_save_path = './data/textrecog/eval_label.txt' gen_label_file(eval_split_path, ann_dir, eval_save_path) print('Finished!') print('标注文件内容如下,文本图片名称+文本数字内容') !head -n 5 ./data/textrecog/train_label.txt ``` ## 5.2.下载预训练模型 执行以下命令下载模型,模型保存到./pretrained_model/crnn_academic-a723a1c5.pth。 ``` !wget --no-check-certificate https://download.openmmlab.com/mmocr/textrecog/crnn/crnn_academic-a723a1c5.pth -O ./pretrained_model/crnn_academic-a723a1c5.pth ``` ## 5.3.训练 训练的数据集、模型、优化器等均已保存在配置文件./textrecog/water_meter_textrecog_config.py和./textrecog/base_config.py中。 base_config.py文件是基础配置,可不必改动。 water_meter_textrecog_config.py文件是针对该案例的配置,例如数据路径、预训练模型路径、epoch数、学习率等可直接在此文件中修改。 默认训练50个epoch,精度不够,可以修改water_meter_textrecog_config.py中的训练参数进行调参。 训练生成的模型保存在./train_url/textrecog路径下。大约耗时2-3分钟左右: ``` !python ./textrecog/train.py \ ./textrecog/water_meter_textrecog_config.py \ --work-dir=./train_url/textrecog ``` ## 5.4.推理 生成推理文件列表: 将需要推理的文件名称保存在txt文件中。 ``` import os img_root_path = './data/textrecog/images_from_seg' with open('./data/textrecog/infer_imgs_list.txt', 'w') as f: f.write('\n'.join(os.listdir(img_root_path))) !head -n 5 ./data/textrecog/infer_imgs_list.txt # 查看生成文件的前5行样本 ``` 推理: 利用训练好的模型进行推理并保存推理结果。结果保存在./data/textrecog/infer_results目录下。该目录下会有多个文件和目录生成。我们只需查看out_vis_dir和result.txt即可。 ``` !mkdir ./data/textrecog/infer_results # 创建推理结果的保存路径 !python ./textrecog/infer.py \ ./data/textrecog/images_from_seg \ ./data/textrecog/infer_imgs_list.txt \ ./textrecog/water_meter_textrecog_config.py \ ./train_url/textrecog/latest.pth \ --out_dir=./data/textrecog/infer_results # 第1个参数: 推理的图片根目录 # 第2个参数: 图片根目录下的推理文件列表 # 第3个参数: 模型配置文件 # 第4个参数: 训练好的模型文件 # 第5个参数: 推理结果保存路径 ``` 推理结果可视化: ``` from util import show img_dir = './data/textrecog/infer_results/out_vis_dir' show(img_dir, show_num=5) ``` # 6.端到端识别 以上我们已经完成了水表识别的整个流程。现在我们将上述算法串联在一起,实现端到端的预测。输入数据为原始拍摄的图片。输出为水表的度数。 ## 6.1分割算法 与文本识别算法算法二选一。 如果文本检测部分使用的是分割算法,参考infer_end2end_with_seg.py脚本,模型路径,数据路径都配置在了该脚本中,可修改该脚本。 如果前面的模型或者数据有改动部分,该脚本请同步修改。 ``` !python infer_end2end_with_seg.py \ --num_classes=2 \ --img_path=./data/raw/test_imgs \ --out=./outputs_with_seg \ --detect_180=False # num_classes:类别数 # img_path:推理图片路径 # out:推理结果保存路径 # detect_180:如果训练了识别翻转的模型,设置detect_180=True即可,默认值为False ``` 推理结果可视化: ``` from util import show_pair img_dir = './data/raw/test_imgs' res_dir = './outputs_with_seg' show_pair(img_dir, res_dir, show_num=2) ``` ## 6.2文本识别算法 与分割算法算法二选一。 如果文本检测部分使用的是文本识别算法,参考infer_end2end_with_textdet.py脚本,模型路径,数据路径都配置在了该脚本中,可修改该脚本。 如果前面的模型或者数据有改动部分,该脚本请同步修改。 ``` !python infer_end2end_with_textdet.py \ --num_classes=2 \ --img_path=./data/raw/test_imgs \ --out=./outputs_with_textdet \ --detect_180=False # num_classes:类别数 # img_path:推理图片路径 # out:推理结果保存路径 # detect_180:如果训练了识别翻转的模型,设置detect_180=True即可,默认值为False ``` 推理结果可视化: ``` from util import show_pair img_dir = './data/raw/test_imgs' res_dir = './outputs_with_textdet' show_pair(img_dir, res_dir, show_num=2) ```
总条数:5192 到第
上滑加载中