大规模机器学习系统中的 No Free Lunch < 有个 AI 的大观前知 >

本贴最后更新于 2719 天前,其中的信息可能已经水流花落

5 月 18 日,由 CSDN 出品的 2017 中国云计算技术大会(简称 CCTC,Cloud Computing Technology Conference)在北京盛大召开,第四范式机器学习算法研发工程师涂威威出席人工智能专场并作主题演讲。

作为第四范式•先知平台核心机器学习框架 GDBT 的设计者,涂威威在大规模分布式机器学习系统架构、机器学习算法设计和应用等方面有深厚积累。演讲中,涂威威表示,现在有越来越多的企业开始利用机器学习技术,把数据转换成智能决策引擎。企业机器学习应用系统中的核心模型训练系统有着什么样的设计和优化的考虑?与教科书中的机器学习应用相比,企业实际的机器学习应用中有哪些容易被人忽略的陷阱?涂威威对此作了经验分享,同时给出了一些可供参考的解决方案。

工业界大规模分布式机器学习计算框架的设计经验

机器学习的经典定义,是利用经验(数据)来改善系统性能。在应用过程中,首先要明确机器学习目标的定义,也就是用机器学习来做什么事情。以谷歌提升搜索广告业务收入为例,谷歌首先对提升收入的目标进行拆解,广告收入=平均单次点击价格点击率广告展现量,其中“广告展现量”被硬性控制(考虑到政策法规和用户体验),“单次点击价格”受广告主主动出价影响,与上面两者不同,“点击率”的目标明确,搜索引擎记录了大量的展现点击日志,而广告候选集很大,不同广告的点击率差别很大,谷歌广告平台有控制广告展现的自主权,因此对于谷歌提升搜索广告收入的问题而言,机器学习最适合用来优化“广告点击率”。在确定了机器学习具体的优化目标是广告点击率之后,谷歌机器学习系统会循环执行四个系统:数据收集 → 数据预处理 → 模型训练 → 模型服务(模型服务产生的数据会被下一个循环的数据收集系统收集)。在这四个系统中,与机器学习算法最相关的就是模型训练系统。

在涂威威看来,计算框架设计上,没有普适的最好框架,只有最适合实际计算问题的框架。

针对机器学习的兼顾开发效率和执行效率的大规模分布式并行计算框架

在工业应用中,有效数据、特征维度正在迅速攀升。在数据量方面,以往一个机器学习任务仅有几万个数据,如今一个业务的数据量已很容易达到千亿级别。在特征维度方面,传统的机器学习采用“抓大放小”的方式—只使用高频宏观特征,忽略包含大量信息的低频微观特征—进行训练,但随着算法、计算能力、数据收集能力的不断增强,更多的低频微观特征被加入到机器学习训练中,使模型的效果更加出色。

特征频率分布

机器学习技术也在工业应用中不断发展,最早期的机器学习工业应用只利用宏观特征、简单模型,到后来发展为两个不同的流派:以微软、雅虎为代表的只利用宏观特征但使用复杂模型流派,以谷歌为代表的使用简单模型但利用微观特征流派,到现在,利用更多微观特征以及复杂模型去更精细地刻画复杂关系已是大势所趋。这便对模型训练提出了更高的要求。

其一,训练系统需要分布式并行。由于功率墙(Power Wall,芯片密度不能无限增长)和延迟墙(Latency Wall,光速限制,芯片规模和时钟频率不能无限增长)的限制,摩尔定律正在慢慢失效,目前,提升计算能力的方式主要是依靠并行计算,从早期的以降低执行延迟为主到现在的以提升吞吐量为主。在模型训练的高性能计算要求下,单机在 IO、存储、计算方面的能力力不从心,机器学习模型训练系统需要分布式并行化。当然我们也需要牢记 Amdahl 定律。

Power Wall,功耗随着集成电路密度指数提升

其二,训练框架需要高开发效率。机器学习领域里,一个著名的定理叫 No Free Lunch[Wolpert and Macready 1997],是指任意算法(包括随机算法)在所有问题上的期望性能一样,不存在通用的算法,因此需要针对不同的实际问题,研发出不同的机器学习算法。这就需要机器学习计算框架的开发效率非常高。

