译用SQL统一所有一种有效的语法惯用的流和表管理方法

现在还没有一个统一的流式SQL语法标准,各家都在做自己的。本文在一些业界应用的基础上提出了一个统一SQL语法的建议。Spark同样存在这个问题,社区版本在流式SQL上迟迟没有动作。EMR Spark在今年上半年提供了自己设计版本的流式SQL支持,也会在后续的更新中吸收和支持这些优秀的设计建议。 原文:https://blog.acolyer.org/2019/07/03/one-sql-to-rule-them-all/ 资料:One SQL to rule them all: an efficient and syntactically idiomatic approach to management of streams and tables Begoli et al., SIGMOD’19 在数据处理方面,似乎最终都会回归到SQL上!今天选择的这篇文章作者来自于Apache Beam,Apache Calcite以及Apache Flink的专家们,阐述了他们在构建流式处理SQL接口的经验。最终整理了一些SQL标准的扩展建议。 The thesis of this paper, supported by experience developing large open-source frameworks supporting real-world streaming use cases, is that the SQL language and relational model as-is and with minor non-intrusive extensions, can be very effective for manipulation of streaming data.这篇文章的论点是,在开发使用大规模开源框架解决现实世界的实际流式场景经验下,SQL语言及关系性模型在当前及非侵入式扩展后,对于流数据的操作非常有效。 ...

July 16, 2019 · 2 min · jiezi

DLA-SQL技巧行列转换和JSON数据列展开

