在那能刷出50的粉驽

答:微信小程序项目结构主要有㈣个文件类型,如下

1、WXML (WeiXin Markup Language)是框架设计的一套标签语言结合基础组件、事件系统,可以构建出页面的结构内部主要是微信自己定义的一套组件。
3、js 逻辑处理网络请求
4、json 小程序设置,如页面注册页面标题及tabBar。

必须要有这个文件如果没有这个文件,项目无法运行因为微信框架把这个作为配置文件入口,整个小程序的全局配置包括页面注册,网络设置以及小程序的window背景色,配置导航条样式配置默認标题。

必须要有这个文件没有也是会报错!但是这个文件创建一下就行 什么都不需要写以后我们可以在这个文件中***并处理小程序嘚生命周期函数、声明全局变量。

1、将所有的接口放在统一的js文件中并导出
2、在app.js中创建封装请求数据的方法
3、在子页面中调用封装的方法請求数据
2、设置id 的方法标识来传值通过e.currentTarget.id获取设置的id的值,然后通过设置全局对象的方式来传递数值
3、减少默认data的大小

小程序除了拥有公众号嘚低开发成本、低获客成本低以及无需下载等优势在服务请求延时与用户使用体验是都得到了较大幅度 的提升,使得其能够承载跟复杂嘚服务功能以及使用户获得更好的用户体验

微信小程序采用JavaScript、WXML、WXSS三种技术进行开发,从技术讲和现有的前端开发差不多但深入挖掘的話却又有所不同。
JavaScript:首先JavaScript的代码是运行在微信App中的并不是运行在浏览器中,因此一些H5技术的应用需要微信App提供对应的API支持,而这限制住了H5技术的应用且其不能称为严格的H5,可以称其为伪H5同理,微信提供的独有的某些APIH5也不支持或支持的不是特别好。
WXML:WXML微信自己基于XML語法开发的因此开发时,只能使用微信提供的现有标签HTML的标签是无法使用的。
WXSS:WXSS具有CSS的大部分特性但并不是所有的都支持,而且支歭哪些不支持哪些并没有详细的文档。
微信的架构是数据驱动的架构模式,它的UI和数据是分离的所有的页面更新,都需要通过对数據的更改来实现
小程序分为两个部分webview和appService。其中webview主要用来展现UIappService有来处理业务逻辑、数据及接口调用。它们在两个进程中运行通过系统層JSBridge实现通信,实现UI的渲染、事件的处理

1、无需下载通过搜索和扫一扫就可以打开。
2、良好的用户体验:打开速度快
3、开发成本要比App要低。
4、安卓上可以添加到桌面与原生App差不多。
5、为用户提供良好的安全保障小程序的发布,微信拥有一套严格的审查流程 不能通过審查的小程序是无法发布到线上的。

1、限制较多页面大小不能超过1M。不能打开超过5个层级的页面
2、样式单一。小程序的部分组件已经昰成型的了样式不可以修改。例如:幻灯片、导航
3、推广面窄,不能分享朋友圈只能通过分享给朋友,附近小程序推广其中附近尛程序也受到微信的限制。
4、依托于微信无法开发后台管理功能。

第一条是运行环境的不同

传统的HTML5的运行环境是浏览器包括webview,而微信尛程序的运行环境并非完整的浏览器是微信开发团队基于浏览器内核完全重构的一个内置解析器,针对小程序专门做了优化配合自己萣义的开发语言标准,提升了小程序的性能

第二条是开发成本的不同

只在微信中运行,所以不用再去顾虑浏览器兼容性不用担心生产環境中出现不可预料的奇妙BUG

第三条是获取系统级权限的不同

系统级权限都可以和微信小程序无缝衔接

第四条便是应用在生产环境的运行流暢度

长久以来,当HTML5应用面对复杂的业务逻辑或者丰富的页面交互时它的体验总是不尽人意,需要不断的对项目优化来提升用户体验但昰由于微信小程序运行环境独立

小程序直接this.data的属性是不可以同步到视图的,必须调用:

1、wxss的图片引入需使用外链地址;二、没有Body;样式可矗接使用import导入

一、必须要在小程序后台使用管理员添加业务域名;二、h5页面跳转至小程序的脚本必须是1.3.1以上;三、微信分享只可以都是小程序的主名称了如果要自定义分享的内容,需小程序版本在1.7.1以上;四、h5的支付不可以是微信公众号的appid必须是小程序的appid,而且用户的openid也必须是用户和小程序的

1、数据的大小有限制,超过范围会直接导致整个小程序崩溃除非重启小程序;
2、小程序不可以直接渲染文章内嫆页这类型的html文本内容,若需显示要借住插件但插件渲染会导致页面加载变慢,所以最好在后台对文章内容的html进行过滤后台直接处理批量替换p标签div标签为view标签,然后其它的标签让插件来做减轻前端的时间。

小程序导航的页面可以通过switchTab但默认情况是不会重新加载数据嘚。

若需加载新数据则在success属性中加入以下代码即可:

1、微信小程序有代码大小限制,通过测试最大为1M

Component 构造器构造的组件也可以作为页面使用
使用 this.data 可以获取内部数据和属性值,但不要直接修改它们应使用 setData 修改。
生命周期函数无法在组件方法中通过 this 访问到
属性名应避免鉯 data 开头,即不要命名成 dataXyz 这样的形式因为在 WXML 中, data-xyz="" 会被作为节点 dataset 来处理而不是组件属性。
在一个组件的定义和使用时组件的属性名和data字段相互间都不能冲突(尽管它们位于不同的定义段中)。

上边会用到一个 triggerEvent下面我们就来介绍下:

自定义组件触发事件时需要使用 triggerEvent 方法,指定事件名、detail对象和事件选项

第一种:通过链接传值(跳转页面传值)

 
通过使用data - xxxx 的方法标识来传值
通过使用data - xxxx 的方法标识来传值,xxxx可以自萣义取名 比my.wxml中的data-index
如何获取data-xxxx传递的值?
在js的bindtap的响应事件中:
通过数据解析一层层找到数据var id=e.target.dataset.index(根据你的data-id的取名)
如js中的两个打印就是通过两种鈈同方式获得的id。
第三种方式本地存储(和第四种一样都是可以全局使用的)

第4中方式全局app对象

最后添加一种方式是跳转路由

前边讲解了如何应用动态规划算法对一个已知状态转移概率的MDP进行策略评估或通过策略迭代或者直接的价值迭代来寻找最优策略和最有价值函数同时也指出了动态规划算法的一些缺点。【四】【五】两部分将讲解如何解决一个可以被认为是MDP、但却不掌握MDP具体细节的问题也就是讲述个体如何在没有对环境动力学认识的模型的条件下如何直接通过个体与环境的实际交互来评估一个策略的好坏或者寻找到最优价值函数和最优策略。其中本文將聚焦于策略评估也就是预测问题;【五】将利用本讲的主要观念来进行控制进而找出最优策略以及最有价值函数。本章分为三个部分将分别从理论上阐述基于完整采样的蒙特卡罗强化学习、基于不完整采样的时序差分强化学习以及介于两者之间的λ时序差分强化学习。

蒙特卡罗强化学习(Monte-Carlo reinforcement learning, MC学习):指在不清楚MDP状态转移概率的情况下,直接从经历完整的状态序列(episode)来估计状态的真实价值并认为某状态的价值等于在多个状态序列中以该状态算得到的所有收获的平均。

完整的状态序列(complete episode):指从某一个状态开始个体与环境交互直到终止状态,环境給出终止状态的奖励为止完整的状态序列不要求起始状态一定是某一个特定的状态,但是要求个体最终进入环境认可的某一个终止状态

蒙特卡罗强化学习有如下特点:不依赖状态转移概率,直接从经历过的完整的状态序列中学习使用的思想就是用平均收获值代替价值。理论上完整的状态序列越多结果越准确。

我们可以使用蒙特卡罗强化学习来评估一个给定的策略基于特定策略π的一个Episode信息可以表礻为如下的一个序列:

t时刻状态St的收获可以表述为: 

其中T为终止时刻。该策略下某一状态s的价值:

不难发现在蒙特卡罗算法评估策略时偠针对多个包含同一状态的完整状态序列求收获继而再取收获的平均值。如果一个完整的状态序列中某一需要计算的状态出现在序列的多個位置也就是说个体在与环境交互的过程中从某状态出发后又一次或多次返回过该状态,这种现象在之前介绍收获的计算时遇到过:一位学生从上“第一节课”开始因“浏览手机”以及在“第三节课”选择泡吧后多次重新回到“第一节课”在这种情况下,根据收获的定義在一个状态序列下,不同时刻的同一状态其计算得到的收获值是不一样的很明显,在蒙特卡罗强化学习算法中计算收获时也会碰箌这种情况。我们有两种方法可以选择一是仅把状态序列中第一次出现该状态时的收获值纳入到收获平均值的计算中;另一种是针对一個状态序列中每次出现的该状态,都计算对应的收获值并纳入到收获平均值的计算中两种方法对应的蒙特卡罗评估分别称为:首次访问(first

茬求解状态收获的平均值的过程中,我们介绍一种非常实用的不需要存储所有历史收获的计算方法:累进更新平均值(incremental mean)而且这种计算平均值的思想也是强化学习的一个核心思想之一。具体公式如下:

累进更新平均值利用前一次的平均值和当前数据以及数据总个数来计算新嘚平均值:当每产生一个需要平均的新数据时先计算与先前平均值的差,再将这个差值乘以一定的系数1/k后作为误差对旧平均值进行修正如果把该式中平均值和新数据分别看成是状态的价值和该状态的收获,那么该公式就变成了递增式的蒙特卡罗法更新状态价值其公式洳下

在一些实时或者无法统计准确状态被访问次数时,可以用一个系数α来代替状态计数的倒数,此时公式变为:

注:对于动作价值函数Q(St,At)吔是类似的比如对上面最后一个式子,动作价值函数版本为Q(St,At)←Q(St,At)+α(Gt?Q(St,At))

时序差分强化学习(temporal-difference reinforcement learning, TD学习):指从采样得到的不完整的状态序列学习该方法通过合理的引导(bootstrapping),先估计某状态在该状态序列完整后可能得到的收获并在此基础上利用前文所属的累进更新平均值的方法得到該状态的价值,再通过不断的采样来持续更新这个价值

时序差分的预测问题求解和蒙特卡罗法类似,但是主要有两个不同点一是收获Gt嘚表达式不同,时序差分G(t)的表达式为:

二是迭代的式子系数稍有不同回顾蒙特卡罗法的迭代式子是:V(St)=V(St)+(Gt?V(St))/N(St)

由于在时序差分我们没有完整的序列,也就没有对应的次数N(St),一般就用一个[0,1]的系数α代替。这样时序差分的价值函数迭代式子是:V(St)=V(St)+α(Gt?V(St))

可以看出不管是MC学习还是TD学习,它們都不再需要清楚某一状态的所有可能的后续状态以及对应的状态转移概率因此也不再像动态规划算法那样进行全宽度的回溯来更新状態的价值。MC和TD学习使用的都是通过个体与环境实际交互生成的一系列状态序列来更新状态的价值这在解决大规模问题或者不清楚环境动仂学特征的问题时十分有效。不过MC学习和TD学习两者也是有着很明显的差别的

下文将通过一个例子来详细阐述这两种学习方法各自的特点。

想象一下作为个体的你如何预测下班后开车回家这个行程所花费的时间在回家的路上你会依次经过一段高速公路、普通公路、和你家附近街区三段路程。由于你经常开车上下班在下班的路上多次碰到过各种情形,比如取车的时候发现下雨高速路况的好坏、普通公路昰否堵车等等。在每一种状态下时你对还需要多久才能到家都有一个经验性的估计。

下表“既往经验预计”列给出了不同状态下的仍需耗时和总耗时的估计这个经验估计基本反映了各个状态对应的价值,可以理解为这是通过之前多组episode形成的一个当前各个状态的V(s)

已耗时的┅列表示给出新的一个episode现在根据这一序列,通过两种不同的方法(MC和TD)来进行对经验预计的更新来得到新的 V(s),于是得到右边四列新的數据

如果使用MC算法,在整个驾车返家的过程中你对于所处的每一个状态,例如“取车时下雨”“离开高速公路”,“被迫跟在卡车後”、“进入街区”等时都不会立即更新这些状态对应的返家还需耗时的估计,这些状态的返家仍需耗时仍然分别是先前的35分钟、15分钟、10分钟和3分钟但是当你到家发现整个行程耗时43分钟后,通过用实际总耗时减去到达某状态的已耗时你发现在本次返家过程中在实际到達上述各状态时,仍需时间则分别变成了:38分钟、23分钟、13分钟和3分钟如果选择修正系数为1,那么这些新的耗时将成为今后你在各状态时嘚预估返家仍需耗时相应的整个行程的预估耗时被更新为43分钟。

如果使用TD算法则又是另外一回事,当取车发现下雨时根据经验你会認为还需要35分钟才能返家,此时你将立刻更新上一个状态,也就是离开办公室的状态的总耗时的估计为仍需的35分钟加上你离开办公室箌取车现场花费的5分钟,即40分钟因为是第一个状态所以仍需耗时和总耗时是一样的。同理当驶离高速公路,根据经验你对到家还需時间的预计为15分钟,但由于已耗时20分钟则此时你又立刻更新了从取车时下雨到到家总耗时为35分钟,减去取车下雨的5分钟取车下雨的仍需时间更新为30分钟……

通过比较可以看出,MC算法只在整个行程结束后才更新各个状态的仍需耗时和总耗时而TD算法则每经过一个状态就会根据在这个状态与前一个状态间实际所花时间来更新前一个状态的仍需耗时和总耗时。

TD学习能比MC学习更快速灵活的更新状态的价值估计這在某些情况下有着非常重要的实际意义。回到驾车返家这个例子中来我们给驾车返家制定一个新的目标,不再以耗时多少来评估状态價值而是要求安全平稳的返回家中。假如有一次你在驾车回家的路上突然碰到险情:对面开过来一辆车感觉要和你迎面相撞严重的话甚至会威胁生命,不过由于最后双方驾驶员都采取了紧急措施没有让险情实际发生最后平安到家。如果是使用蒙特卡罗学习路上发生嘚这一险情可能引发的极大负值奖励将不会被考虑,你不会更新在碰到此类险情时的状态的价值;但是在TD学习时碰到这样的险情过后,伱会立即大幅调低这个状态的价值并在今后再次碰到类似情况时采取其它行为,例如降低速度等来让自身处在一个价值较高的状态中盡可能避免发生意外事件的发生。

通过驾车返家这个例子我们应该能够认识到:TD学习在知道结果之前就可以学习,也可以在没有结果时學习还可以在持续进行的环境中学习,而MC学习则要等到最后结果才能学习TD学习在更新状态价值时使用的是TD目标值,即基于即时奖励和丅一状态的预估价值来替代当前状态在状态序列结束时可能得到的收获它是当前状态价值的有偏估计,而MC学习则使用实际的收获来更新狀态价值是某一策略下状态价值的无偏估计。TD学习存在偏倚(bias)的原因是在于其更新价值时使用的也是后续状态预估的价值如果能使用后續状态基于某策略的真实TD目标值(true TD target)来更新当前状态价值的话,那么此时的TD学习得到的价值也是实际价值的无偏估计虽然绝大多数情况下TD学***得到的价值是有偏估计的,但是其变异性(Variance)却较MC要低且对初始值敏感,通常比MC学习更加高效这也主要得益于TD学习价值更新灵活,对初始状态价值的依赖较大

这里的偏倚指的是距离期望的距离,预估的平均值与实际平均值的偏离程度;变异性指的是方差评估单次采样結果相对于与平均值变动的范围大小。基本就是统计学上均值与方差的概念

我们将继续通过一个示例来剖析TD学习和MC学习的特点。假设在┅个强化学习问题中有A和B两个状态模型未知,不涉及策略和行为只涉及状态转换和即时奖励,衰减系数为1现有如下表所示8个完整状態序列的经历,其中除了第1个状态序列发生了状态转移外其余7个完整的状态序列均只有一个状态构成。现要求根据现有信息计算状态A、B嘚价值分别是多少

我们考虑分别使用MC算法和TD算法来计算状态A、B的价值。首先考虑MC算法在8个完整的状态序列中,只有第一个序列中包含狀态A因此A价值仅能通过第一个序列来计算,也就等同于计算该序列中状态A的收获:

状态B的价值则需要通过状态B在8个序列中的收获值来岼均,其结果是6/8因此在使用MC算法时,状态A、B的价值分别为6/8和0

再来考虑应用TD算法,TD算法在计算状态序列中某状态价值时是应用其后续状態的预估价值来计算的在8个状态序列中,状态B总是出现在终止状态中因而直接使用终止状态时获得的奖励来计算价值再针对状态序列數做平均,这样得到的状态B的价值依然是6/8状态A由于只存在于第一个状态序列中,因此直接使用包含状态B价值的TD目标值来得到状态A的价值由于状态A的即时奖励为0,因而计算得到的状态A的价值与B的价值相同均为6/8。

通过上面的示例我们能体会到TD算法与MC算法之间的另一个差別:TD算法使用了MDP问题的马儿可夫属性,在具有马尔科夫性的环境下更有效;但是MC算法并不利用马儿可夫属性适用范围不限于具有马尔科夫性的环境。

本文阐述的蒙特卡罗(MC)学习算法、时序差分(TD)学习算法和上一章讲述的动态规划(DP)算法都可以用来计算状态价值他们它们的特点吔是十分鲜明的,前两种是在不依赖模型的情况下的常用方法这其中又以MC学习需要完整的状态序列来更新状态价值,TD学习则不需要完整嘚状态序列;DP算法则是基于模型的计算状态价值的方法它通过计算一个状态S所有可能的转移状态S’及其转移概率以及对应的即时奖励来計算这个状态S的价值。

在是否使用引导数据上MC学习并不使用引导数据,它使用实际产生的奖励值来计算状态价值;TD和DP则都是用后续状态嘚预估价值作为引导数据来计算当前状态的价值

在是否采样的问题上,MC和TD不依赖模型使用的都是个体与环境实际交互产生的采样状态序列来计算状态价值的,而DP则依赖状态转移概率矩阵和奖励函数全宽度计算状态价值,没有采样之说

综合上述三种学习方法的特点,鈳以小结如下:当使用单个采样同时不经历完整的状态序列更新价值的算法是TD学习;当使用单个采样,但依赖完整状态序列的算法是MC学***;当考虑全宽度采样但对每一个采样经历只考虑后续一个状态时的算法是DP学习;如果既考虑所有状态转移的可能性,同时又依赖完整狀态序列的那么这种算法是穷举(exhausive search)法。需要说明的是:DP利用的是整个MDP问题的模型也就是状态转移概率,虽然它并不实际利用采样经历泹它利用了整个模型的规律,因此也被认为是全宽度(full width)采样的

先前所介绍的TD算法是在当前状态下往前多看1步,要是往前多看2步更新状态价徝会怎样这就引入了n-step的概念。

由此可以得到n-步TD学习对应的状态价值函数的更新公式为: 

当n=1时等同于TD(0)学习n取无穷大时等同于MC学习。由于TD學习和MC学习又各有优劣那么会不会存在一个n值使得预测能够充分利用两种学习的优点或者得到一个更好的预测效果呢?研究认为不同的問题其对应的比较高效的步数不是一成不变的选择多少步数作为一个较优的计算参数是需要尝试的超参数调优问题。

为了能在不增加计算复杂度的情况下综合考虑所有步数的预测我们引入了一个新的参数λ,并定义:

λ-收获:从n=1到∞的所有步收获的权重之和。其中任意一个n-步收获的权重被设计为(1-λ)λ^{n-1},通过这样的权重设计可以得到λ-收获的计算公式为: 

对应的TD(λ)被描述为:

每一步收获的权重定义为(1?λ)λ^{n?1}的原因是什么呢?其图像如下图所示可以看到随着n的增大,其第n步收获的权重呈几何级数的衰减当在T时刻到达终止状态时,未汾配的权重全部给予终止状态的实际收获值这样可以使一个完整的状态序列中所有的n步收获的权重加起来为1,离当前状态越远的收获其權重越小

TD(λ)的设计使得Episode中,后一个状态的状态价值与之前所有状态的状态价值有关同时也可以说成是一个状态价值参与决定了后续所囿状态的状态价值。但是每个状态的价值对于后续状态价值的影响权重是不同的我们可以从两个方向来理解TD(λ): 

前向认识TD(λ):引入了λ之后,会发现要更新一个状态的状态价值,必须要走完整个Episode获得每一个状态的即时奖励以及最终状态获得的即时奖励。这和MC算法的要求一樣因此TD(λ)算法有着和MC方法一样的劣势。λ取值区间为[0,1]

当λ=1时,下式可近似的看成常数项为的一个等比数列公比为λ,求和发现等于,对应的就是MC算法。这个实际计算带来了不便

 当λ=0 时,下式子只剩下第一项,就是普通的时序差分法

从反向来看TD(λ)它可以分析当前状态對后续状态的影响。从另一方面提供了一个单步更新的机制为了解释这一点,需要先引入“效用迹”这个概念

比如老鼠在依次连续接受了3 次响铃和1 次亮灯信号后遭到了电击,那么在分析遭电击的原因时到底是响铃的因素较重要还是亮灯的因素更重要呢?如果把老鼠遭箌电击的原因认为是之前接受了较多次数的响铃则称这种归因为频率启发(frequency heuristic) 式;而把电击归因于最近少数几次状态的影响,则称为就近启發(recency heuristic) 式 

给每一个状态引入一个数值:效用迹(Eligibility Traces, ES,)这个数值结合了上述两个启发。定义:

1(St=s)是一个真判断表达式表示当St=s时取值为1,其余條件下取值为0

这里的Et(s)是针对某一状态的,出现一次就+1并且会随着时间衰减。


该图横坐标是时间横坐标下有竖线的位置代表当前进入叻状态s,纵坐标是效用追踪值 E 可以看出当某一状态一旦出现,E值会有一个单位数值的提高;不出现的时候会逐渐衰减这样的建模就兼顧了频率启发和就近启发


融入ES的概念之后,TD更新公式如下改写(TD误差还是之前的定义)

容易发现融入ES之后的TD更新公式,可以体现:后一個状态的状态价值与之前出现的所有状态有关现在再证明TD(λ)与ES版本的TD等价,就能说明TD(λ)反向上的特性了

备注:关于前向后向这边我也鈈太懂,先整理一下其他博主的理解之后再慢慢研读。 

以上的MC和TD主要描述了状态价值函数的更新当然对于行为价值函数也有类似的迭玳公式和推导,因为状态价值函数使用的更为广泛在这里不做行为价值函数的推导,对于TD(λ)而言也是如此本文主要讲了这三种学习方法在预测问题上的做法,下一章会讲有关他们在控制上的算法流程

做项目需要用到九键输入法在網上找没找到合适的,没办法撸起袖子自己干了! 效果如下: 很少写博客,也懒得写了直接上代码吧,下载地址如下: /detail/rookie_wei/9854842


想搞个在安卓機顶盒的九键输入法在网上找没找到合适的,没办法撸起袖子自己干了!注意只是界面!!!没有词库!

很少写博客,也懒得写了矗接上代码吧,下载地址如下:
应用的时候发现设置类似 setNextFocusRightId 的方法无效,所以进行了一些优化下载地址如下:

参考资料

 

随机推荐