典型的机器学习建模过程

其三,训练系统需要高执行效率。在面对实际问题时,需要对数据、特征表达、模型、模型参数等进行多种尝试,且每一次尝试,都需要单独做模型训练。所以,模型训练是整个机器学习建模过程中被重复执行最多的模块,执行效率也就成为了重中之重。

机器学习核心系统对计算资源的需求对比

其四,底层框架的 No Free Lunch。对于不同的计算问题,计算的模式和对各种计算资源的需求都是不一样的,因此没有在所有问题上最好的架构,只有最适合实际问题的架构。针对机器学习任务的特性进行框架设计才能更有效地解决大规模机器学习模型训练的计算问题。

开发效率的优化

在提高开发效率上,这里分享计算和编程模式的选择、编程语言的选择两个方面。

并行计算范式分为两种,一种是基于共享内存的并行计算范式,不同的计算节点共享同一块内存,这里底层需要处理访存冲突等问题,这种模式一般被用在小规模处理器的情况,比如单机多处理器;另外一种是基于消息传递的并行计算范式,每个计算节点使用自己的内存,计算节点之间通过消息传递的模式进行并行计算。在实际的分布式并行系统中,多机器之间一般基于消息传递,单机内部一般基于共享内存(也有一些系统基于消息传递)。

机器学习的分布式模式,又分为数据分布式和模型分布式。数据分布式是指将训练数据切成很多份,不同的机器处理一部分数据。但对于一些较大的模型,单机可能没有办法完成整个模型的运算,于是把模型切成很多份,不同机器计算模型的不同部分。在实际应用过程中,根据不同的场景需要,二者一般是并存的。

数据分布式和模型分布式

机器学习模型训练中常见的分布式并行计算模型

最常见的就是分布式数据流计算模型。数据流模型是一种数据驱动的并行计算执行模型。数据流计算逻辑基于数据流图表达。 用户通过描述一个计算流图来完成计算,对计算流图中的计算节点进行定义,用户一般不需要指定具体执行流程。数据流图内部不同数据的计算一般是异步完成的,其中的计算节点只要上游 ready 就可以执行计算逻辑。目前主流的 ETL(Extract-Transform-Load)数据处理框架比如 Hadoop、Spark、Flink 等都是基于数据流计算模型。但是机器学习计算任务有一个共享的不断被擦写的中间状态:模型参数,计算过程会不断的读写中间状态。数据流的计算模型在执行过程中一般是异步的,所以很难对共享中间状态——模型参数,进行很好的一致性控制。所以基于数据流计算模型的一致性模型一般都是同步的,在数据流内部保证强一致性,但是基于同步的系统执行性能取决于最慢的计算节点,计算效率比较低。

数据流计算模型中的模型参数困惑

另一个常见的分布式并行计算模型就是基于参数服务器的分布式计算模型。参数服务器就是对机器学习模型训练计算中的共享状态——模型参数管理的一种直观的抽象,对模型参数的读写由统一的参数服务器管理,参数服务器本质上就是一个支持多种一致性模型的高性能 Key-Value 存储服务。基于参数服务器可以实现不同的一致性模型,一个极端就是 BSP(Bulk Synchronous Parallel,同步并行),所有的计算节点在计算过程中都获取一致的模型参数,对于算法实现而言有一致性的保障,但是代价是同步造成的资源浪费;另一个极端是 ASP(Asynchronous Parallel,异步并行),所有的计算节点在计算过程中彼此之间的模型参数没有任何的一致性保证,计算节点之间完全异步执行,这种一致性模型计算效率很高,但是模型参数没有一致性保证,不同节点获取到的是不同版本的模型,训练过程不稳定,影响算法效果;CMU 的 Erix Xing 教授提出了介于 BSP 和 ASP 两者之间的 SSP(Stale Synchronous Parallel),通过限制最大不一致的参数版本数来控制整体的同步节奏,这样既能缓解由于同步带来的执行效率问题,又使得算法相对于 ASP 在收敛性质上有更好的保证。基于不同的一致性模型可以很好地在运行速度和算法效果上进行权衡。