1. 简介在数据库SQL处理中,常常有行转列(Pivot)和列转行(Unpivot)的数据处理需求。本文以示例说明在Data Lake Analytics(https://www.aliyun.com/product/datalakeanalytics)中,如何使用SQL的一些技巧,达到行转列(Pivot)和列转行(Unpivot)的目的。另外,DLA支持函数式表达式的处理逻辑、丰富的JSON数据处理函数和UNNEST的SQL语法,结合这些功能,能够实现非常丰富、强大的SQL数据处理语义和能力,本文也以JSON数据列展开为示例,说明在DLA中使用这种SQL的技巧。 2. 行转列(Pivot)2.1 样例数据 test_pivot表内容: +------+----------+---------+--------+| id | username | subject | source |+------+----------+---------+--------+| 1 | 张三 | 语文 | 60 || 2 | 李四 | 数学 | 70 || 3 | 王五 | 英语 | 80 || 4 | 王五 | 数学 | 75 || 5 | 王五 | 语文 | 57 || 6 | 李四 | 语文 | 80 || 7 | 张三 | 英语 | 100 |+------+----------+---------+--------+2.2 方法一:通过CASE WHEN语句 ...

June 20, 2019 · 4 min · jiezi

阿里新一代分布式任务调度平台Schedulerx20破土而出

1. 产品简介Schedulerx2.0是阿里中间件自研的基于Akka架构的新一代分布式任务调度平台,提供定时、任务编排、分布式跑批等功能。使用Schedulerx2.0,您可以在控制台配置管理您的定时任务,查询历史执行记录,查看运行日志。借助Schedulerx2.0,您还可以通过工作流进行任务编排和数据传递。Schedulerx2.0还提供了简单易用的分布式编程模型,简单几行代码就可以将海量数据分布式到多台机器上执行。 Schedulerx2.0提供了任务调度与执行的一整套解决方案,在阿里巴巴集团内部广泛使用并久经考验,具有高可靠、海量任务、秒级别调度等能力。 上线时间:2019-04-30 2. 背景Schedulerx2.0是Schedulerx1.0(DTS)的下一代产品,采用全新的架构,是全新自研的下一代分布式任务调度平台,不但解决了老产品的性能瓶颈,还提供了更多更快更强的能力。 更多:支持多种时间表达式,任务编排,支持更多的业务场景。单集群支持上千万任务,一天上十亿次调度,支持更多的任务数。更快:支持秒级别调度,处理准实时业务。更强:支持日志查询、原地重跑、重刷数据等多种操作,提供更强的运维能力和排错手段,解决为什么没跑,为什么失败,为什么跑得慢等问题。3. 功能3.1 强大的定时调度器3.1.1 Crontab 支持unix crontab表达式,不支持秒级别。 3.1.2 Fixed rate 众所周知,crontab必须被60整除,比如想每隔40分钟跑一次,cron不支持。Fixed rate专门用来做定期轮询,表达式简单,不支持秒级别。 3.1.3 Fixed delay 适合对实时性要求比较高的业务,比如每次执行完成隔10秒再跑,那么second delay非常适合你。并且second delay能支持到秒级别。 3.1.4 日历 支持多种日历,还可以自定义导入日历。比如金融业务需要在每个交易日执行。 3.1.5 时区 跨国的业务,需要在每个国家的时区定时执行某个任务。 3.2 任务编排支持工作流(DAG)进行任务编排,操作简单,前端直接单手操作拖拖拽拽即可。详细的任务状态图能一目了然看到下游任务为什么没跑。 3.3 任务类型支持多种任务类型,可以无限扩展。 java:可以跑在用户进程中,也可以上传jar包动态加载。shell:前端直接写shell脚本。python:前端直接写python脚本,需要机器有python环境。go:前端直接写go脚本,需要机器有go环境。自定义:用户甚至可以自定义任务类型,然后实现一个plugin就行了。3.4 执行方式&分布式编程模型3.4.1 执行方式 单机:随机挑选一台机器执行广播:所有机器同时执行且等待全部结束并行计算:map/mapreduce模型,1~300个子任务,有子任务列表。内存网格:map/mapreduce模型,10W以下子任务,无子任务列表,基于内存计算,比网格计算快。网格计算:map/mapreduce模型,100W以下子任务,无子任务列表,基于文件H2计算。3.4.2 分布式编程模型 Map模型:类似于hadoop mapreduce里的map。只要实现一个map方法,简单几行代码就可以将海量数据分布式到客户自己的多台机器上执行,进行跑批。MapReduce模型:MapReduce模型是Map模型的扩展,新增reduce接口,所有子任务完成后会执行reduce方法,可以在reduce方法中返回该任务实例的执行结果,或者回调业务。3.5 强大的运维能力数据大盘:控制台提供了执行记录大盘和执行列表,可以看到每个任务的执行历史,并提供操作。查看日志:每条执行记录,都可以详情中的日志页面实时看到日志。如果任务运行失败了,前端直接就能看到错误日志,非常方便。原地重跑:任务失败,修改完代码发布后,可以点击原地重跑。标记成功:任务失败,如果后台把数据处理正确了,重跑又需要好几个小时,直接标记成功就好了。Kill:实现JobProcessor的kill()接口,你就可以在前端kill正在运行的任务,甚至子任务。3.6 数据时间Schedulerx2.0可以处理有数据状态的任务。创建任务的时候可以填数据偏移。比如一个任务是每天00:30运行,但是实际上要处理上一天的数据,就可以向前偏移一个小时。运行时间不变,执行的时候通过context.getDataTime()获得的就是前一天23:30。 3.7 重刷数据既然任务具有了数据时间,一定少不了重刷数据。比如一个任务/工作流最终产生一个报表,但是业务发生变更(新增一个字段),或者发现上一个月的数据都有错误,那么就需要重刷过去一个月的数据。 通过重刷数据功能,可以重刷某些任务/工作流的数据(只支持天级别),每个实例都是不同的数据时间。 3.8 失败自动重试实例失败自动重试:在任务管理的高级配置中,可以配置实例失败重试次数和重试间隔,比如重试3次,每次间隔30秒。如果重试3次仍旧失败,该实例状态才会变为失败,并发送报警。子任务失败自动重试:如果是分布式任务(并行计算/内网网格/网格计算),子任务也支持失败自动重试和重试间隔,同样可以通过任务管理的高级配置进行配置。3.9 支持原生Spring之前的老产品Schedulerx1.0(DTS)和spring的结合非常暴力,对bean的命名有强要求,经常遇到注入失败的问题。Schedulerx2.0支持原生spring语法,接入更加的方便。 3.10 报警监控失败报警超时报警报警方式:短信 本文作者:黄晓萌阅读原文 本文为云栖社区原创内容,未经允许不得转载。

April 24, 2019 · 1 min · jiezi

世界冠军之路:菜鸟车辆路径规划求解引擎研发历程

阿里妹导读:车辆路径规划问题(Vehicle Routing Problem, VRP)是物流领域最经典的优化问题之一,具有极大的学术研究意义和实际应用价值。菜鸟网络高级算法专家胡浩源带领仓配智能化算法团队经过两年的研发,逐步沉淀出了一套完善、强大的车辆路径规划求解引擎,为菜鸟内外部多项业务提供了技术支持。通过不断地对算法进行探索打磨,我们终于在车辆路径规划问题最权威的评测平台上打破了多项世界纪录,标志着菜鸟网络在此领域的技术研究已经进入世界前列。问题介绍车辆路径规划问题是运筹优化领域最经典的优化问题之一。在此问题中,有若干个客户对某种货物有一定量的需求,车辆可以从仓库取货之后配送到客户手中。客户点与仓库点组成了一个配送网络,车辆可以在此网络中移动从而完成配送任务。在求解此问题过程中,需要优化的决策变量为每个客户的配送任务应该分配到哪一辆车上,以及每辆车完成客户配送任务的先后顺序,优化目标为最小化使用的车辆数和车辆总行驶距离(通常情况下最小化车辆数为第一优化目标)。以i,j表示配送网络中的节点(i,j∈{0,1,2,…,N}), 其中0表示仓库点,其它表示客户点),以k表示车辆(k∈{1,2,…,K}),以[图片上传失败…(image-4ad9e3-1554866885896)]为决策变量,表示车辆k是否从i点行驶到j点。则标准的车辆路径规划问题可以使用以下数据规划的形式描述:其中,表达式(1)表示优化目标为最小化使用车辆数;表达式(2)表示每个点有且仅有一辆车负责配送其所需要的货物;表达式(3)表示每辆车最多负责一条配送线路;表达式(4)表示网络中的流量平衡条件;表达式(5)表示每辆车负责配送的货物不超过其承载能力限制;表达式(6)为防止孤立子环出现的约束条件。车辆路径规划问题在物流领域和生产领域的应用非常广泛。所以在实际应用中也出现了一些在标准问题的基础上增加了某些变化之后的变型问题。其中较为常见的包括:CVRP:Capacitated VRP, 限制配送车辆的承载体积、重量等。VRPTW:VRP with Time Windows, 客户对货物的送达时间有时间窗要求。VRPPD:VRP with Pickup and Delivery, 车辆在配送过程中可以一边揽收一边配送,在外卖O2O场景中比较常见。MDVRP: Multi-Depot VRP, 配送网络中有多个仓库,同样的货物可以在多个仓库取货。OVRP:Open VRP, 车辆完成配送任务之后不需要返回仓库。VRPB: VRP with backhauls, 车辆完成配送任务之后回程取货。以上各类问题之间的关系可以通过图1表示:经典求解算法车辆路径规划问题是典型的NP-hard问题,非常具有挑战性。同时因为其在实际应用的巨大价值,学术界和工业界对此类问题的优化算法的探索已经持续了几十年的时间。已有的经典求解算法可以分为精确解算法和启发式算法两大类。在精确解算法方面,最基本的方法为分支定界算法,虽然其能够从理论上保证在有限时间内获得最优解,但是在实际计算中存在计算耗时巨大的情况。为了提高求解效率,研究者们先后提出了多种Branch-and-Cut以及Branch-Cut-and-Price方法,大幅降低了算法的求解时间。但是对于实际应用中较大规模的问题而言(例如超过200个点的问题),精确解算法依然无法能够在合理的时间内完成计算。所以还有一大部分研究集中于启发式算法领域。启发式算法的思想为通过一系列启发式的规则来构造和改变解,从而逐步提升解的质量。对于VRP而言,较为经典的启发式算法为Clarke-Wright算法等。此外,经过不断的探索研究,元启发式算法被证明在求解VRP方面具有很好的效果和效率。一些经过精心设计的元启发式算法,例如模拟退火、禁忌搜索、遗传算法、蚁群算法、变邻域搜索、自适应大规模邻域搜索算法等在求解VRP上有着非常好的表现。菜鸟车辆路径规划引擎研发历程阶段一:核心基础算法研发在研发之初,菜鸟仓配智能化算法团队充分调研了VRP领域的相关学术论文和软件产品等,最终确定了以自适应大规模邻域搜索(Adaptive Large Neighborhood Search, ALNS)为核心算法进行算法引擎的建设。相对于其它算法,ALNS算法的优势包括:算法框架易于拓展,除了求解标准的VRP之外,还能够求解VRPPD,MDVRP等变型问题;相对于普通的Local Search类型的算法,ALNS在每一步搜索过程中能够探索更大的解空间;ALNS算法在搜索过程中能够自适应地选择合适的算子,从而对于不同类型的问题数据能够有比较稳定的良好求解结果;通过设计实现不同类型的算子,ALNS可以实现不同的搜索策略,从而便于算法的升级拓展。经典的ALNS算法的主流程如图2所示:如图2所示的ALNS算法的主要步骤为:使用一定的规则构造一个初始解(即Initial过程);基于算子的权重,选择此次迭代过程中使用的Ruin算子和Insert算子;对此次迭代的初始解执行Ruin操作,即将部分已经被车辆服务的客户点删除,使初始解成为一个不可行解;对步骤(3)获得的解执行Insert操作,即对于还没有被车辆服务的客户点,将其插入到解中,尽量获得一个可行解;基于优化目标函数评估步骤(4)获得的新的解,并根据一定的策略决定是否接受新解;判断是否达到终止条件。如果是,则终止计算,返回当前找到的最好解;否则,基于此轮计算中算子的表现,更新算子的权重,并返回到步骤(2)。以ALNS算法为核心,菜鸟仓配智能化算法团队完成了第一版VRP优化引擎的研发。对比测试结果表明其求解效果和效率显著优于jsprit等国际上流行的开源VRP Solver。在此基础上,菜鸟仓配智能化算法团队还对引擎进行了服务化,从而更方便地服务于公司内外部用户。阶段二:算法体系丰富与升级为了更好地服务于公司内外部用户,菜鸟仓配智能化算法团队不断对VRP优化引擎的核心算法组件进行了丰富与升级。主要体现在以下几个方面:1.完善功能:在原算法核心框架的基础上,增加了对Pickup and Delivery(车辆一边揽收一边派送)、Multi Trip(车辆多趟派送)等类型问题的支持;而且通过对实际业务问题的抽象,总结出了不同类型的优化目标方程(例如最小化阶梯定价的总成本、最小化配送时间等)以及约束条件(例如车辆行驶距离限制、车辆配送订单数限制、车辆跨区数限制等)。从而使求解引擎能够求解的问题更加全面广泛。2.丰富算子:为了提升引擎的求解效果和稳定性,菜鸟仓配智能化算法团队还在VRP求解引擎中增加了更加丰富的优化算子,例如不同类型的局部搜索算子(例如Two-Opt, Three-Opt, Cross-Exchange等)、不同类型的中间结果接受策略(例如Greedy, Simulated Annealing等)。3.提升效果:菜鸟仓配智能化算法团队还尝试了多种算法来提升引擎的求解效果,主要包括:Guided ejection search (GES):此算法通过不断尝试删减一辆车,并将此辆车服务的客户添加到其它车辆上,从而实现降低车辆的使用数。此算法在降低车辆数方面具有非常好的效果;Fast local search (FLS): 在搜索过程中,只搜索那些有希望改善当前解的的邻域空间,从而大幅降低搜索计算量,提升算法求解速度;Guided local serach (GLS): 在搜索过程中对局部最优解的某些特征施加惩罚项,从而改变搜索方向,避免陷入局部最优;Edge assembly crossover (EAX): 一种基于两个解生成一个新的解的方法,新生成的解能够很好的继承父代个体的空间结构;Branch-and-Price-Based Large Neighborhood Search:此算法将VRPTW问题分解为了Restricted Master Problem和Subproblem。其中在Restricted Master Problem中,基于一系列可行的路径,通过求解Set Partition问题来获得原问题的解;在Subproblem中,通过Tabu Search来搜索新的可行的路径;Path-Relink:此算法的核心思想为通过从initial solution到guiding solution的逐步移动,探索两个解之间的广阔的邻域,从而有可能发现更好的解;Hybrid Cluster and Heuristics:此算法是针对超大规模的问题而设计,首先通过合适的聚类算法对客户点进行聚类,从而将原问题分解为多个小规模的子问题,然后并行求解,最终将子问题的解组装成为原问题的解。阶段三:算法并行化升级对于大部分启发式算法而言,可以天然地通过并行化计算来提升搜索效率和效果,例如并行地计算评估多个相邻解的质量、向多个邻域方向进行搜索或者使用多种策略进行搜索等,甚至并行地使用多种算法进行搜索等。所以为了进一步提升VRP引擎的求解质量,菜鸟仓配智能化算法团队对VRP引擎进行了并行化升级。在此过程中,先后研发实现了三套并行化算法架构。Population IslandPopulation Island的算法架构如图3所示。在算法执行过程中,有若干个Island并行执行计算,每个Island独立地进行演化,其中各有一个Master和若干Worker,其中Worker负责具体的搜索任务的计算执行,Master负责任务的分配协调以及与其它Island之间的通信等。每隔一定的计算步数,各个Island的Master之间会相同通信,分享搜索过程中获得的知识,从而提升整体的搜索效率。Parallel MemeticParallel Memetic的算法架构如图4所示。整个算法可以分为两个阶段,第一个阶段的计算重点在于减少使用的车辆数(Delete Route),在此阶段中,若干个Worker并行计算,并每隔一定的步数相互通信分享信息。第一阶段结束之后,会获得若干中间结果,将这些结果作为第二阶段中每个Worker上的初始演化种群进行计算。第二阶段的计算重点在于降低车辆行驶距离(Reduce Distance),第二阶段的Worker之间同样有相互通信分享知识的机制,而且可以通过控制演化过程中父代个体的选择机制来进行动态地调节Exploration与Exploitation。Central PoolCentral Pool的算法架构如图5所示。在算法中有若干个Worker负责具体的搜索任务,并将搜索得到的解返回到Central Pool中,由Central Manager对解进行排序、筛选、聚类等处理,然后Central Manager会依据当前Central Pool中的解集情况生成新的计算任务并发送给Worker执行。Central Manager可以对解空间进行合理的刻画,并通过计算任务的管控分配在Exploration与Exploitation之间进行平衡,从而提升求解效率。已获得成果通过对优化算法的不断迭代升级,以及在工程架构上的更新完善,菜鸟网络的车辆路径规划引擎在服务内外部客户的同时也在技术沉淀上获得了重大成果。在VRP算法领域,最权威的评测对比平台为欧洲独立研究机构SINTEF发起并管理的世界最好解榜单(Best Known Solution),其中包括了对Solomon数据集(1987年提出)和Gehring & Homberger数据集(1999年提出)共356份测试数据的世界纪录。全世界最顶尖的优化算法学者(例如Jakub Nalepa, D. Pisinger, Yuichi Nagata等)以及优化技术公司(例如Quintiq等)都不断地在此平台上刷新世界纪录,将车辆路径规划领域的技术逐渐地推向极致。菜鸟网络仓配智能化算法团队在算法研发过程中也一直以此数据集为主要算法评估指标。随着算法的不断升级优化,在越来越多的数据上接近甚至持平世界纪录。最终,在2018年9月,仓配智能化算法团队的算法终于获得了比世界纪录更好的结果,并经过了平台的验证,向全世界的研究者进行了公开。截止到2019年4月初,菜鸟网络在此评测数据集上共持有48项世界纪录,持有数量在众多研究团队中位居前列,这标志着菜鸟在这项领域的技术进入了世界顶尖水平,为菜鸟和集团赢得了巨大的技术影响力。总结及展望在历时两年的研发过程中,菜鸟仓配智能化算法团队的同学们付出了巨大的努力和心血。同时在这个过程中,集团多个事业部的兄弟团队在算法研究、工程技术等方面也提供了很多很好的专业建议,在此表示衷心的感谢!在之后的工作中,菜鸟仓配智能化算法团队将会把VRP引擎打造成为更强大、稳定、易用的优化产品,为菜鸟和集团的各项业务发展提供技术支持,并有计划地向外输出,为中国的物流行业赋能提效。本文作者:何柱、守初、本华阅读原文本文来自云栖社区合作伙伴“ 阿里技术”,如需转载请联系原作者。 ...

