增強模型的探索能力-強化學(xué)習(xí)NoisyNet原理及實現(xiàn)!

增加Agent的探索能力是強化學(xué)習(xí)中經(jīng)常遇到的問題缝驳,一種常用的方法是采用e-greedy的策略连锯,即以e的概率采取隨機的動作归苍,以1-e的概率采取當(dāng)前獲得價值最大的動作。本文我們將介紹另一種方法:NoisyNet运怖,該方法通過對參數(shù)增加噪聲來增加模型的探索能力拼弃。

1、NoisyNet的原理

我們的噪聲通常添加在全連接層摇展,考慮我們?nèi)B接層的前向計算公式:

假設(shè)兩層的神經(jīng)元個數(shù)分別為p個和q個吻氧,那么w是q*p的,x是p維的咏连,y和b都是q維的龟虎。

此時我們在參數(shù)上增加噪聲已艰,文章中假設(shè)每一個參數(shù)b和w分別服從于均值為μ序苏,方差為σ的正態(tài)分布绿饵,同時存在一定的隨機噪聲ε,我們可以假設(shè)噪聲是服從標(biāo)準(zhǔn)正態(tài)分布N(0,1)的踱启。那么前向計算公式變?yōu)椋?/p>

這樣报账,我們模型的變量從原來的p*q + q個,變?yōu)榱? * p * q + q個埠偿,你可能會問透罢,變量不是3 * p * q + q個么?因為這里冠蒋,我們的噪聲ε在每一輪中羽圃,都是隨機產(chǎn)生的常量,試想如果噪聲ε也是變量的話抖剿,就跟原有的wx+b沒有什么區(qū)別了朽寞。

接下來就是這個噪聲如何產(chǎn)生的問題了。文中提到了兩種方法:

Independent Gaussian noise:這也是我們最容易想到的方法斩郎,就是直接從標(biāo)準(zhǔn)正態(tài)分布中脑融,隨機產(chǎn)生p*q+q個常量。這也就是說缩宜,對于每一個全連接層來說肘迎,為每一個w和b都產(chǎn)生獨立的噪聲,這無疑對于模型的計算帶來了不小的負擔(dān)锻煌。

Factorised Gaussian noise:該方法有效地減少了噪聲的個數(shù)妓布,我們只需要p + q個噪聲即可,w和b的噪聲計算方式如下:

而上式中的f所代表的函數(shù)如下:

了解了如何給參數(shù)增加噪聲宋梧,我們就可以把這種方法應(yīng)用于DQN或者AC等方法中匣沼。

2、NoisyNet的TF實現(xiàn)

代碼的地址為:https://github.com/princewen/tensorflow_practice/tree/master/RL/Basic-NoisyNet-Demo

這里實現(xiàn)的是使用DQN來玩Atrai游戲的Demo捂龄。關(guān)于DQN的整體實現(xiàn)思路释涛,我們就不在細講了加叁,這里重點介紹一下eval-net的構(gòu)建以及其中最重點的帶噪聲的全連接層的實現(xiàn)。

我們這里的網(wǎng)絡(luò)結(jié)構(gòu)是兩層卷積層 + 三層全連接層枢贿,輸入是當(dāng)前的狀態(tài)殉农,即三幀的游戲畫面,輸出是上下左右共四個動作的預(yù)估Q值:

def build_layers(self, state, c_names, units_1, units_2, w_i, b_i, reg=None):
    with tf.variable_scope('conv1'):
        conv1 = conv(state, [5, 5, 3, 6], [6], [1, 2, 2, 1], w_i, b_i)
    with tf.variable_scope('conv2'):
        conv2 = conv(conv1, [3, 3, 6, 12], [12], [1, 2, 2, 1], w_i, b_i)
    with tf.variable_scope('flatten'):
        flatten = tf.contrib.layers.flatten(conv2)
        # 兩種reshape寫法
        # flatten = tf.reshape(relu5, [-1, np.prod(relu5.get_shape().as_list()[1:])])
        # flatten = tf.reshape(relu5, [-1, np.prod(relu5.shape.as_list()[1:])])
        # print flatten.get_shape()
    with tf.variable_scope('dense1'):
        dense1 = noisy_dense(flatten, units_1, [units_1], c_names, w_i, b_i, noisy_distribution=self.config.noisy_distribution)
    with tf.variable_scope('dense2'):
        dense2 = noisy_dense(dense1, units_2, [units_2], c_names, w_i, b_i, noisy_distribution=self.config.noisy_distribution)
    with tf.variable_scope('dense3'):
        dense3 = noisy_dense(dense2, self.action_dim, [self.action_dim], c_names, w_i, b_i, noisy_distribution=self.config.noisy_distribution)
    return dense3