其实,数据流计算模型和参数服务器计算模型刻画了机器学习模型训练计算过程的不同方面,机器学习的样本数据的流动用数据流来描述就很自然,模型训练过程中的中间状态可以被参数服务器计算模型自然的描述。因此,这两者进行结合是整体的发展趋势:在数据流中对参数服务器进行读写操作,比如 Intel 就开发了 Spark 上的参数服务器。但是数据流计算模型和参数服务器计算模型的一致性模型不尽相同,参数服务器的一致性模型比如 BSP 或者 SSP 都会打破数据流原有的异步计算逻辑。参数服务器和数据流结合的灾备策略和一致性管理策略需要仔细的设计才能很好地统一和融合。

数据流和参数服务器结合的架构

编程模型和编程语言的选择

编程范式可以分为两种,命令式与声明式。命令式编程通过显式指定具体执行流程来进行编程,常见的命令式语言是 C/C++ 等;与命令式编程不同,声明式编程不显示指定具体执行流程,只定义描述计算任务目标,将具体执行交由底层计算框架决定。命令式编程由于显式指定具体执行流程会显得更加灵活,而声明式编程底层计算框架可以针对执行流程进行更深入的优化从而可能会更加高效。在实际的机器学习模型训练计算框架中,两者其实一般是并存的,比如 MxNet、Tensorflow 等。

求和运算的命令式实现和声明式实现比较

为了兼顾运行效率和易用性,机器学习模型训练计算框架的编程语言的选择一般采用前后端分离的方式:以 C/C++、Java/Scala 等作为后端以保证系统运行效率,使用 Python、R 等作为前端以提供更为易用的编程接口。对于后端语言的选择上,主流的就是 Java 和 C++,这两者各有优劣:

在生态上,Java 由于易于开发使得其生态要远远好于 C++,很多大数据计算框架都基于 Java 或者类 Java 语言开发;

在可移植性上,由于 JVM 屏蔽了很多底层差异性,所以 Java 要优于 C++;

在内存管理上,基于 GC 的 Java 在大数据、同步分布式并行的情况下,效率要远低于优化过的 C++ 的效率,因为大数据情况下,GC 的概率会很高,而一旦一台服务器开始 GC 其计算能力将受很大影响,整体集群尤其在同步情况下的计算效率也会大打折扣,而机器数增加的情况下,在一定时刻触发 GC 的概率也会大大增加;

在语言抽象上,C++ 的模板机制在编译时刻进行展开,可以做更多的编译优化,在实际执行时除了产生的程序文件更大一些之外,整体执行效率非常高,而与之对应的 Java 泛型采用类型擦除方式实现,在实际运行时做数据类型 cast,会带来很多额外的开销,使得其整体执行效率受到很大影响。

在实际机器学习模型训练系统的设计上,具体的选择取决于框架设计者的偏好和实际问题(比如系统部署要求、开发代价等)的需求。

执行效率的优化

执行效率优化方面主要举例分享计算、存储、通讯、容错四个方面的优化。

在计算方面,最重要的优化点就是均衡。均衡不仅包括不同的机器、不同的计算线程之间的负载均衡,还包括算术逻辑运算资源、存储资源、通讯资源等等各种与计算有关资源之间的均衡,其最终目的是最大化所有计算资源的利用率。在实际的优化过程中,需要仔细地对程序进行 Profiling,然后找出可能的性能瓶颈,针对性能瓶颈进行优化,解决瓶颈问题,但是这时候性能瓶颈可能会转移,就要继续迭代:Profiling→ 发现瓶颈 → 解决瓶颈。

典型的计算性能优化循环

CPU 和 GPU 的架构对比

分布式计算是有代价的,比如序列化代价、网络通讯代价等等,并不是所有的任务都需要分布式执行,有些情况下任务或者任务的某些部分可以很好地被单机执行,不要为了分布式而分布式。为了得到更好的计算性能,需要对单机和分布式进行分离优化。