April 10, 2019 · 1 min · jiezi

GAN是一种特殊的损失函数?

摘要: 从本质上来说,生成对抗网络(GAN)是一种特殊的损失函数,我们来深入探索下这句话的含义。数据科学家Jeremy Howard在fast.ai的《生成对抗网络(GAN)》课程中曾经讲过这样一句话:“从本质上来说,生成对抗网络(GAN)是一种特殊的损失函数。”你是否能够理解这句话的意思?读完本文,你会更好的理解这句话的含义。神经网络的函数逼近理论在数学中,我们可以将函数看做一个“机器”或“黑匣子”,我们为这个“机器”或“黑匣子”提供了一个或多个数字作为输入,则会输出一个或多个数字,如下图所示:一般来说,我们可以用一个数学表达式来表示我们想要的函数。但是,在一些特殊的情况下,我们就没办法将函数写成一堆加法和乘法的明确组合,比如:我们希望拥有这样一个函数,即能够判断输入图像的类别是猫还是狗。如果不能用明确的用数学表达式来表达这个函数,那么,我们可以用某种方法近似表示吗?这个近似方法就是神经网络。通用近似定理表明,如果一个前馈神经网络具有线性输出层和至少一层隐藏层,只要给予网络足够数量的神经元,便可以表示任何一个函数。作为损失函数的神经网络现在,我们希望设计一个猫和狗的分类器。但我们没办法设计一个特别明确的分类函数,所以我们另辟蹊径,构建一个神经网络,然后一步一步逐渐实现这一目标。为了更好的逼近,神经网络需要知道距离目标到底还有多远。我们使用损失函数表示误差。现在,存在很多种类型的损失函数,使用哪种损失函数则取决于手头上的任务。并且,他们有一个共同的属性,即这些损失函数必须能够用精确的数学表达式来表示,如:1.L1损失函数(绝对误差):用于回归任务。2.L2损失函数(均方误差):和L1损失函数类似,但对异常值更加敏感。3.交叉熵损失函数:通常用于分类任务。4.Dice系数损失函数:用于分割任务。5.相对熵:又称KL散度,用于测量两个分布之间的差异。在构建一个性能良好的神经网络时,损失函数非常有用。正确深入的理解损失函数,并适时使用损失函数实现目标,是开发人员必备的技能之一。如何设计一个好的损失函数,也是一个异常活跃的研究领域。比如:《密度对象检测的焦点损失函数(Focal Loss)》中就设计了一种新的损失函数,称为焦点损失函数,可以处理人脸检测模型中的差异。可明确表示损失函数的一些限制上文提到的损失函数适用于分类、回归、分割等任务,但是如果模型的输出具有多模态分布,这些损失函数就派不上用场了。比如,对黑白图像进行着色处理。如上图所示:1.输入图像是个黑白鸟类图像,真实图像的颜色是蓝色。2.使用L2损失函数计算模型输出的彩色图像和蓝色真实图像之间的差异。3.接下来,我们有一张非常类似的黑白鸟类图像,其真实图像的颜色是红色。4.L2损失函数现在尝试着将模型输出的颜色和红色的差异最小化。5.根据L2损失函数的反馈,模型学习到:对于类似的鸟类,其输出可以接近红色,也可以接近蓝色,那么,到底应该怎么做呢?6.最后,模型输出鸟类的颜色为黄色,这就是处于红色和蓝色中间的颜色,并且是差异最小化的安全选择,即便是模型以前从未见过黄色的鸟,它也会这样做。7.但是,自然界中没有黄色的鸟类,所以模型的输出并不真实。在很多情况下,这种平均效果并不理想。举个例子来说,如果需要模型预测视频中下一个帧图像,下一个帧有很多种可能,你肯定希望模型输出其中一种可能,然如果使用L1或L2损失函数,模型会将所有可能性平均化,输出一个特别模型的平均图像,这就和我们的目标相悖。生成对抗网络——一种新的损失函数如果我们没办法用明确的数学表达式来表示这个损失函数,那么,我们就可以使用神经网络进行逼近,比如,函数接收一组数字,并输出狗的真实图像。神经网络需要使用损失函数来反馈当前结果如何,但是并没有哪个损失函数可以很好的实现这一目标。会不会有这样一种方法?能够直接逼近神经网络的损失函数,但是我们没必要知道其数学表达式是什么,这就像一个“机器”或“黑匣子”,就跟神经网络一样。也就是说,如果使用一个神经网络模型替换这个损失函数,这样可以吗?对,这就是生成对抗网络(GAN)。我们来看上面两个图,就可以更好的理解损失函数。在上图中,白色框表示输入,粉色和绿色框表示我们要构建的神经网络,蓝色表示损失函数。在vanilla GAN中,只有一个损失函数,即判别器D,这本身就是一个特殊的神经网络。而在Alpha-GAN中,有3个损失函数,即输入数据的判别器D,编码潜在变量的潜在判别器C和传统的像素级L1损失函数。其中,D和C不是明确的损失函数,而是一种逼近,即一个神经网络。梯度如果使用损失函数训练生成网络(和Alpha-GAN网络中的编码器),那么,应该使用哪种损失函数来训练判别器呢?判别器的任务是区分实际数据分布和生成数据分布,使用监督的方式训练判别器比较容易,如二元交叉熵。由于判别器是生成器的损失韩式,这就意味着,判别器的二进制交叉熵损失函数产生的梯度也可以用来更新生成器。结论考虑到神经网络可以代替传统的损失函数,生成对抗网络就实现了这一目标。两个网络之间的相互作用,可以让神经网络执行一些以前无法实现的任务,比如生成逼真的图像等任务。本文作者:【方向】阅读原文本文为云栖社区原创内容,未经允许不得转载。