接下來局荚,我們重點介紹一下之中noisy_dense的實現(xiàn)。首先愈污,我們得到每個w的均值和方差的估計:

weights = tf.get_variable('weights', shape=[flatten_shape, units], initializer=w_i)
w_sigma = tf.get_variable('w_sigma', [flatten_shape, units], initializer=w_i, collections=c_names)

如果噪聲采用Independent Gaussian noise的方式耀态,我們接下來需要得到p*q個的隨機噪聲,并得到最終的w:

if noisy_distribution == 'independent':
    weights += tf.multiply(tf.random_normal(shape=w_sigma.shape), w_sigma)

如果噪聲采用Factorised Gaussian noise的方式暂雹,我們需要得到p + q個噪聲首装,并對這些噪聲進行變換,最終得到w:

elif noisy_distribution == 'factorised':
    noise_1 = f(tf.random_normal(tf.TensorShape([flatten_shape, 1]), dtype=tf.float32))  # 注意是列向量形式杭跪,方便矩陣乘法
    noise_2 = f(tf.random_normal(tf.TensorShape([1, units]), dtype=tf.float32))
    weights += tf.multiply(noise_1 * noise_2, w_sigma)

其中變換的代碼如下:

  def f(e_list):
    return tf.multiply(tf.sign(e_list), tf.pow(tf.abs(e_list), 0.5))

接下來仙逻,進行全連接的操作:

dense = tf.matmul(inputs, weights)

最后,如果有偏置項的話涧尿,我們同樣通過不同的方式為偏置項增加噪聲:

if bias_shape is not None:
    assert bias_shape[0] == units
    biases = tf.get_variable('biases', shape=bias_shape, initializer=b_i)
    b_noise = tf.get_variable('b_noise', [1, units], initializer=b_i, collections=c_names)
    if noisy_distribution == 'independent':
        biases += tf.multiply(tf.random_normal(shape=b_noise.shape), b_noise)
    elif noisy_distribution == 'factorised':
        biases += tf.multiply(noise_2, b_noise)

最后系奉,經(jīng)過激活函數(shù)得到最后的輸出:

return activation(dense) if activation is not None else dense

完整noise_dense的函數(shù)如下:

def noisy_dense(inputs, units, bias_shape, c_names, w_i, b_i=None, activation=tf.nn.relu, noisy_distribution='factorised'):
    def f(e_list):
        return tf.multiply(tf.sign(e_list), tf.pow(tf.abs(e_list), 0.5))

    if not isinstance(inputs, ops.Tensor):
        inputs = ops.convert_to_tensor(inputs, dtype='float')

    if len(inputs.shape) > 2:
        inputs = tf.contrib.layers.flatten(inputs)
    flatten_shape = inputs.shape[1]
    weights = tf.get_variable('weights', shape=[flatten_shape, units], initializer=w_i)
    w_sigma = tf.get_variable('w_sigma', [flatten_shape, units], initializer=w_i, collections=c_names)
    if noisy_distribution == 'independent':
        weights += tf.multiply(tf.random_normal(shape=w_sigma.shape), w_sigma)
    elif noisy_distribution == 'factorised':
        noise_1 = f(tf.random_normal(tf.TensorShape([flatten_shape, 1]), dtype=tf.float32))  # 注意是列向量形式,方便矩陣乘法
        noise_2 = f(tf.random_normal(tf.TensorShape([1, units]), dtype=tf.float32))
        weights += tf.multiply(noise_1 * noise_2, w_sigma)
    dense = tf.matmul(inputs, weights)
    if bias_shape is not None:
        assert bias_shape[0] == units
        biases = tf.get_variable('biases', shape=bias_shape, initializer=b_i)
        b_noise = tf.get_variable('b_noise', [1, units], initializer=b_i, collections=c_names)
        if noisy_distribution == 'independent':
            biases += tf.multiply(tf.random_normal(shape=b_noise.shape), b_noise)
        elif noisy_distribution == 'factorised':
            biases += tf.multiply(noise_2, b_noise)
        return activation(dense + biases) if activation is not None else dense + biases
    return activation(dense) if activation is not None else dense