CPU、GPU、FPGA 等不同硬件有各自的优势,比如 CPU 适合复杂指令,有分支预测,大缓存,适合任务并行;GPU 有大量的算术逻辑运算单元,但缓存较小,没有分支预测,适合粗粒度数据并行,但不适合复杂指令执行,可以用来加速比如矩阵运算等粗粒度并行的计算任务;FPGA 对于特定的计算任务,比如深度学习预测,经过优化后有着介于 CPU 和 GPU 之间的峰值,同时功耗远低于 GPU 芯片。针对机器学习任务需要进行合理的任务调度,充分发挥不同计算硬件的优势,提升计算硬件的利用率。

近些年 CPU、GPU 等计算硬件的效率提升速度远高于主存性能的提升速度,所以计算和存储上的性能差距在不断扩大,形成了“存储墙”(Memory Wall),因此在很多问题上,存储优化更为重要。在存储方面,从 CPU 的寄存器到 L1、L2 等高速缓存,再到 CPU 本地内存,再到其他 CPU 内存,还有外存等有着复杂的存储结构和不同的存储硬件,访问效率也有着量级的差距。Jeff Dean 建议编程人员牢记不同存储硬件的性能数据。

存储层级架构、性能数据和存储墙

针对存储的层次结构和各个层级存储硬件的性能特性,可以采取数据本地化及访存模式等存储优化的策略。因为机器学习是迭代的,可以将一些训练数据或者一些中间计算结果放在本地,再次训练时,无需请求远端的数据;另外在单机情况下,也可以尝试不同的内存分配策略,调整计算模式,增强数据本地化。在访存模式优化方面,也可以进行很多优化:数据访问重新排序,比如 GPU 中纹理渲染和矩阵乘法运算中常见的 Z 秩序曲线优化;调整数据布局,比如可以采用更紧致的数据结构,提升顺序访存的缓存命中率,同时,在多线程场景下,尽量避免线程之间频繁竞争申请释放内存,会竞争同一把锁。除此之外还可以将冷热数据进行分离,提升缓存命中率;数据预取,比如可以用另外一根线程提前预取数据到更快的存储中,提升后续计算的访存效率。

通信是分布式机器学习计算系统中至关重要的部分。通讯包括点对点通讯和组通讯(如 AllReduce、AllGather 等)。可通过软件优化、硬件优化的形式提高执行效率。

在软件优化方面,可以通过比如序列化框架优化、通讯压缩、应用层优化的方式进行优化:

通讯依赖于序列化,通用序列化框架比如 ProtoBuffer、Thrift 等,为了通用性、一些前后兼容性和跨语言考虑等会牺牲一定的效率,针对特定的通讯场景可以设计更加简单的序列化框架,提升序列化效率。

在带宽成为瓶颈时,可以考虑使用 CPU 兑换带宽的方式,比如利用压缩技术来降低带宽压力。

更重要的优化来自于考虑应用层通讯模式,可以做更多的优化:比如参数服务器的客户端,可以将同一台机器中多个线程的请求进行请求合并,因为同一次机器学习训练过程中,不同线程之间大概率会有很多重复的模型参数请求;或者根据参数服务器不同的一致性模型,可以做请求缓存,提升查询效率,降低带宽;或者对于不同的网络拓扑,可以采取不同的组通讯实现方式。

除了软件优化之外,通讯架构需要充分利用硬件特性,利用硬件来提升网络吞吐、降低网络延迟,比如可以配置多网卡建立冗余链路提升网络吞吐,或者部署 Infiniband 提升网络吞吐、降低网络延迟等。

在容错方面,对于不同的系统,容错策略之间核心的区别就在于选择最适合的 Tradeoff。这里的 Tradeoff 是指每次失败后恢复任务所需要付出的代价和为了降低这个代价所付出的 overhead 之间的权衡。在选择机器学习模型训练系统的容错策略时,需要考虑机器学习模型训练任务的特点:首先机器学习模型训练是一个迭代式的计算任务,中间状态较多;其次机器学习模型训练系统中模型参数是最重要的状态;最后,机器学习模型训练不一定需要强一致性。

