陳勃 王錦艷



摘 要:針對(duì)深度Q網(wǎng)絡(luò)(DQN)應(yīng)用中基于python數(shù)據(jù)結(jié)構(gòu)直接實(shí)現(xiàn)的經(jīng)驗(yàn)回放過(guò)程時(shí)常成為性能瓶頸,提出一種具有高性能及通用性的經(jīng)驗(yàn)回放模塊設(shè)計(jì)方案。該設(shè)計(jì)方案具有兩層軟件結(jié)構(gòu):底層的功能內(nèi)核由C++語(yǔ)言實(shí)現(xiàn),以提供較高的執(zhí)行效率; 上層則由python語(yǔ)言編寫(xiě),以面向?qū)ο蟮姆绞椒庋b模塊功能并提供調(diào)用接口,使模塊具有較高易用性。針對(duì)經(jīng)驗(yàn)回放所涉及的關(guān)鍵操作,一些技術(shù)細(xì)節(jié)被充分研究和精心設(shè)計(jì), 例如,將優(yōu)先級(jí)回放機(jī)制作為附屬組件與模塊的主體運(yùn)行邏輯分離,將樣本的可抽取性驗(yàn)證提前到樣本記錄操作中進(jìn)行,使用高效的樣本淘汰策略與算法等。這些措施使模塊具有較高的通用性和可擴(kuò)展性。實(shí)驗(yàn)結(jié)果表明,按照該模塊實(shí)現(xiàn)的經(jīng)驗(yàn)回放過(guò)程,整體執(zhí)行效率得到了充分優(yōu)化,兩個(gè)關(guān)鍵操作——樣本記錄與樣本抽取,皆可高效執(zhí)行。與基于python數(shù)據(jù)結(jié)構(gòu)的直接實(shí)現(xiàn)方式相比,所提模塊在樣本抽取操作上的性能提升了約100倍,從而避免了經(jīng)驗(yàn)回放過(guò)程成為整個(gè)系統(tǒng)的性能瓶頸,滿足了各類DQN相關(guān)應(yīng)用項(xiàng)目的需要。
關(guān)鍵詞:強(qiáng)化學(xué)習(xí);深度學(xué)習(xí);深度Q網(wǎng)絡(luò);經(jīng)驗(yàn)回放;軟件設(shè)計(jì)
中圖分類號(hào):TP302
文獻(xiàn)標(biāo)志碼:A
Design of experiencereplay module with high performance
CHEN Bo*, WANG Jinyan
College of Mathematics and Computer Science, Fuzhou University, Fuzhou Fujian 350108, China
Abstract:
Concerning the problem that a straightforward implementation of the experiencereplay procedure based on python datastructures may lead to a performance bottleneck in Deep Q Network (DQN) related applications, a design scheme of a universal experiencereplay module was proposed to provide high performance. The proposed module consists of two software layers. One of them, called the “kernel”, was written in C++, to implement fundamental functions for experiencereplay, achieving a high execution efficiency. And the other layer “wrapper”, written in python, encapsulated the module function and provided the call interface in an objectoriented style, guaranteeing the usability. For the critical operations in experiencereplay, the software structure and algorithms were well researched and designed. The measures include implementing the priority replay mechanism as an accessorial part of the main module with logical separation, bringing forward the samples verification of “get_batch” to the “record” operation, using efficient strategies and algorithms in eliminating samples, and so on. With such measures, the proposed module is universal and extendible. The experimental results show that the execution efficiency of the experiencereplay process is well optimized by using the proposed module, and the two critical operations, the “record” and the “get_batch”, can be executed efficiently. The proposed module operates the “get_batch” about 100 times faster compared with the straightforward implementation based on python datastructures. Therefore, the experiencereplay process is no longer a performance bottleneck in the system, meeting the requirements of various kinds of DQNrelated applications.
Key words:
reinforcement learning; deep learning; Deep Q Network (DQN); experiencereplay; software design
0?引言
Q學(xué)習(xí)(QLearning)是強(qiáng)化學(xué)習(xí)方法的一個(gè)重要分支,用于從智能個(gè)體的過(guò)往行為和環(huán)境反饋中學(xué)習(xí)行為決策模式。此類強(qiáng)化學(xué)習(xí)過(guò)程利用時(shí)間差分(Temporal Difference,TD)方法[1],迭代地累積個(gè)體的短期收益(Reward),從而評(píng)估在每種可觀察狀態(tài)(State)下施行每種動(dòng)作(Action)的長(zhǎng)程收益值(Q值),來(lái)為個(gè)體決策作出參考[2]。
傳統(tǒng)QLearning通常采用二維表格的形式來(lái)記錄Q值,但這對(duì)于具有大量可觀察狀態(tài)或者連續(xù)狀態(tài)的場(chǎng)合顯然不適用[3]。隨著近年來(lái)深度學(xué)習(xí)軟硬件技術(shù)的蓬勃發(fā)展,深度Q網(wǎng)絡(luò)(Deep Q Network,DQN)方法應(yīng)運(yùn)而生。它采用深度神經(jīng)網(wǎng)絡(luò)擬合Q函數(shù)[4-5],而非利用二維表格,從而能夠處理巨大的或者連續(xù)的狀態(tài)空間。DQN方法誕生以來(lái),在應(yīng)用領(lǐng)域取得了許多顯著的成果,例如,Mnih等[5]以雅達(dá)利(Atari) 2600平臺(tái)中的游戲?yàn)榄h(huán)境訓(xùn)練神經(jīng)網(wǎng)絡(luò),經(jīng)過(guò)訓(xùn)練后該網(wǎng)絡(luò)在多項(xiàng)游戲中的表現(xiàn)超過(guò)人類水平;DeepMind團(tuán)隊(duì)研發(fā)的智能圍棋程序AlphaGo于2016年擊敗頂級(jí)人類棋手李世石,并于2017年擊敗世界冠軍柯潔[6];趙玉婷等[7]在2018年將DQN方法應(yīng)用于雙足機(jī)器人在非平整地面上的行走控制,使得行走穩(wěn)定性明顯改善。Alansary等[8]在2019年提出基于DQN框架的強(qiáng)化學(xué)習(xí)主體,用于醫(yī)學(xué)圖像中的自動(dòng)標(biāo)志檢測(cè);Zhu等[9]在2019年將DQN方法用于國(guó)際空中機(jī)器人大賽(International Aerial Robotics Competition,IARC)的牧羊人游戲任務(wù)中,并驗(yàn)證了方法的有效性和效率等。
DQN方法之所以能夠取得如此豐碩的成果,除了它利用神經(jīng)網(wǎng)絡(luò)對(duì)Q函數(shù)進(jìn)行了更具適用性的表示之外,另兩個(gè)重要的原因是:其一,利用單獨(dú)的、延遲更新的目標(biāo)網(wǎng)絡(luò)來(lái)計(jì)算學(xué)習(xí)目標(biāo),使得訓(xùn)練過(guò)程中的誤差值不致有過(guò)大波動(dòng),以保證訓(xùn)練的收斂;其二,引入了經(jīng)驗(yàn)回放(Experience Replay)機(jī)制,消除了訓(xùn)練樣本間的相關(guān)性,從而符合訓(xùn)練樣本獨(dú)立同分布的統(tǒng)計(jì)學(xué)假設(shè)[5, 10]。由此可見(jiàn),經(jīng)驗(yàn)回放是DQN方法中的一個(gè)重要環(huán)節(jié)。而從軟件設(shè)計(jì)與實(shí)現(xiàn)的角度,應(yīng)當(dāng)將經(jīng)驗(yàn)回放過(guò)程作為獨(dú)立模塊進(jìn)行封裝,以便于整個(gè)DQN方法的實(shí)現(xiàn)與應(yīng)用。在經(jīng)驗(yàn)回放模塊的設(shè)計(jì)中主要需要關(guān)注以下兩點(diǎn):
1) 運(yùn)行性能。DQN相關(guān)應(yīng)用中,將頻繁使用經(jīng)驗(yàn)回放模塊的三個(gè)操作,即經(jīng)驗(yàn)的記錄(record)、采樣抽?。╣et_batch)和優(yōu)先級(jí)設(shè)置(set_priority)。這三個(gè)操作所產(chǎn)生的時(shí)間開(kāi)銷必須得到優(yōu)化,否則,可能成為整個(gè)系統(tǒng)的性能瓶頸,影響整體的執(zhí)行效率。
2) 通用性。作為一個(gè)獨(dú)立模塊,應(yīng)當(dāng)為各類DQN相關(guān)應(yīng)用提供支持,而非只針對(duì)某種特殊的應(yīng)用場(chǎng)景。具體而言,應(yīng)當(dāng)支持記錄任意結(jié)構(gòu)的可觀察狀態(tài)(State),兼顧時(shí)間序列與非時(shí)間序列兩類數(shù)據(jù),以及支持多樣化的采樣抽取策略等。
本文針對(duì)以上兩點(diǎn)需求,提出一種可行的經(jīng)驗(yàn)回放模塊設(shè)計(jì)方案,并展示和討論其實(shí)現(xiàn)效果。
1?經(jīng)驗(yàn)回放模塊的接口形式
作為一個(gè)封裝的模塊,需要定義可供外部調(diào)用的接口,這包括一組相關(guān)的軟件實(shí)體概念和一組可供調(diào)用的操作方法。本章將對(duì)其進(jìn)行介紹。
首先,本文提出的經(jīng)驗(yàn)回放模塊涉及下述軟件實(shí)體概念:
1) 可觀察狀態(tài)(state)。DQN系統(tǒng)中的state是網(wǎng)絡(luò)的輸入,是智能個(gè)體可觀察到的環(huán)境的數(shù)字化表示。在不同應(yīng)用中,state可以具有不同的形式,可以是向量、矩陣,或者具有任意高維形狀。經(jīng)驗(yàn)回放模塊不應(yīng)假設(shè)state具有任何特定形狀或含義,從而保證模塊的通用性。
2) 動(dòng)作(action)。智能體能夠采取的行動(dòng)的編碼,是一個(gè)整型數(shù)值。
3) 獎(jiǎng)勵(lì)(reward)。智能體在某個(gè)state下采取某個(gè)action后立即獲得的獎(jiǎng)勵(lì),是一個(gè)實(shí)數(shù)(浮點(diǎn))型值。
4) 記錄(record)。一個(gè)state、action、reward的組合成為一條record。為支持時(shí)間序列相關(guān)應(yīng)用,經(jīng)驗(yàn)回放模塊應(yīng)當(dāng)維護(hù)record間的順序關(guān)系。
5) 回合(episode)及其句柄(handle):具有時(shí)間順序關(guān)系的若干record組成一個(gè)episode。在實(shí)際的DQN相關(guān)應(yīng)用中,episode通常對(duì)應(yīng)了智能體完成某次任務(wù)的完整體驗(yàn),例如一局完整的游戲。經(jīng)驗(yàn)回放模塊用一個(gè)唯一的整型數(shù)來(lái)標(biāo)識(shí)某個(gè)episode,稱作這個(gè)episode的handle。
6) 采樣準(zhǔn)則(pick_policy)。在使用非時(shí)間序列數(shù)據(jù)的應(yīng)用[11]中,采樣抽取時(shí)以單個(gè)record為采樣的最小單元。而時(shí)間序列相關(guān)的應(yīng)用[12]中,可能需要連續(xù)抽取長(zhǎng)度為pick_len的若干個(gè)連續(xù)的record。此外,某些應(yīng)用中,允許抽取的片段長(zhǎng)度不足預(yù)期值pick_len(當(dāng)?shù)竭_(dá)episode結(jié)尾時(shí)),使得實(shí)際抽取的片段長(zhǎng)度參差不齊(但不超過(guò)pick_len)。上述這些采樣抽取相關(guān)的準(zhǔn)則在這里稱作pick_policy。
7) 可抽取樣本(pick)。具有順序關(guān)系的若干record組成一個(gè)片段,如果片段符合pick_policy,則在采樣抽取時(shí)可作為候選片段,稱作一個(gè)pick。任意一個(gè)pick可以用其來(lái)源的episode及其首個(gè)record在該episode中的時(shí)間序列位置表示,故可記作有序?qū)Α磒ick_epi, pick_pos〉。
8) 優(yōu)先級(jí)(priority)。當(dāng)對(duì)記錄在經(jīng)驗(yàn)回放模塊中的數(shù)據(jù)進(jìn)行采樣抽取時(shí),可以使用均勻隨機(jī)抽取或者依優(yōu)先級(jí)抽取的策略。若使用后者,則整個(gè)經(jīng)驗(yàn)回放過(guò)程被稱作“優(yōu)先級(jí)經(jīng)驗(yàn)回放”(Prioritized Experience Replay)[13-15],此時(shí),每個(gè)pick應(yīng)當(dāng)具有某種優(yōu)先級(jí)數(shù)priority,它應(yīng)是一個(gè)實(shí)數(shù)(浮點(diǎn))型值。
9) 抽取選擇器(pick_selector)及其句柄(handle)。為使得模塊能夠支持多樣化的采樣抽取策略(均勻隨機(jī)或者多種優(yōu)先級(jí)抽取算法),本文提出的軟件結(jié)構(gòu)中,將采樣抽取策略抽象為一種稱為pick_selector的附屬組件(詳見(jiàn)第2章),經(jīng)驗(yàn)回放模塊利用不同的pick_selector以實(shí)施不同的采樣抽取行為。每個(gè)pick_selector實(shí)例用一個(gè)唯一的整型數(shù)標(biāo)識(shí),稱為它的handle。
在以上實(shí)體概念的基礎(chǔ)上,定義經(jīng)驗(yàn)回放模塊應(yīng)當(dāng)支持的主要操作方法有:
1) new_episode()。建立一個(gè)新的episode,并返回其對(duì)應(yīng)的句柄h_epi。
2) new_pick_selector(pick_selector_class)。建立一個(gè)pick_selector的實(shí)例,其類型為pick_selector_class,并返回該抽取選擇器的句柄h_ps。
3) record(h_epi, state, action, reward, final_state)。在以句柄h_epi標(biāo)識(shí)的episode中追加一條完整的record,即一個(gè)state、action、reward的組合。final_state是一個(gè)可選項(xiàng),若傳入final_state則指示該回合以狀態(tài)final_state結(jié)束。
4) get_batch(batch_size, h_ps)。用以句柄h_ps標(biāo)識(shí)的pick_selector采樣抽取batch_size個(gè)的pick。返回值為一個(gè)元組:(batch_state, batch_action, batch_reward, batch_state_next, seq_len, seq_len_next, batch_pick_epi, batch_pick_pos)。其中,返回量batch_state的形狀比單一state的形狀多出兩維,呈現(xiàn)為(batch_size, pick_len,…,…),即以矩陣形式給出抽取的每個(gè)pick中的每個(gè)時(shí)間點(diǎn)上的state。類似地,batch_action和batch_reward的形狀為(batch_size, pick_len),分別表示每個(gè)pick中的每個(gè)時(shí)間點(diǎn)上的action和reward。batch_state_next形狀與batch_state相同,給出了每個(gè)pick中的每個(gè)時(shí)間點(diǎn)的下一時(shí)刻的state。seq_len和seq_len_next都是長(zhǎng)度為batch_size的向量。如前文所述,由于某些抽取準(zhǔn)則中可能允許抽取不足pick_len長(zhǎng)度的pick,故需要用seq_len和seq_len_next分別反饋batch_state和batch_state_next中每個(gè)pick實(shí)際有效的時(shí)間序列長(zhǎng)度。這樣,抽取出的數(shù)據(jù)中長(zhǎng)于這些實(shí)際長(zhǎng)度的部分才可以被外部的應(yīng)用所忽略。batch_pick_epi和batch_pick_pos分別是pick_epi和pick_pos的向量,長(zhǎng)度也為batch_size。它們用于標(biāo)識(shí)所抽取的每個(gè)pick的來(lái)源,以便set_priority方法反饋更新其優(yōu)先級(jí)。
5) set_priority(h_ps, pick_epi, pick_pos, priority)。針對(duì)以h_ps標(biāo)識(shí)的pick_selector,對(duì)以〈pick_epi, pick_pos〉標(biāo)識(shí)的pick設(shè)置優(yōu)先級(jí)priority。
6) serialize()。序列化導(dǎo)出經(jīng)驗(yàn)回放模塊的數(shù)據(jù),用于持久化保存經(jīng)驗(yàn)池。
7) unserialize()。反序列化,用于從保存的持久化數(shù)據(jù)中恢復(fù)經(jīng)驗(yàn)回放模塊。
2?經(jīng)驗(yàn)回放模塊的架構(gòu)設(shè)計(jì)
由于目前大量的強(qiáng)化學(xué)習(xí)應(yīng)用基于python實(shí)現(xiàn)[16-17],與之相適應(yīng),以往的經(jīng)驗(yàn)回放模塊大多也都由python編寫(xiě)。這使得模塊便于被應(yīng)用系統(tǒng)所調(diào)用。然而,受限于python解釋器本身的效率,此類經(jīng)驗(yàn)回放模塊無(wú)法達(dá)到較高的運(yùn)行性能,進(jìn)而影響整個(gè)應(yīng)用的性能。本文綜合考慮性能和易用性,在架構(gòu)設(shè)計(jì)上采用雙層的軟件結(jié)構(gòu)(如圖 1):基本功能由C++語(yǔ)言實(shí)現(xiàn),以謀求較高的運(yùn)行性能,這些基本功能被導(dǎo)出為動(dòng)態(tài)鏈接庫(kù)中的函數(shù)接口,而后由python編寫(xiě)的包裝類進(jìn)行封裝,以面向?qū)ο蟮男问教峁┙o外部應(yīng)用。這種架構(gòu)兼顧了兩方面的需求,既實(shí)現(xiàn)了性能的優(yōu)化,又便于被python應(yīng)用所使用。下面將介紹上述兩層結(jié)構(gòu)各自的分工及設(shè)計(jì)。
2.1?功能內(nèi)核(C++)
功能內(nèi)核進(jìn)一步分為函數(shù)接口層和數(shù)據(jù)結(jié)構(gòu)層,前者用于實(shí)現(xiàn)內(nèi)核的主要功能,并為python實(shí)現(xiàn)的包裝類提供函數(shù)接口,而后者則包含關(guān)鍵的數(shù)據(jù)結(jié)構(gòu),以及一些底層的算法步驟。
數(shù)據(jù)結(jié)構(gòu)層的EX_RP結(jié)構(gòu)體是內(nèi)核中最關(guān)鍵的數(shù)據(jù)結(jié)構(gòu),其主要包含了一個(gè)稱為“episodes”的映射表(以C++標(biāo)準(zhǔn)模板庫(kù)的map容器承載),以及一個(gè)名為batch_maker的結(jié)構(gòu)體。前者以episode的句柄h_epi為鍵值,存儲(chǔ)指向episode結(jié)構(gòu)體的指針——在單個(gè)episode中,向量(以vector容器承載)states、actions、rewards分別以時(shí)間順序存放每一時(shí)刻的state、action、reward。
batch_maker結(jié)構(gòu)體在對(duì)經(jīng)驗(yàn)數(shù)據(jù)進(jìn)行采樣抽取操作時(shí)至關(guān)重要,其中主要包含兩個(gè)成員向量:pick_table與ps_table。
pick_table中保存了所有episode中可供抽取的pick的訪問(wèn)位置信息,形式為有序?qū)Α磒ick_epi, pick_pos〉,其中的pick_epi實(shí)際是一個(gè)指向episodes中相應(yīng)episode節(jié)點(diǎn)的指針。另一方面,在episode節(jié)點(diǎn)中的向量pick_index則記錄了該episode中可用的pick在pick_table中對(duì)應(yīng)索引項(xiàng)的位置。于是存放于episode中具體的pick數(shù)據(jù)和pick_table中的全局索引可以實(shí)現(xiàn)快速地相互查詢,這一特性在性能優(yōu)化中十分必要(詳見(jiàn)第4章)。
ps_table是用于記錄“抽取選擇器”(pick_selector)的向量,其中保存了指向pick_selector對(duì)象的指針。作為經(jīng)驗(yàn)回放模塊的附屬組件,接口類PickSelector指示一組需要實(shí)現(xiàn)的接口函數(shù),通過(guò)對(duì)這些接口的不同實(shí)現(xiàn),可派生多種PickSelector的子類,形如PickSelectorX,用于實(shí)現(xiàn)不同的優(yōu)先級(jí)回放策略。通過(guò)相應(yīng)的new_pick_selector_X函數(shù)可創(chuàng)建PickSelectorX類型的對(duì)象實(shí)例,并將其指針記錄到ps_table中。而后,其中的接口函數(shù)將在內(nèi)核運(yùn)行的適當(dāng)時(shí)機(jī)被回調(diào)。例如,其中的select函數(shù)將在get_batch過(guò)程中被調(diào)用,以實(shí)現(xiàn)樣本選取的具體行為;而每次向pick_table中添加新pick信息時(shí),on_pick_table_push_back函數(shù)會(huì)被回調(diào),以保證數(shù)據(jù)一致,等等。由于篇幅限制,且此處旨在描述整體架構(gòu),故對(duì)于具體接口定義和實(shí)現(xiàn)不作一一詳述。這種將pick_selector作為附屬組件的做法,將選擇器的實(shí)現(xiàn)與經(jīng)驗(yàn)回放模塊的主體運(yùn)行邏輯分離,使得多樣化的抽取采樣策略能夠靈活地添加并運(yùn)用于系統(tǒng)中,從而增強(qiáng)了模塊的通用性和可擴(kuò)展性。
數(shù)據(jù)結(jié)構(gòu)層之上的函數(shù)接口層實(shí)現(xiàn)了模塊的具體行為:例如,如前文所述,new_pick_selector_X創(chuàng)建類型為PickSelectorX的抽取選擇器實(shí)例,并將其指針記錄到ps_table中;record實(shí)現(xiàn)經(jīng)驗(yàn)數(shù)據(jù)的記錄;get_batch實(shí)現(xiàn)經(jīng)驗(yàn)數(shù)據(jù)的采樣抽取,等。這些接口基本與經(jīng)驗(yàn)回放模塊的外部接口相對(duì)應(yīng),圖1中已展示了其中的一部分,本文將在第4章中詳述其中record和get_batch的一些實(shí)現(xiàn)細(xì)節(jié)。
面向其上層,函數(shù)接口層以動(dòng)態(tài)鏈接庫(kù)形式導(dǎo)出上述接口方法,以便python實(shí)現(xiàn)的包裝類調(diào)用。
2.2?包裝類(python)
python實(shí)現(xiàn)的包裝類ExperienceReplay中包含外部接口的封裝。其利用ctypes模塊導(dǎo)入C++實(shí)現(xiàn)的內(nèi)核動(dòng)態(tài)鏈接庫(kù)后,調(diào)用函數(shù)接口層提供的函數(shù)以實(shí)現(xiàn)模塊的實(shí)質(zhì)功能。此外,該包裝類還提供附加特性,包括線程安全與數(shù)據(jù)形式轉(zhuǎn)換等。
首先,經(jīng)驗(yàn)?zāi)K可能被多線程調(diào)用,故應(yīng)當(dāng)考慮其訪問(wèn)過(guò)程中的線程安全,以確保數(shù)據(jù)的一致性。ExperienceReplay中含有一個(gè)成員變量_mutex,它是一個(gè)threading.Semaphore類型的信號(hào)量。通過(guò)對(duì)_mutex的請(qǐng)求與釋放,可以實(shí)現(xiàn)簡(jiǎn)單的線程安全:ExperienceReplay中的任何方法,在需要“原子性訪問(wèn)”其成員變量或調(diào)用內(nèi)核函數(shù)的代碼段前皆添加了_mutex.acquire(),以請(qǐng)求信號(hào)量,而在訪問(wèn)完成后皆以_mutex.release()釋放信號(hào)量。
其次,對(duì)于數(shù)據(jù)形式的轉(zhuǎn)換主要有兩個(gè)任務(wù):
1) state形狀的維護(hù)。如前文所述,模塊應(yīng)當(dāng)支持各種形狀的state,但內(nèi)核中并不維護(hù)或假設(shè)state的形狀。因此,在ExperienceReplay中,將應(yīng)用層傳入的state形狀保存為成員變量——元組_state_shape,而后將state變形為一維數(shù)組傳入內(nèi)核處理;當(dāng)需要對(duì)外回饋state數(shù)據(jù)時(shí),則應(yīng)當(dāng)以先前保存的形狀_state_shape重塑(reshape)傳出的一維數(shù)組。這一數(shù)據(jù)轉(zhuǎn)換過(guò)程,使得應(yīng)用層能夠使用任意形狀的state。
2) python數(shù)據(jù)類型與C數(shù)據(jù)類型轉(zhuǎn)換。內(nèi)核接口使用C語(yǔ)言風(fēng)格的數(shù)據(jù)類型和數(shù)據(jù)訪問(wèn)方式,而應(yīng)用層卻需要以python風(fēng)格的數(shù)據(jù)類型存儲(chǔ)和使用數(shù)據(jù),ExperienceReplay中為此進(jìn)行了必要的轉(zhuǎn)換。例如,較為復(fù)雜的get_batch操作對(duì)應(yīng)的內(nèi)核函數(shù)接口形式為:
程序前
get_batch(char* ptrER, int hPS, int batch_size,
char* batch_pick_epi, int* batch_pick_pos,
float* batch_state, int* batch_action,
float* batch_reward, float* batch_state_next,
int* seq_len, int* seq_len_next);
程序后
其中,參數(shù)ptrER為欲操作的EX_RP對(duì)象的指針,包裝類初始化時(shí)通過(guò)調(diào)用接口函數(shù)ex_rp_new 已創(chuàng)建了一個(gè)EX_RP對(duì)象并獲取了該指針,保存為成員變量_kernel,故此時(shí)只需直接傳入即可。參數(shù)hPS與batch_size分別指示所使用的選擇器句柄,以及采樣抽取樣本量。對(duì)于python環(huán)境下傳入的任意整型數(shù),可以使用ctypes模塊方法ctypes.int()轉(zhuǎn)換為C語(yǔ)言風(fēng)格整型數(shù)以傳入內(nèi)核接口函數(shù),此處即為:hPS=ctypes.int(hPS)和batch_size=ctypes.int(batch_size)。剩余的參數(shù)皆為傳出數(shù)據(jù)的指針——在包裝類方法中為其申請(qǐng)空間,而后將指針傳入,內(nèi)核將修改地址內(nèi)的數(shù)據(jù),作為處理結(jié)果,之后包裝類則可在這些空間中訪問(wèn)到這些結(jié)果。以batch_action為例,它將用于存儲(chǔ)get_batch結(jié)果中的batch_action分量(其他傳出分量的解釋詳見(jiàn)第1章),形狀應(yīng)當(dāng)是(batch_size, pick_len)。但無(wú)論外部數(shù)據(jù)形狀如何,內(nèi)核函數(shù)的參數(shù)定義皆為一維數(shù)組,故包裝類中應(yīng)當(dāng)先為batch_action申請(qǐng)大小為batch_size*pick_len的一維整型空間并獲得地址指針:batch_action=(ctypes.c_int * (batch_size * pick_len))(),而后將batch_action傳入內(nèi)核。內(nèi)核處理后,將傳出數(shù)據(jù)重塑為具有形狀(batch_size, pick_len)的numpy.array類型數(shù)據(jù)以向應(yīng)用層傳出,即:
程序前
batch_action=
numpy.array(batch_action).reshape([batch_size, pick_len])
程序后
上述數(shù)據(jù)類型的轉(zhuǎn)換,使得應(yīng)用層可以完全使用python風(fēng)格的數(shù)據(jù)類型和數(shù)據(jù)訪問(wèn)方式,而無(wú)需關(guān)注底層較為復(fù)雜繁瑣的實(shí)際數(shù)據(jù)交互,大大增強(qiáng)了模塊的易用性。
除了主要的ExperienceReplay類外,包裝層還將所有用于創(chuàng)建pick_selector的接口函數(shù)new_pick_selector_X封裝于類PickSelectorClass中——PickSelectorClass中名為X的靜態(tài)函數(shù)(帶有修飾符@staticmethod)實(shí)際調(diào)用接口函數(shù)new_pick_selector_X。當(dāng)用戶層調(diào)用ExperienceReplay中的new_pick_selector方法時(shí)需傳入函數(shù)名稱PickSelectorClass.X作為參數(shù),形如:
程序前
new_pick_selector(PickSelectorClass.X)
程序后
而new_pick_selector方法執(zhí)行中將回調(diào)該函數(shù),從而在數(shù)據(jù)結(jié)構(gòu)層創(chuàng)建PickSelectorX類型的實(shí)例。這種接口調(diào)用方式使得應(yīng)用層無(wú)需關(guān)心底層將pick_selector與經(jīng)驗(yàn)回放模塊主體分離的設(shè)計(jì)細(xì)節(jié),更易于理解和使用。
3?實(shí)現(xiàn)細(xì)節(jié)與理論分析
本文提出的經(jīng)驗(yàn)回放模塊在實(shí)現(xiàn)階段主要關(guān)注性能的優(yōu)化。在實(shí)際應(yīng)用中,record、get_batch和set_priority是需要被反復(fù)調(diào)用的三個(gè)接口方法,可能成為實(shí)際應(yīng)用中的性能瓶頸。因此,它們是性能優(yōu)化的重點(diǎn)。其中,set_priority的性能由具體的優(yōu)先級(jí)算法主導(dǎo),不是本文論述的要點(diǎn)。于是,本文著重關(guān)注record和get_batch的性能優(yōu)化。
在實(shí)踐中,由于record操作僅處理單條記錄的插入,而get_batch需要一次性抽取batch_size條記錄,故其時(shí)間開(kāi)銷大約相差batch_size倍,get_batch操作是實(shí)際的性能瓶頸。此外,若經(jīng)驗(yàn)池的容量有限,則在某些時(shí)刻進(jìn)行record操作時(shí)還需考慮記錄的淘汰(刪除),這一操作復(fù)雜度可能較高,需要加以優(yōu)化。綜上,本章將主要討論get_batch操作以及record中記錄淘汰過(guò)程的性能優(yōu)化。
3.1?get_batch操作的性能優(yōu)化
get_batch操作過(guò)程邏輯上需要依pick_policy的規(guī)則整理所有可用的pick,而后利用pick_selector進(jìn)行樣本抽取。若已有樣本(record)規(guī)模為N,則這一過(guò)程的時(shí)間復(fù)雜度可達(dá)O(N)。這是由于在整理可用pick的過(guò)程中需要遍歷所有record,以檢查其是否為可用的pick;即使不預(yù)先整理所有可用pick,為了支持均勻隨機(jī)采樣策略,在樣本抽取步驟中也需要遍歷所有episode,才能實(shí)現(xiàn)在所有record中進(jìn)行無(wú)差別的均勻采樣。這也將使得get_batch操作的時(shí)間開(kāi)銷與N相關(guān)。
對(duì)于get_batch的性能優(yōu)化,本文的指導(dǎo)思想是,將驗(yàn)證pick可用性的步驟移動(dòng)到record操作中完成:當(dāng)一個(gè)新的record被添加到經(jīng)驗(yàn)池中時(shí),立即檢驗(yàn)是否因此增加了一個(gè)可用pick,而當(dāng)可用pick被驗(yàn)證時(shí),它立即被記錄到pick_table中。于是,在get_batch時(shí)無(wú)需再進(jìn)行pick的整理和驗(yàn)證,只需要從全局的pick_table中利用pick_selector進(jìn)行樣本抽取即可。get_batch的步驟為:
1)調(diào)用pick_selector的select接口,以選取batch_size個(gè)pick在pick_table中的位置,記作數(shù)組pick_index。
2)依據(jù)pick_index,在pick_table中取得pick的訪問(wèn)位置信息,即batch_size個(gè)有序?qū)Α磒ick_epi, pick_pos〉。
3)對(duì)每個(gè)被選取的有序?qū)?,根?jù)指針pick_epi訪問(wèn)episode節(jié)點(diǎn),并在pick_pos位置抽取pick數(shù)據(jù)。
上述流程中,除了pick_selector中select接口的具體實(shí)現(xiàn)因抽樣策略而不同,其他步驟的時(shí)間開(kāi)銷皆與樣本規(guī)模N無(wú)關(guān)。對(duì)于select接口,若在均勻隨機(jī)抽樣策略下,其時(shí)間開(kāi)銷本就與N無(wú)關(guān);若采用各種優(yōu)先級(jí)抽取策略,也可采用為與N無(wú)關(guān),或者具有O(lbN)復(fù)雜度的算法過(guò)程,例如同樣可將優(yōu)先級(jí)排序過(guò)程移動(dòng)到record和set_priority操作中完成(實(shí)現(xiàn)于PickSelector的回調(diào)函數(shù)接口on_pick_table_push_back和set_priority中),從而避免在select接口中進(jìn)行耗時(shí)的優(yōu)先級(jí)排序。事實(shí)上,select接口的優(yōu)化方式依賴于專門(mén)設(shè)計(jì)的數(shù)據(jù)結(jié)構(gòu)和算法,是另一個(gè)值得研究的話題,但不是本文討論的重點(diǎn)內(nèi)容,故不作更多展開(kāi)說(shuō)明。
另一方面,將pick可用性的驗(yàn)證移動(dòng)到record操作中,使得record操作增加了驗(yàn)證單個(gè)pick可用性的時(shí)間開(kāi)銷,但這與N的大小無(wú)關(guān),故并不增加record操作的時(shí)間復(fù)雜度。
綜上,按照上述優(yōu)化方式,get_batch操作的時(shí)間復(fù)雜度由具體的抽樣選擇器的select方法決定,可控制在O(1)或者O(logN),且優(yōu)化后不會(huì)提高record操作的時(shí)間復(fù)雜度。因此,模塊的整體運(yùn)行性能可得到提升。
3.2?record操作中記錄淘汰過(guò)程及其性能優(yōu)化
record操作的基本流程為:
1)檢查傳入的句柄h_epi所標(biāo)識(shí)的episode是否存在,若不存在,則調(diào)用new_episode以創(chuàng)建新episode,并將h_epi修改為新句柄。
2)將新的record數(shù)據(jù)寫(xiě)入上述episode。
3)依照pick_policy檢驗(yàn)新的record是否造成可用pick增加,如果生成了新的pick,則將其記錄到pick_table,且將pick在pick_table中記錄的位置寫(xiě)入episode的pick_index。
4)檢查經(jīng)驗(yàn)池中的record數(shù)量是否達(dá)到上限,若達(dá)上限,則觸發(fā)記錄淘汰過(guò)程。
一般而言,上層應(yīng)用應(yīng)直接通過(guò)new_episode操作顯式創(chuàng)建episode,并使用其返回的句柄h_epi來(lái)指代這個(gè)episode。但應(yīng)當(dāng)注意到,所創(chuàng)建出的episode句柄h_epi并非永久有效:若經(jīng)驗(yàn)池容量有限,則當(dāng)記錄數(shù)到達(dá)上限時(shí),步驟4)將會(huì)淘汰某些記錄。本文提出的方案將淘汰某個(gè)episode的所有記錄,于是被淘汰的episode將從池中消失。若此時(shí)上層應(yīng)用中該episode仍活躍(有新記錄產(chǎn)生),則可能再次發(fā)起record操作,這種情況下經(jīng)驗(yàn)回放模塊的行為將是,在步驟1)中重新分配新的episode句柄h_epi,并作為record操作的返回值傳遞給上層應(yīng)用。于是,對(duì)于上層應(yīng)用而言,應(yīng)當(dāng)處理record操作的返回值,以獲知episode的句柄是否發(fā)生了變化。
對(duì)于記錄淘汰過(guò)程,這里需要討論以下兩個(gè)問(wèn)題:
1) 淘汰episode的選擇。這里考慮兩種淘汰策略:先進(jìn)先出(First In First Out,F(xiàn)IFO)策略和二次機(jī)會(huì)(Second Chance)策略。這兩種策略的指導(dǎo)思想皆源于操作系統(tǒng)的頁(yè)面置換算法。
FIFO策略簡(jiǎn)單地依據(jù)episode生成的先后順序選擇擬淘汰的episode:需規(guī)定EX_RP以自增方式生成episode的句柄,即每次new_episode操作從0開(kāi)始依次以自然數(shù)指派新的句柄,下一個(gè)將被分配的句柄值記為EX_RP結(jié)構(gòu)體的成員變量h_epi_head,則句柄大小即可代表episode的新舊程度。維護(hù)一個(gè)成員變量h_epi_tail以記錄當(dāng)前最小的句柄值,則每次淘汰時(shí)直接選擇h_epi_tail所指代的episode即可。淘汰完成后h_epi_tail增加1,從而指向下一個(gè)待淘汰的episode。
二次機(jī)會(huì)策略則需要在每個(gè)episode節(jié)點(diǎn)中添加一個(gè)布爾型成員變量access_flag,用于指示episode是否被采樣抽取過(guò)——每次get_batch操作抽取到一個(gè)pick時(shí),會(huì)將對(duì)應(yīng)episode的access_flag置為true。而在EX_RP結(jié)構(gòu)中,額外維護(hù)一個(gè)成員變量h_epi_remove以記錄下一個(gè)擬淘汰的episode。當(dāng)需要淘汰時(shí),h_epi_remove在h_epi_tail與h_epi_head之間循環(huán)移動(dòng),以查找access_flag為false的episode,將其作為被淘汰的對(duì)象。其間,h_epi_remove掠過(guò)的episode的access_flag將被重置為false——即給予每個(gè)曾被抽取過(guò)的episode一次從淘汰中豁免的機(jī)會(huì)。
實(shí)際應(yīng)用中應(yīng)當(dāng)采用何種淘汰策略,應(yīng)當(dāng)與采樣抽取策略配合:對(duì)于均勻隨機(jī)采樣,經(jīng)驗(yàn)池中的pick均無(wú)差別,則淘汰時(shí)使用FIFO策略即可;而對(duì)于各種優(yōu)先級(jí)采樣,優(yōu)先級(jí)高的pick將更有可能被采樣,在淘汰時(shí)使用二次機(jī)會(huì)策略,可以保證這些價(jià)值較高的pick被盡可能地保留在池中。此外,基于操作系統(tǒng)研發(fā)中十分成熟的頁(yè)面置換算法,容易實(shí)現(xiàn)其他類似的淘汰策略,例如最近最少使用算法(Least Recently Used,LRU)、最不常用算法(Least Frequently Used,LFU)等。
2) 淘汰過(guò)程的性能優(yōu)化。如前文所述,淘汰過(guò)程將從經(jīng)驗(yàn)池中刪除某個(gè)episode的全部記錄,即從episodes中刪除episode對(duì)應(yīng)的節(jié)點(diǎn),并從pick_table中刪除所有屬于該episode的pick信息。前者的時(shí)間開(kāi)銷與全局樣本規(guī)模N無(wú)關(guān),但后者則是在長(zhǎng)度約為N的vector中刪除散放的n個(gè)數(shù)據(jù)項(xiàng)(假設(shè)該episode中包含n條記錄)。按照通常vector中的刪除操作,需要考慮數(shù)據(jù)的成塊挪動(dòng),具有較高時(shí)間開(kāi)銷,整體復(fù)雜度為O(nN)。需要對(duì)其進(jìn)行優(yōu)化。
本文的優(yōu)化思路是,考慮到pick_table中的數(shù)據(jù)無(wú)需保持有序,如圖2所示,若需從中刪除數(shù)據(jù)項(xiàng)i,可將其與pick_table的最后一個(gè)數(shù)據(jù)項(xiàng)j交換,而后再刪除。如此,便可避免數(shù)據(jù)的成塊挪動(dòng)。假設(shè)某時(shí)刻pick_table最后一個(gè)數(shù)據(jù)項(xiàng)的位置為j,pick_table[j]=〈pick_epi, pick_pos〉標(biāo)識(shí)了這最后一個(gè)pick所屬的episode為pick_epi,位置為pick_pos。則刪除某個(gè)episode(記為e)的具體流程為:
① 從e的pick_index向量中依次查找下一個(gè)pick在pick_table中對(duì)應(yīng)索引的位置i,若已達(dá)pick_index的結(jié)尾,則跳轉(zhuǎn)到步驟⑧;
② 若j ≥ 0,則設(shè)e′=pick_index[j].pick_epi,p′= pick_index[j].pick_pos;
③ 若i ≤ j且e′= e,則j=j-1,并回到步驟②;
④ 若i > j,則回到步驟①;
⑤ 修改e′.pick_index[p′]=i;
⑥ 將pick_table[i]與pick_table [j]數(shù)據(jù)交換;
⑦j=j-1,并回到步驟①;
⑧ 刪除pick_table中位于j之后的數(shù)據(jù);
⑨ 從episodes中刪除e。
依上述流程,淘汰一個(gè)episode的時(shí)間復(fù)雜度降為O(n),即僅與擬淘汰episode的記錄數(shù)n有關(guān),而與全局樣本規(guī)模N無(wú)關(guān)。又易知,當(dāng)經(jīng)驗(yàn)池容量滿后,若episode的平均記錄數(shù)為n,則平均每進(jìn)行n次record操作,才會(huì)發(fā)生一次淘汰。于是,淘汰過(guò)程實(shí)際為record帶來(lái)等效于O(1)復(fù)雜度的時(shí)間開(kāi)銷。而不發(fā)生淘汰時(shí)record的時(shí)間開(kāi)銷也僅為O(1),因此,經(jīng)過(guò)上述優(yōu)化后,record操作的整體時(shí)間復(fù)雜度為O(1)。
4?性能測(cè)試與討論
為測(cè)試所提出的方法的實(shí)際執(zhí)行性能,本文設(shè)計(jì)并實(shí)施了一項(xiàng)簡(jiǎn)單的實(shí)驗(yàn)。該測(cè)試實(shí)驗(yàn)運(yùn)行環(huán)境的主要參數(shù)為:Intel Core i77700K CPU 4.2GHz、16GB RAM、Windows 10操作系統(tǒng)。
每次實(shí)驗(yàn)中,模擬一個(gè)假設(shè)的數(shù)據(jù)記錄(record)與樣本抽?。╣et_batch)過(guò)程。首先,假設(shè)有來(lái)自2k個(gè)回合的數(shù)據(jù),每個(gè)回合含有2s條隨機(jī)生成的記錄,故總計(jì)數(shù)據(jù)規(guī)模為N=2k+s條記錄;然后,將這些記錄利用record操作逐條添加進(jìn)空的經(jīng)驗(yàn)池,統(tǒng)計(jì)這一過(guò)程耗費(fèi)的時(shí)間,計(jì)算出平均每100次record操作的時(shí)間開(kāi)銷,記作統(tǒng)計(jì)量record_100;接著,對(duì)這個(gè)經(jīng)驗(yàn)池進(jìn)行10-000次get_batch操作,單次抽取5-000個(gè)記錄片段(batch_size=5-000),每個(gè)片段的時(shí)間長(zhǎng)度為8(pick_len=8),統(tǒng)計(jì)其耗費(fèi)的時(shí)間,從而計(jì)算每次get_batch的平均時(shí)間開(kāi)銷,記作統(tǒng)計(jì)量get_5000。
分別取k=5, 5.5, 6, 6.5, …, 11; s=6, 6.5, 7, 7.5, …, 12,共進(jìn)行169次不同k、s組合的實(shí)驗(yàn),得到一組時(shí)間開(kāi)銷統(tǒng)計(jì)量。為避免計(jì)算機(jī)在運(yùn)行測(cè)試時(shí)由于不可預(yù)期的原因(如后臺(tái)運(yùn)行的其他程序等)造成統(tǒng)計(jì)誤差,上述實(shí)驗(yàn)反復(fù)進(jìn)行了5次。對(duì)于每個(gè)統(tǒng)計(jì)量,皆取得5次實(shí)驗(yàn)的最小值,得到的結(jié)果數(shù)值如表1、2所示。
統(tǒng)計(jì)量record_100與get_5000可視化作圖如圖3與圖4??梢钥吹絩ecord的操作的時(shí)間開(kāi)銷與數(shù)據(jù)的規(guī)模N基本無(wú)關(guān),這與第3章的理論分析相符,且record_100耗時(shí)皆在700μs 左右,即單次record操作耗時(shí)僅7μs,在實(shí)際應(yīng)用中不會(huì)成為性能瓶頸。
另一方面,與理論分析有所不同,從圖4可看出,get_batch操作的時(shí)間開(kāi)銷與數(shù)據(jù)規(guī)模(N=2k+s)相關(guān)。進(jìn)一步繪制數(shù)據(jù)規(guī)模N同get_5000的關(guān)系曲線(相同N值下的多個(gè)get_5000取平均值),如圖5所示。
從圖5可以看到,當(dāng)lb N<16時(shí),時(shí)間開(kāi)銷基本與規(guī)模無(wú)關(guān),當(dāng)lb N ≥ 16時(shí),時(shí)間開(kāi)銷上漲,初期上漲較快,而后期上漲趨勢(shì)逐漸放緩。本文認(rèn)為,之所以get_batch的時(shí)間開(kāi)銷并非完全如理論分析所描述的常數(shù)級(jí)別,是由于記錄抽取操作需要一次性訪問(wèn)大量記錄,這些記錄在內(nèi)存中分散的程度,與數(shù)據(jù)規(guī)模相關(guān):當(dāng)數(shù)據(jù)規(guī)模小于某個(gè)范圍時(shí),內(nèi)存訪問(wèn)較為集中,CPU緩存命中率很高,時(shí)間開(kāi)銷則在很低水平上基本呈現(xiàn)常數(shù)級(jí)復(fù)雜度;但當(dāng)數(shù)據(jù)規(guī)模上升時(shí),CPU緩存命中率將下降,實(shí)際訪存的時(shí)間將被增長(zhǎng),從而導(dǎo)致此時(shí)的時(shí)間開(kāi)銷隨數(shù)據(jù)規(guī)模增長(zhǎng)。
因此,與理論分析不符的時(shí)間開(kāi)銷增長(zhǎng)是由于CPU緩存等硬件級(jí)別或系統(tǒng)優(yōu)化層面上的機(jī)制所導(dǎo)致,與算法本身的性能特性無(wú)關(guān)。而且,可以看到,無(wú)論時(shí)間開(kāi)銷增長(zhǎng)情況如何,在較大的數(shù)據(jù)規(guī)模上,做一次get_batch(5-000條記錄)消耗的時(shí)間也能控制在800μs以下,且增長(zhǎng)速率很低——低于具有O(lbN)理論復(fù)雜度的算法。這一性能是令人滿意的,且不會(huì)在實(shí)際應(yīng)用中形成性能瓶頸。
此外,為對(duì)比以C++為內(nèi)核實(shí)現(xiàn)的經(jīng)驗(yàn)回放與單純依靠python實(shí)現(xiàn)的性能差異,我們還將本文中的C++內(nèi)核替換為python實(shí)現(xiàn)的版本,并嘗試執(zhí)行同樣的測(cè)試。表3展示了僅使用python版本時(shí)record_100與get_5000的耗時(shí)。
可以看到,在純python版本中record_100數(shù)值在500μs左右,即單次record操作耗時(shí)5μs,較本文方法略低。這是由于record操作本身業(yè)務(wù)邏輯簡(jiǎn)單,單次處理數(shù)據(jù)量小,無(wú)論使用python還是C++實(shí)現(xiàn)都十分迅速。因此當(dāng)使用本文的C++與python混合方案時(shí)C++/python間的接口開(kāi)銷使得綜合性能有所損失。
然而,在實(shí)際的DQN應(yīng)用中,模型訓(xùn)練過(guò)程才是性能提升的關(guān)鍵,而record操作無(wú)論從數(shù)據(jù)處理量還是耗時(shí)占比上與get_batch操作相比都不是同個(gè)數(shù)量級(jí)。而且本文的優(yōu)化策略之一就是以合理地犧牲record性能來(lái)提升get_batch的執(zhí)行效率。因此,get_5000數(shù)值對(duì)于性能評(píng)價(jià)才更具實(shí)際意義。
從表3可以看出,僅使用python實(shí)現(xiàn)時(shí)的get_5000高達(dá)33ms以上。對(duì)照表2,這個(gè)數(shù)值是本文提出的方法在同等條件下的約100倍。在實(shí)際的DQN應(yīng)用中,如此低效的get_batch往往比計(jì)算設(shè)備(如GPU等)中模型訓(xùn)練的實(shí)際運(yùn)算過(guò)程還慢,導(dǎo)致計(jì)算設(shè)備不得不等待訓(xùn)練樣本的填充,從而拖累整個(gè)訓(xùn)練過(guò)程。由此可見(jiàn),本文利用C++作為處理內(nèi)核來(lái)替代python實(shí)現(xiàn)的主要優(yōu)勢(shì)在于將get_batch操作的耗時(shí)壓縮至原來(lái)的百分之一左右,從而避免其成為性能瓶頸,使模型計(jì)算設(shè)備無(wú)須等待訓(xùn)練樣本的填充,而達(dá)到更高的設(shè)備利用率。
5?結(jié)語(yǔ)
本文設(shè)計(jì)并實(shí)現(xiàn)了一種高效的經(jīng)驗(yàn)回放模塊以供DQN相關(guān)的應(yīng)用項(xiàng)目使用,所提出的模塊具有易用性好,通用性、可擴(kuò)展性高,執(zhí)行性能高等特點(diǎn)。在設(shè)計(jì)上,該模塊采用兩層結(jié)構(gòu),底層的功能內(nèi)核以C++語(yǔ)言實(shí)現(xiàn),以提供較高的執(zhí)行效率,而上層以python語(yǔ)言封裝并對(duì)外部應(yīng)用提供接口,使得基于python編寫(xiě)的應(yīng)用項(xiàng)目能夠以面向?qū)ο蟮姆绞捷p松調(diào)用。針對(duì)經(jīng)驗(yàn)回放所涉及的關(guān)鍵操作,一些技術(shù)細(xì)節(jié)被充分研究和精心設(shè)計(jì)。例如,將優(yōu)先級(jí)回放機(jī)制作為附屬組件與模塊的主體運(yùn)行邏輯分離、將樣本的可抽取性驗(yàn)證提前到record操作中進(jìn)行、使用高效的記錄淘汰策略與算法等。這些措施使得模塊具有較高的通用性和可擴(kuò)展性,且整體執(zhí)行效率得到了充分優(yōu)化。本文的實(shí)驗(yàn)分析部分驗(yàn)證了模塊的實(shí)際性能,兩個(gè)核心操作record和get_batch皆可被高效執(zhí)行,且與單純使用python實(shí)現(xiàn)的常用方法相比,get_batch操作的性能提升約100倍,從而避免在整個(gè)DQN相關(guān)應(yīng)用中成為性能瓶頸,滿足了實(shí)際應(yīng)用的需要。
參考文獻(xiàn) (References)
[1]SUTTON R S. Learning to predict by the methods of temporal differences[J]. Machine Learning, 1988, 3(1): 9-44.
[2]WATKINS C J C H, DAYAN P. Qlearning[J]. Machine Learning, 1992, 8(3/4): 279-292.
[3]沙宗軒, 薛菲, 朱杰. 基于并行強(qiáng)化學(xué)習(xí)的云機(jī)器人任務(wù)調(diào)度策略[J]. 計(jì)算機(jī)應(yīng)用, 2019, 39(2): 501-508. (SHA Z X, XUE F, ZHU J. Scheduling strategy of cloud robots based on parallel reinforcement learning[J]. Journal of Computer Applications, 2019, 39(2): 501-508.)
[4]SHAKEEL P M, BASKAR S, DHULIPALA V R S, et al. Maintaining security and privacy in health care system using learning based deepQnetworks[J]. Journal of Medical Systems, 2018, 42(10): 186-186.
[5]MNIH V, KAVUKCUOGLU K, SILVER D, et al. Humanlevel control through deep reinforcement learning[J]. Nature, 2015, 518(7540): 529-533.
[6]SILVER D, HUANG A, MADDISON C J, et al. Mastering the game of go with deep neural networks and tree search[J]. Nature, 2016, 529(7587): 484-489.
[7]趙玉婷, 韓寶玲, 羅慶生. 基于deep Qnetwork雙足機(jī)器人非平整地面行走穩(wěn)定性控制方法[J]. 計(jì)算機(jī)應(yīng)用, 2018, 38(9): 2459-2463. (ZHAO Y T, HAN B L, LUO Q S. Walking stability control method based on deep Qnetwork for biped robot on uneven ground[J]. Journal of Computer Applications, 2018, 38(9): 2459-2463.)
[8]ALANSARY A, OKTAY O, LI Y W, et al. Evaluating reinforcement learning agents for anatomical landmark detection[J]. Medical Image Analysis, 2019, 53: 156-164.
[9]ZHU J, ZHU J, WANG Z, et al. Hierarchical decision and control for continuous multitarget problem: policy evaluation with action delay[J]. IEEE Transactions on Neural Networks and Learning Systems, 2019, 30(2): 464-473.
[10]LIN L J. Selfimproving reactive Agents based on reinforcement learning, planning and teaching[J]. Machine Learning, 1992, 8(3/4): 293-321.
[11]WULFING J, KUMAR S S, BOEDECKER J, et al. Adaptive longterm control of biological neural networks with deep reinforcement learning[J]. Neurocomputing, 2019, 342: 66-74.
[12]HOCHREITER S, SCHMIDHUBER J. Long shortterm memory[J]. Neural Computation, 1997, 9: 1735-1780.
[13]KIM J J, CHA S H, CHO K H, et al. Deep reinforcement learning based multiAgent collaborated network for distributed stock trading[J]. International Journal of Grid and Distributed Computing, 2018, 11(2): 11-20.
[14]朱斐, 吳文, 劉全, 等. 一種最大置信上界經(jīng)驗(yàn)采樣的深度Q網(wǎng)絡(luò)方法[J]. 計(jì)算機(jī)研究與發(fā)展, 2018, 55(8): 1694-1705.(ZHU F, WU W, LIU Q, et al. A deep Qnetwork method based on upper confidence bound experience sampling[J]. Journal of Computer Research and Development, 2018, 55(8): 1694-1705.)
[15]BRUIN T D, KOBER J, TUYLS K, et al. Experience selection in deep reinforcement learning for control[J]. Journal of Machine Learning Research, 2018, 19: 1-56.
[16]YOU S X, DIAO M, GAO L P. Deep reinforcement learning for target searching in cognitive electronic warfare[J]. IEEE Access, 2019, 7: 37432-37447.
[17]LEI X Y, ZHANG Z A, DONG P F. Dynamic path planning of unknown environment based on deep reinforcement learning[J]. Journal of Robotics, 2018, 2018: Article ID 5781591.
This work is partially supported by the Natural Science Foundation of Fujian Province (2016J01294).
CHEN Bo, born in 1984, Ph. D., associate professor. His research interests include artificial intelligence, multiAgent simulation.
WANG Jinyan, born in 1995, M. S. candidate. Her research interests include machine learning, multiAgent simulation.