說點題外話姑廉,這個方法我是通過《強化學(xué)習(xí)精要:核心算法與Tensorflow》這本書看到的缺亮,書中對該方法的描述好像與論文和github上代碼中所描述的有所出入,書中好像是把變量的方差當(dāng)作噪聲了桥言。如果大家看過這本書同時也看過原作萌踱,如果覺得書中寫的沒有問題而本文寫的有錯誤的話,歡迎大家在下方留言指正号阿!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末并鸵,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子扔涧,更是在濱河造成了極大的恐慌园担,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,273評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件扰柠,死亡現(xiàn)場離奇詭異粉铐,居然都是意外死亡,警方通過查閱死者的電腦和手機卤档,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評論 3 398
  • 文/潘曉璐 我一進店門蝙泼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人劝枣,你說我怎么就攤上這事汤踏≈ǎ” “怎么了?”我有些...
    開封第一講書人閱讀 167,709評論 0 360
  • 文/不壞的土叔 我叫張陵溪胶,是天一觀的道長搂擦。 經(jīng)常有香客問我,道長哗脖,這世上最難降的妖魔是什么瀑踢? 我笑而不...
    開封第一講書人閱讀 59,520評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮才避,結(jié)果婚禮上橱夭,老公的妹妹穿的比我還像新娘。我一直安慰自己桑逝,他們只是感情好棘劣,可當(dāng)我...
    茶點故事閱讀 68,515評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著楞遏,像睡著了一般茬暇。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上寡喝,一...
    開封第一講書人閱讀 52,158評論 1 308
  • 那天糙俗,我揣著相機與錄音,去河邊找鬼拘荡。 笑死臼节,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的珊皿。 我是一名探鬼主播网缝,決...
    沈念sama閱讀 40,755評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼蟋定!你這毒婦竟也來了粉臊?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,660評論 0 276
  • 序言:老撾萬榮一對情侶失蹤驶兜,失蹤者是張志新(化名)和其女友劉穎扼仲,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體抄淑,經(jīng)...
    沈念sama閱讀 46,203評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡屠凶,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,287評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了肆资。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片矗愧。...
    茶點故事閱讀 40,427評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖郑原,靈堂內(nèi)的尸體忽然破棺而出唉韭,到底是詐尸還是另有隱情夜涕,我是刑警寧澤,帶...
    沈念sama閱讀 36,122評論 5 349
  • 正文 年R本政府宣布属愤,位于F島的核電站女器,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏住诸。R本人自食惡果不足惜驾胆,卻給世界環(huán)境...
    茶點故事閱讀 41,801評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望只壳。 院中可真熱鬧俏拱,春花似錦、人聲如沸吼句。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽惕艳。三九已至,卻和暖如春驹愚,著一層夾襖步出監(jiān)牢的瞬間远搪,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工逢捺, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留谁鳍,地道東北人。 一個月前我還...
    沈念sama閱讀 48,808評論 3 376
  • 正文 我出身青樓劫瞳,卻偏偏與公主長得像倘潜,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子志于,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,440評論 2 359

推薦閱讀更多精彩內(nèi)容

  • 1乳腺增生 很多女性都有乳房脹痛杖挣、乳腺增生的問題肩榕,其中不少和愛生氣有關(guān);產(chǎn)后心情不好程梦,容易發(fā)生乳腺炎点把;中老年人更可...
    好醫(yī)道閱讀 173評論 0 0
  • 2017.4.5白話版 1橘荠、我們先回顧一下熊老師上周末曾留下的一個問題:如果我爺爺?shù)臓敔斊圬摿四銧敔數(shù)臓敔敚阍摬?..
    祥和鴻泰閱讀 207評論 1 1
  • 大學(xué)郎逃,應(yīng)該是戀愛最美好的時候哥童,因為不再像高中那樣,因為再不會有老師因為覺得早戀影響學(xué)習(xí)而各種想方設(shè)拆散我們一對對可...
    Mercy_8fa8閱讀 165評論 0 0
  • 20180612星期二 天氣晴 時間過的真快啊褒翰,第二學(xué)期已進入復(fù)習(xí)階段了贮懈,還是慢調(diào)斯文地學(xué)習(xí)的話,很快就...
    璇戎爸爸閱讀 201評論 0 0
  • 隨筆 寫作是需要契機的优训,正如現(xiàn)在的我一樣朵你,聽著莫名的歌,抒發(fā)著莫名的情緒揣非!其實我本身是一個簡單的糾結(jié)體抡医,我時常想寫...
    柳陽love閱讀 197評論 0 0