在业界常见的有 Data Lineage 和 Checkpointing 两种机器学习训练任务灾备方案。Data Lineage 通过记录数据的来源,简化了对数据来源的追踪,一旦数据发生错误或者丢失,可以根据 Data Lineage 找到之前的数据利用重复计算进行数据恢复,常见的开源项目 Spark 就使用这种灾备方案。Data Lineage 的粒度可大可小,同时需要一个比较可靠的维护 Data Lineage 的服务,总体 overhead 较大,对于机器学习模型训练中的共享状态——模型参数不一定是很好的灾备方式,因为模型参数是共享的有着非常多的中间状态,每个中间状态都依赖于之前版本的模型参数和中间所有数据的计算;与 Data Lineage 不同,机器学习模型训练系统中的 Checkpointing 策略,一般会重点关注对机器学习模型参数的灾备,由于机器学习是迭代式的,可以利用这一点,在满足机器学习一致性模型的情况下,在单次或多次迭代之间或者迭代内对机器学习模型参数以及训练进度进行灾备,这样在发生故障的情况下,可以从上一次迭代的模型 checkpoint 开始,进行下一轮迭代。相比于 Data Lineage,机器学习模型训练系统对模型参数和模型训练进度进行 Checkpointing 灾备是更加自然和合适的,所以目前主流的专门针对机器学习设计的计算框架比如 Tensorflow、Mxnet 等都是采用 Checkpointing 灾备策略。

除了上述的容错方式之外,还可以使用传统灾备常用的部署冗余系统来进行灾备,根据灾备系统的在线情况,可以分为冷、温和热备份方式,实际应用中可以根据实际的资源和计算性能要求选择最合适实际问题的冗余容错方式。

机器学习实际应用的常见陷阱

在实际的机器学习应用中,经常会遇到一些容易被忽视的陷阱。这里举例分享一些常见的陷阱:一致性、开放世界、依赖管理、可理解性/可调试性。

一致性陷阱

一致性陷阱是最常见的容易被忽视的陷阱。

首先训练/预估一致性问题是最常见的,其中包括特征表达不一致以及目标含义不一致。特征表达不一致较为常见,起因也有很多:表达方式不一是比较常见的,比如在训练数据中 0 代表男,1 代表女,可是在预估数据中 1 代表女,0 代表男;训练和评估特征提取中,某一方或者两方都出现了逻辑错误,会导致不一致;有一种比较隐秘的不一致叫“穿越”,尤其在时序数据上特别容易发生,“穿越”就是指特征里包含了违反时序或者因果逻辑的信息,比如有特征是在整个训练数据集中取该特征时正负例的个数/比例,这里其实隐含使用到了样本的标注信息,但是实际在预估过程中是不可能提前拿到标注信息的(否则就不需要预估了);又比如某些特征使用了当前样本时间点之后的信息,但是这在实际的预估中是做不到的,因为目前还无法穿越到未来。还有一种不一致性是目标含义的不一致性,比如目标是优化搜索结果的用户满意度,但是却用用户点击作为机器学习的目标,用户点击了某个搜索结果不代表用户对这个结果满意。

另外一种容易被忽视的一致性是字段含义会随着时间的推移会发生变化。

在实际应用中需要重点关注一致性测试,留意特征的具体物理含义,避免出现特征表达不一致、目标含义不一致、随时间变化的不一致的问题。

开放世界陷阱

机器学习系统被应用到实际业务中去时,面对的就是一个开放世界,机器学习系统不再是一个静态孤立的系统,而是需要跟外部世界打交道,这里就有很多的陷阱。其中有一个非常著名的幸存者偏差问题,因为当前的模型会影响下一次模型的训练数据,如果不做干涉,那么训练数据是有偏差的。这个偏差最著名的起源来自二战期间,科学家团队研究如何对飞机加固来提升飞机在战场的存活率,他们找来了战场上存活下来的飞机上的弹孔进行分析,最后得出结论:腹部中弹最多,所以需要在腹部进行加固,可提高存活率。但是,统计学家 Abraham Wald 指出他们忽略了那些被摧毁的飞机,因为它们被击中了机翼、引擎等关键部位,所以可能更好地保护机翼、引擎等关键部位才能提升飞机在战场上的存活率。在推荐系统、搜索引擎等系统中这样的问题是非常常见的,用户看到的结果是基于机器学习模型推荐出来的,而这些结果又会成为下一次机器学习模型训练的数据,但是这些数据是有模型偏置的。本质上这是一个 Exploitation 和 Exploration 上权衡的问题,需要以长期效果为目标,解决这样的问题可以参考强化学习中的解决方案。除了幸存者偏差陷阱之外,机器学习系统在实际业务系统中也可能会与其他系统进行配合,机器学习系统的输出会随着数据而发生变化,但是如果与之配合的系统中依赖机器学习系统输出的参数比如阈值等却固定不变,就可能会影响整个系统的效果。实际应用中需要监控机器学习系统的输出分布和对其他系统的影响,可采取比如预估分布矫正等策略。