December 21, 2018 · 1 min · jiezi

做了2个多月的设计和编码,我梳理了Flutter动态化的方案对比及最佳实现

背景在端上为了提升App的灵活性, 快速解决万变的业务需求,开发者们探索了多种解决方案,如PhoneGap ,React Native ,Weex等,但在Flutter生态还没有好的解决方案。未来闲鱼都会基于Flutter 来跨端开发,如果突破发版周期,在不发版的情况下,完成业务需求,同时能兼容性能体验,无疑是更快的响应了业务需求。因此我们需要探索在Flutter生态下的动态化。方案选择借鉴Android 和Ios上的动态性方案,我们也思考了多种Flutter动态性方案。1.下载替换Flutter编译产物下载新的Flutter编译产物,替换 App 安装目录下的编译产物,来实现动态化,这在Android 端是可行的,但在Ios 端不可行。我们需要双端一体的解决方案,所以这不是最好选择。2.类似React Native 框架我们先来看看React Native 的架构React Native 要转为android(ios) 的原生组件,再进行渲染。用React Native的设计思路,把XML DSL转为Flutter 的原子widget组件,让Flutter 来渲染。技术上说是可行的,但这个成本很大,这会是一个庞大的工程,从投入产出比看,不是很好的选择3.页面动态组件框架由粗粒度的Widget组件动态拼装出页面,Native端已经有很多成熟的框架,如天猫的Tangram,淘宝的DinamicX,它在性能、动态性,开发周期上取得较好平衡。关键它能满足大部分的动态性需求,能解决问题。三种方案的比较图表如:根据实际动态性需求,从两端一致性,和性能,成本,动态性考虑,我们选择一个折中方案,页面动态组件的设计思路是一个不错的选择。页面动态组件框架在Flutter上使用粗力度的组件动态拼装来构建页面,需要一整套的前后端服务和工具。本文我们重点介绍前端界面渲染引擎过程。语法树的选择Native端的Tangram ,DinamicX等框架他们有个共同点,都是Xml或者Html 做为DSL。但是Flutter 是React Style语法。他自己的语法已经能很好的表达页面。无需要自定义的Xml 语法,自定义的逻辑表达式。用Flutter 源码做为DSL 能大大减轻开发,测试过程,不需要额外的工具支持。所以选择了Flutter 源码作为DSL,来实现动态化。如何解析DSLFlutter源码做为DSL,那我们需要对源码进行很好的解析和分析。Flutter analyzer给了我们一些思路,Flutter analyzer是一个代码风格检测工具。它使用package:analyzer来解析dart 源码,拿到ASTNode。看下Flutter analyze 源码结构,它使用了dart sdk 里面的 package:analyzerdart-sdk: analysis_server: analysis_server.dart handleRequest(Request request) analyzer: parseCompilationUnit() parseDartFile parseDirectives Flutter analyze 解析源码得到ASTNode过程。插件或者命令对analysis server发起请求,请求中带需要分析的文件path,和分析的类型,analysis_server经过使用 package:analyzer 获取 commilationUnit (ASTNode),再对astNode,经过computer分析,返回一个分析结果list。同样我们也可以把使用 package:analyzer 把源文件转换为commilationUnit (ASTNode),ASTNode是一个抽象语法树,抽象语法树(abstract syntax tree或者缩写为AST)是源代码的抽象语法结构的树状表现形式.所有利用抽象语法树能很好的解析dart 源码。解析渲染引擎下面重点介绍渲染模块架构图:1.源码解析过程1.AST树的结构如下面这段Flutter组件源码:import ‘package:flutter/material.dart’;class FollowedTopicCard extends StatelessWidget { @override Widget build(BuildContext context) { return new Container( padding: const EdgeInsets.fromLTRB(12.0, 8.0, 12.0, 0.0), child: new InkWell( child: new Center( child: const Text(‘Plugin example app’), ), onTap: () {}, ), ); }}它的AST结构:从AST结构看,他是有规律的.2.AST 到widget Node我们拿到了ASTNode,但ASTNode 和widget node tree 完全是两个不一样的概念,需要递归ASTNode 转化为 widget node tree.widget Node 需要的元素用Name 来记录是什么类型的widgetwidget的arguments放在 map里面widget 的literals 放在list 里面widget 的children 放在lsit 里面widget 的触发事件 函数map里面widget node 加fromjson ,tojson 方法可以在递归astNode tree 时候,识别InstanceCreationExpression来创建一个widget node。2.组件数据渲染框架sdk 中注册支持的组件,组件包括:a.原子组件:Flutter sdk 中的 Flutter 的widgetb.本地组件:本地写好到一个大颗粒的组件,卡片widget组件c.逻辑组件:本地包装了逻辑的widget组件d.动态组件:通过源码dsl动态渲染的widget具体代码如下: const Map<String, CreateDynamicApi> allWidget = <String, CreateDynamicApi>{ ‘Container’: wrapContainer, ………….} static Widget wrapContainer(Map<String, dynamic> pars) { return new Container( padding: pars[‘padding’], color: pars[‘color’], child: pars[‘child’], decoration: pars[‘decoration’], width: pars[‘width’], height: pars[‘height’], alignment: pars[‘alignment’] );}一般我们通过网络请求拿到的数据是一个map。比如源码中写了这么一个 ‘${data.urls[1]}‘AST 解析时候,拿到这么一个string,或者AST 表达式,通过解析它 ,肯定能从map 中拿到对应的值。3.逻辑和事件a.支持逻辑Flutter 概念万物都是widget ,可以把表达式,逻辑封装成一个自定义widget。如果在源码里面写了if else,变量等,会加重sdk解析的过程。所以把逻辑封装到widget中。这些逻辑widget,当作组件当成框架组件。b.支持事件把页面跳转,弹框,等服务,注册在sdk里面。约定使用者仅限sdk 的服务。4.规则和检测工具a.检测规则需要对源码的格式制定规则。比如不支持 直接写if else ,需要使用逻辑wiget组件来代替if else 语句。如果不制定规则,那ast Node 到widget node 的解析过程会很复杂。理论上都可以解析,只要解析sdk 够强大。制定规则,可以减轻sdk的解析逻辑。b.工具检测用工具来检测源码是否符合制定的规则,以保证所有的源码都能解析出来。性能和效果帧率大于50fps,体验上看比weex相同功能的页面更加流畅,Samsung galaxy s8上,感觉不出组件是通过动态渲染的.数据结构服务端请求到的数据,我们可以约定一种格式如下:class DataModel { Map<dynamic, dynamic> data; String type;}每个page 都是由组件组成的,每个组件的数据都是 DataModel来渲染。根据type 来找到对应的模版,模版+data,渲染出界面。动态模版管理模块我们把Widget Node Tree 转换为一个组件Json模版,它需要一套管理平台,来支持版本控制,动态下载,升级,回滚,更新等。框架的边界该框架是通过组件的组装,组件布局动态变更,页面布局动态变更来实现动态化。所以它适合运营变化较快的首页,详情,订单,我的等页面。一些复杂的逻辑需要封装在组件里面,把组件内置到框架中,当作本地组件。框架侧重于动态组件的组装,而引擎对于源码复杂的逻辑表达式的解析是弱化的。后续拓展1.和UI自动化的结合UI自动化 ,前面已经有文章介绍。UI自动化工具生成组件,再组件转为模版,动态下发,来快速解决运营需求。2.国际化的支持App在不同国家会有不同的功能,我们可以根据区域,来动态拼装我们的页面。3.千人千面根据不同的人群,来动态渲染不一样的界面。总结本文介绍动态化方案的渲染部分。该方案都在初探阶段,还有很多需要完善,后续会继续扩展和修改,等达到开源标准后,会考虑开源。动态方案是一个后端前端一体的方案,需要一整套工具配合,后续会有文章继续介绍整体的动态化方案。敬请关注闲鱼技术公共账号,也邀请您加入闲鱼一起探索有意思的技术。参考资料:Static Analysis:https://www.dartlang.org/guides/language/analysis-optionshttps://www.dartlang.org/tools/analyzerdart analyzer :https://pub.dartlang.org/packages/analyzerhttps://github.com/dart-lang/sdk/tree/master/pkg/analyzer_cli#dartanalyzerdartdevc:https://webdev.dartlang.org/tools/dartdevc本文作者:闲鱼技术-石磬阅读原文本文为云栖社区原创内容,未经允许不得转载。 ...

December 5, 2018 · 1 min · jiezi