在做project的時候接觸到DQN(deep Q-Network)和一個超強大的package,gym。在這裡就寫一寫如何用

DQN網路

去進行玩遊戲。

1。什麼是DQN網路:

在強化學習當中,比較著名的一個演算法是Q-learning演算法,它的核心思想是先初始化一個Q表,然後根據以下式子不斷迭代更新這個Q表,直到收斂,那麼這個Q表就是我們需要求的最優策略。

Q(S,A) + \alpha(R+\gamma \max_aQ(S

其中S代表當前狀態,A是執行的動作,

S

是在狀態S下執行動作A之後的狀態。具體就不詳細多說了,有興趣的個人覺得這篇部落格講的挺不錯的

但是在實際生產環境中,有時候這個Q表會很大,儲存和更新會消耗大量的計算資源,甚至有些超大的Q表根本不可能進行完整儲存。那麼當問題的狀態集合規模很大的時候,一個可行的建模方法是

價值函式

的近似表示(Value Function Approximation)。

我們首先引入一個

狀態價值函式

\hat{v}

,這個這個函式由引數

w

描述,並且接受狀態

s

作為輸入,計算後得到的狀態

s

的價值,就是我們的期望:

\hat{v}(s, w) \approx v_{\pi}(s)

類似的我們可以引入一個

動作價值函式

\hat{q}

\hat{q}(s,a,w) \approx q_{\pi}(s,a)

價值函式近似的方法有很多,最簡單的我們可以有線性表示法,用

\phi (s)

表示狀態

s

的特徵向量,那麼這個時候狀態價值函式我們可以近似表示為:

\hat{v}(s, w) = \phi(s)^Tw

除了線性表示法之後,我們還可以用決策樹,最近領,神經網路來表達

狀態函式

。那麼當Q-learning中的Q表用神經網路的方法來進行價值函式近似,這就叫做Deep Q-learning ,簡稱DQN。下面我們將用一個程式程式碼來演示一下DQN的實際情況。

2。什麼是Gym

Gym是強化學習中很強大的一個包,有了它我們可以把更多的精力放在演算法的構建上面,而不需要花費過多的時間去搭建環境,下面我簡單的說一下gym的使用

我們先對 OpenAI 的 gym 庫的幾個核心概念作個簡單介紹。

想象一下你在玩貪吃蛇,你需要分析當前遊戲的

狀態(State)

,例如你所處的位置,周圍的障礙物等,才能夠決定下一步的

動作(Action)

,上下左右。那你每走一步,就會得到一個

獎勵(Reward)

。這個獎勵可能是正向獎勵(Positive Reward),也可能是負向獎勵(Negative Reward),比如撞到了障礙物。重複N次這樣的過程,直到遊戲

結束(Done)

下面我們用一個gym中最經典的一個遊戲環境Cartpole Game來熟悉一下這幾個概念的含義。在這個例子中,Action是隨機選擇的。

import

gym

import

random

import

time

env

=

gym

make

“CartPole-v0”

# 載入遊戲環境

state

=

env

reset

()

score

=

0

while

True

time

sleep

0。1

env

render

()

# 顯示畫面

action

=

random

randint

0

1

# 隨機選擇一個動作 0 或 1

state

reward

done

_

=

env

step

action

# 執行這個動作

score

+=

reward

# 每回合的得分

if

done

# 遊戲結束

print

‘score: ’

score

# 列印分數

break

env

close

()

強化學習應用篇----用DQN玩遊戲

下面我們用一個簡單的小車爬坡的遊戲來實現一下DQN

from

collections

import

deque

import

random

import

gym

import

numpy

as

np

from

tensorflow。keras

import

models

layers

optimizers

class

DQN

object

):

def

__init__

self

):

self

step

=

0

self

update_freq

=

200

# 模型更新頻率

self

replay_size

=

2000

# 訓練集大小

self

replay_queue

=

deque

maxlen

=

self

replay_size

self

model

=

self

create_model

()

self

target_model

=

self

create_model

()

def

create_model

self

):

“”“建立一個隱藏層為100的神經網路”“”

STATE_DIM

ACTION_DIM

=

2

3

model

=

models

Sequential

([

layers

Dense

100

input_dim

=

STATE_DIM

activation

=

‘relu’

),

layers

Dense

ACTION_DIM

activation

=

“linear”

])

model

compile

loss

=

‘mean_squared_error’

optimizer

=

optimizers

Adam

0。001

))

return

model

def

act

self

s

epsilon

=

0。1

):

“”“預測動作”“”

# 剛開始時,加一點隨機成分,產生更多的狀態

if

np

random

uniform

()

<

epsilon

-

self

step

*

0。0002

return

np

random

choice

([

0

1

2

])

return

np

argmax

self

model

predict

np

array

([

s

]))[

0

])

def

save_model

self

file_path

=

‘MountainCar-v0-dqn。h5’

):

print

‘model saved’

self

model

save

file_path

def

remember

self

s

a

next_s

reward

):

“”“歷史記錄,position >= 0。4時給額外的reward,快速收斂”“”

if

next_s

0

>=

0。4

reward

+=

1

self

replay_queue

append

((

s

a

next_s

reward

))

def

train

self

batch_size

=

64

lr

=

1

factor

=

0。95

):

if

len

self

replay_queue

<

self

replay_size

return

self

step

+=

1

# 每 update_freq 步,將 model 的權重賦值給 target_model

if

self

step

%

self

update_freq

==

0

self

target_model

set_weights

self

model

get_weights

())

replay_batch

=

random

sample

self

replay_queue

batch_size

s_batch

=

np

array

([

replay

0

for

replay

in

replay_batch

])

next_s_batch

=

np

array

([

replay

2

for

replay

in

replay_batch

])

Q

=

self

model

predict

s_batch

Q_next

=

self

target_model

predict

next_s_batch

# 使用公式更新訓練集中的Q值

for

i

replay

in

enumerate

replay_batch

):

_

a

_

reward

=

replay

Q

i

][

a

=

1

-

lr

*

Q

i

][

a

+

lr

*

reward

+

factor

*

np

amax

Q_next

i

]))

# 傳入網路進行訓練

self

model

fit

s_batch

Q

verbose

=

0

然後是訓練網路

env

=

gym

make

‘MountainCar-v0’

episodes

=

1000

# 訓練1000次

score_list

=

[]

# 記錄所有分數

agent

=

DQN

()

for

i

in

range

episodes

):

s

=

env

reset

()

score

=

0

while

True

a

=

agent

act

s

next_s

reward

done

_

=

env

step

a

agent

remember

s

a

next_s

reward

agent

train

()

score

+=

reward

s

=

next_s

if

done

score_list

append

score

print

‘episode:’

i

‘score:’

score

‘max:’

max

score_list

))

break

# 最後10次的平均分大於 -160 時,停止並儲存模型

if

np

mean

score_list

-

10

:])

>

-

160

agent

save_model

()

break

env

close

()

訓練完之後,我們載入這個模型,看看實際的效果

import

time

import

gym

import

numpy

as

np

from

tensorflow。keras

import

models

env

=

gym

make

‘MountainCar-v0’

model

=

models

load_model

‘MountainCar-v0-dqn。h5’

s

=

env

reset

()

score

=

0

while

True

env

render

()

time

sleep

0。01

a

=

np

argmax

model

predict

np

array

([

s

]))[

0

])

s

reward

done

_

=

env

step

a

score

+=

reward

if

done

print

‘score:’

score

break

env

close

()

其實gym裡面還有很多有趣的遊戲,不過有的訓練量有點大,小破電腦撐不住,這裡就先搞這一個看看