依赖陷阱

不谨慎的依赖容易导致非常灾难性的结果,但是在实际应用中往往会被忽视。常见的依赖有:

数据依赖:与传统软件系统不同,机器学习系统的表现依赖于外部数据。而数据依赖相比于代码依赖会更加可怕,因为很多情况下是隐式的很难察觉或分析。

在大公司中经常发生的情况是模型之间的依赖,在解决某个业务问题时,建立了机器学习模型 B,为了图快,依赖了其他团队模型 A 的输出,但是如果依赖的团队升级了模型 A,那么对于 B 而言将会是灾难性的。

除了数据依赖和模型之间的依赖之外,更难被察觉的是隐性依赖,可能会有一些特征字段会被模型自己改变,比如推荐系统中“用户点击推荐文章的次数”这个特征会随着推荐模型的升级而发生改变。

实际应用中要密切关注数据依赖,尽量避免产生模型之间的依赖,避免出现隐性依赖。

可理解性/可调试性陷阱

可理解性/可调试性最容易被大家忽略。在实际的业务应用中,经常为了追求效果可能会采用非常复杂的模型,然后这个模型可能很难理解,也很难调试。

对于一些业务,比如医疗应用、银行审计等都会需要模型的可理解性。对于可理解性,一种常见的解决方法是说做模型转换,比如说像周志华教授提出的 Twice Learning 方法,可以把一个非常复杂的应用模型,通过 Twice Learning 的方式转换成一个性能相近的决策树模型,而决策树模型是一个比较容易理解的模型。还有一种做法就是对模型的预测结果给出解释,比如最新的工作 LIME 借用类似 Twice Learning 的思想,在局部区域内用可理解模型对复杂模型进行解释。

可调试性对于实际应用是非常重要的,因为模型几乎不可能 100% 正确,而为了追求业务效果,容易采用非常复杂的特征和模型,但是在复杂模型和特征情况下没发生了 bad case,或者想要提升模型性能,会很难分析,导致模型很难提升,不利于后续的发展,所以在实际的业务中需要选择适合实际问题和团队能力的特征、模型复杂度。

[Twice Learnig 和 LIME]

总结

机器学习利用数据改善系统性能,是一种数据驱动的实现人工智能的方式,已经被广泛应用在各行各业。随着实际业务数据量和数据维度的增长,计算能力的不断提升,机器学习算法的持续优化,工业应用中的机器学习正在从早期的简单模型宏观特征转变到现在的复杂模型微观特征,这样的转变为机器学习训练系统的设计与优化带来了新的挑战。

机器学习应用的核心系统包括数据收集、数据预处理、模型训练和模型服务,每个系统对计算、存储、通讯和一致性的要求都不一样。对于模型训练系统而言,由于摩尔定律失效,实际业务整体的数据量和数据维度持续不断的增长,机器学习算法的 No Free Lunch 定理,实际建模过程中频繁尝试的需要,计算框架的 No Free Lunch,实际的机器学习系统需要一个专门针对机器学习设计的兼顾开发效率和执行效率的分布式并行计算框架。这次分享首先对解决开发效率中的计算和编程模型的选择,编程语言的选择做了介绍,开发者需要根据自己实际的应用场景、开发成本和团队能力等去做权衡和选择。然后又举例介绍了解决执行效率中涉及到的计算、存储、通讯和容错的设计和优化。持续 Profiling,迭代消除瓶颈,均衡利用好各种计算资源,尽可能最大化各类计算资源的利用率,从而提升整体执行效率。

机器学习被应用到实际的业务中会有很多容易被忽视的陷阱。这次分享对其中常见的各种类型的一致性陷阱、机器学习面对开放世界中的陷阱、机器学习系统中各种依赖的陷阱以及容易被忽视的模型可理解性和可调试性做了简单的介绍,同时给出了一些可供参考的解决方案。在实际的机器学习应用中需要尽量避免踏入这些陷阱。

转载自:36 大数据

  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3186 引用 • 8212 回帖 • 1 关注
  • 人工智能

    人工智能(Artificial Intelligence)是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门技术科学。

    132 引用 • 188 回帖
  • 机器学习

    机器学习(Machine Learning)是一门多领域交叉学科,涉及概率论、统计学、逼近论、凸分析、算法复杂度理论等多门学科。专门研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能。

    83 引用 • 37 回帖 • 1 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
c3gen
羡慕有什么用,你又不努力! 武汉

推荐标签 标签

  • IPFS

    IPFS(InterPlanetary File System,星际文件系统)是永久的、去中心化保存和共享文件的方法,这是一种内容可寻址、版本化、点对点超媒体的分布式协议。请浏览 IPFS 入门笔记了解更多细节。

    21 引用 • 245 回帖 • 248 关注
  • React

    React 是 Facebook 开源的一个用于构建 UI 的 JavaScript 库。

    192 引用 • 291 回帖 • 402 关注
  • 持续集成

    持续集成(Continuous Integration)是一种软件开发实践,即团队开发成员经常集成他们的工作,通过每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误。

    15 引用 • 7 回帖
  • Love2D

    Love2D 是一个开源的, 跨平台的 2D 游戏引擎。使用纯 Lua 脚本来进行游戏开发。目前支持的平台有 Windows, Mac OS X, Linux, Android 和 iOS。

    14 引用 • 53 回帖 • 527 关注
  • BookxNote

    BookxNote 是一款全新的电子书学习工具,助力您的学习与思考,让您的大脑更高效的记忆。

    笔记整理交给我,一心只读圣贤书。

    1 引用 • 1 回帖
  • Sym

    Sym 是一款用 Java 实现的现代化社区(论坛/BBS/社交网络/博客)系统平台。

    下一代的社区系统,为未来而构建

    524 引用 • 4600 回帖 • 701 关注
  • Git

    Git 是 Linux Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。

    209 引用 • 358 回帖
  • Sillot

    Insights(注意当前设置 master 为默认分支)

    汐洛彖夲肜矩阵(Sillot T☳Converbenk Matrix),致力于服务智慧新彖乄,具有彖乄驱动、极致优雅、开发者友好的特点。其中汐洛绞架(Sillot-Gibbet)基于自思源笔记(siyuan-note),前身是思源笔记汐洛版(更早是思源笔记汐洛分支),是智慧新录乄终端(多端融合,移动端优先)。

    主仓库地址:Hi-Windom/Sillot

    文档地址:sillot.db.sc.cn

    注意事项:

    1. ⚠️ 汐洛仍在早期开发阶段,尚不稳定
    2. ⚠️ 汐洛并非面向普通用户设计,使用前请了解风险
    3. ⚠️ 汐洛绞架基于思源笔记,开发者尽最大努力与思源笔记保持兼容,但无法实现 100% 兼容
    29 引用 • 25 回帖 • 79 关注
  • FlowUs

    FlowUs.息流 个人及团队的新一代生产力工具。

    让复杂的信息管理更轻松、自由、充满创意。

    1 引用
  • JWT

    JWT(JSON Web Token)是一种用于双方之间传递信息的简洁的、安全的表述性声明规范。JWT 作为一个开放的标准(RFC 7519),定义了一种简洁的,自包含的方法用于通信双方之间以 JSON 的形式安全的传递信息。

    20 引用 • 15 回帖 • 6 关注
  • 职场

    找到自己的位置,萌新烦恼少。

    127 引用 • 1705 回帖
  • MongoDB

    MongoDB(来自于英文单词“Humongous”,中文含义为“庞大”)是一个基于分布式文件存储的数据库,由 C++ 语言编写。旨在为应用提供可扩展的高性能数据存储解决方案。MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似 JSON 的 BSON 格式,因此可以存储比较复杂的数据类型。

    90 引用 • 59 回帖 • 4 关注
  • Typecho

    Typecho 是一款博客程序,它在 GPLv2 许可证下发行,基于 PHP 构建,可以运行在各种平台上,支持多种数据库(MySQL、PostgreSQL、SQLite)。

    12 引用 • 65 回帖 • 453 关注
  • 支付宝

    支付宝是全球领先的独立第三方支付平台,致力于为广大用户提供安全快速的电子支付/网上支付/安全支付/手机支付体验,及转账收款/水电煤缴费/信用卡还款/AA 收款等生活服务应用。

    29 引用 • 347 回帖
  • Unity

    Unity 是由 Unity Technologies 开发的一个让开发者可以轻松创建诸如 2D、3D 多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

    25 引用 • 7 回帖 • 186 关注
  • 小薇

    小薇是一个用 Java 写的 QQ 聊天机器人 Web 服务,可以用于社群互动。

    由于 Smart QQ 从 2019 年 1 月 1 日起停止服务,所以该项目也已经停止维护了!

    34 引用 • 467 回帖 • 740 关注
  • Flutter

    Flutter 是谷歌的移动 UI 框架,可以快速在 iOS 和 Android 上构建高质量的原生用户界面。 Flutter 可以与现有的代码一起工作,它正在被越来越多的开发者和组织使用,并且 Flutter 是完全免费、开源的。

    39 引用 • 92 回帖 • 4 关注
  • 心情

    心是产生任何想法的源泉,心本体会陷入到对自己本体不能理解的状态中,因为心能产生任何想法,不能分出对错,不能分出自己。

    59 引用 • 369 回帖 • 1 关注
  • Sphinx

    Sphinx 是一个基于 SQL 的全文检索引擎,可以结合 MySQL、PostgreSQL 做全文搜索,它可以提供比数据库本身更专业的搜索功能,使得应用程序更容易实现专业化的全文检索。

    1 引用 • 207 关注
  • GraphQL

    GraphQL 是一个用于 API 的查询语言,是一个使用基于类型系统来执行查询的服务端运行时(类型系统由你的数据定义)。GraphQL 并没有和任何特定数据库或者存储引擎绑定,而是依靠你现有的代码和数据支撑。

    4 引用 • 3 回帖 • 8 关注
  • 反馈

    Communication channel for makers and users.

    123 引用 • 911 回帖 • 237 关注
  • 强迫症

    强迫症(OCD)属于焦虑障碍的一种类型,是一组以强迫思维和强迫行为为主要临床表现的神经精神疾病,其特点为有意识的强迫和反强迫并存,一些毫无意义、甚至违背自己意愿的想法或冲动反反复复侵入患者的日常生活。

    15 引用 • 161 回帖 • 2 关注
  • Tomcat

    Tomcat 最早是由 Sun Microsystems 开发的一个 Servlet 容器,在 1999 年被捐献给 ASF(Apache Software Foundation),隶属于 Jakarta 项目,现在已经独立为一个顶级项目。Tomcat 主要实现了 JavaEE 中的 Servlet、JSP 规范,同时也提供 HTTP 服务,是市场上非常流行的 Java Web 容器。

    162 引用 • 529 回帖 • 4 关注
  • Hadoop

    Hadoop 是由 Apache 基金会所开发的一个分布式系统基础架构。用户可以在不了解分布式底层细节的情况下,开发分布式程序。充分利用集群的威力进行高速运算和存储。

    86 引用 • 122 回帖 • 616 关注
  • 单点登录

    单点登录(Single Sign On)是目前比较流行的企业业务整合的解决方案之一。SSO 的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。

    9 引用 • 25 回帖
  • 锤子科技

    锤子科技(Smartisan)成立于 2012 年 5 月,是一家制造移动互联网终端设备的公司,公司的使命是用完美主义的工匠精神,打造用户体验一流的数码消费类产品(智能手机为主),改善人们的生活质量。

    4 引用 • 31 回帖
  • 互联网

    互联网(Internet),又称网际网络,或音译因特网、英特网。互联网始于 1969 年美国的阿帕网,是网络与网络之间所串连成的庞大网络,这些网络以一组通用的协议相连,形成逻辑上的单一巨大国际网络。

    98 引用 • 344 回帖