簡體   English   中英

為什么我的Deep Q Network不能掌握簡單的Gridworld(Tensorflow)? (如何評估Deep-Q-Net)

[英]Why doesn't my Deep Q Network master a simple Gridworld (Tensorflow)? (How to evaluate a Deep-Q-Net)

我嘗試熟悉Q-learning和Deep Neural Networks,目前嘗試使用Deep Reinforcement Learning實現Play Atari

為了測試我的實現並玩它,我試着嘗試一個簡單的gridworld。 我有一個N x N網格,從左上角開始,在右下角結束。 可能的操作是:向左,向上,向右,向下。

即使我的實現與非常相似(希望它是一個好的),它似乎似乎沒有學到任何東西。 看看它需要完成的總步數(我猜平均值將達到500,網格大小為10x10,但也有非常低和高的值),它對我來說比其他任何東西都更隨機。

我嘗試使用和不使用卷積層並使用所有參數,但說實話,我不知道我的實現是否有問題或需要更長時間訓練(我讓它訓練了很長時間)或者什么永遠。 但至少它接縫會聚,這里是一個訓練課程的損失值的情節:

損失圖像

那么這種情況下的問題是什么?

但也可能更重要的是我如何“調試”這個Deep-Q-Nets,在監督培訓中有訓練,測試和驗證集,例如精確和召回,可以對它們進行評估。 對於使用Deep-Q-Nets的無監督學習,我有哪些選擇,以便下次我可以自己修復它?

最后這里是代碼:

這是網絡:

ACTIONS = 5

# Inputs
x = tf.placeholder('float', shape=[None, 10, 10, 4])
y = tf.placeholder('float', shape=[None])
a = tf.placeholder('float', shape=[None, ACTIONS])

# Layer 1 Conv1 - input
with tf.name_scope('Layer1'):
    W_conv1 = weight_variable([8,8,4,8])
    b_conv1 = bias_variable([8])    
    h_conv1 = tf.nn.relu(conv2d(x, W_conv1, 5)+b_conv1)

# Layer 2 Conv2 - hidden1 
with tf.name_scope('Layer2'):
    W_conv2 = weight_variable([2,2,8,8])
    b_conv2 = bias_variable([8])
    h_conv2 = tf.nn.relu(conv2d(h_conv1, W_conv2, 1)+b_conv2)
    h_conv2_max_pool = max_pool_2x2(h_conv2)

# Layer 3 fc1 - hidden 2
with tf.name_scope('Layer3'):
    W_fc1 = weight_variable([8, 32])
    b_fc1 = bias_variable([32])
    h_conv2_flat = tf.reshape(h_conv2_max_pool, [-1, 8])
    h_fc1 = tf.nn.relu(tf.matmul(h_conv2_flat, W_fc1)+b_fc1)

# Layer 4 fc2 - readout
with tf.name_scope('Layer4'):
    W_fc2 = weight_variable([32, ACTIONS])
    b_fc2 = bias_variable([ACTIONS])
    readout = tf.matmul(h_fc1, W_fc2)+ b_fc2

# Training
with tf.name_scope('training'):
    readout_action = tf.reduce_sum(tf.mul(readout, a), reduction_indices=1)
    loss = tf.reduce_mean(tf.square(y - readout_action))
    train = tf.train.AdamOptimizer(1e-6).minimize(loss)

    loss_summ = tf.scalar_summary('loss', loss)

在這里培訓:

# 0 => left
# 1 => up
# 2 => right
# 3 => down
# 4 = noop

ACTIONS = 5
GAMMA = 0.95
BATCH = 50
TRANSITIONS = 2000
OBSERVATIONS = 1000
MAXSTEPS = 1000

D = deque()
epsilon = 1

average = 0
for episode in xrange(1000):
    step_count = 0
    game_ended = False

    state = np.array([0.0]*100, float).reshape(100)
    state[0] = 1

    rsh_state = state.reshape(10,10)
    s = np.stack((rsh_state, rsh_state, rsh_state, rsh_state), axis=2)

    while step_count < MAXSTEPS and not game_ended:
        reward = 0
        step_count += 1

        read = readout.eval(feed_dict={x: [s]})[0]

        act = np.zeros(ACTIONS)
        action = random.randint(0,4)
        if len(D) > OBSERVATIONS and random.random() > epsilon:
            action = np.argmax(read)
        act[action] = 1

        # play the game
        pos_idx = state.argmax(axis=0)
        pos = pos_idx + 1

        state[pos_idx] = 0
        if action == 0 and pos%10 != 1: #left
            state[pos_idx-1] = 1
        elif action == 1 and pos > 10: #up
            state[pos_idx-10] = 1
        elif action == 2 and pos%10 != 0: #right
            state[pos_idx+1] = 1
        elif action == 3 and pos < 91: #down
            state[pos_idx+10] = 1
        else: #noop
            state[pos_idx] = 1
            pass

        if state.argmax(axis=0) == pos_idx and reward > 0:
            reward -= 0.0001

        if step_count == MAXSTEPS:
            reward -= 100
        elif state[99] == 1: # reward & finished
            reward += 100
            game_ended = True
        else:
            reward -= 1


        s_old = np.copy(s)
        s = np.append(s[:,:,1:], state.reshape(10,10,1), axis=2)

        D.append((s_old, act, reward, s))
        if len(D) > TRANSITIONS:
            D.popleft()

        if len(D) > OBSERVATIONS:
            minibatch = random.sample(D, BATCH)

            s_j_batch = [d[0] for d in minibatch]
            a_batch = [d[1] for d in minibatch]
            r_batch = [d[2] for d in minibatch]
            s_j1_batch = [d[3] for d in minibatch]

            readout_j1_batch = readout.eval(feed_dict={x:s_j1_batch})
            y_batch = []

            for i in xrange(0, len(minibatch)):
                y_batch.append(r_batch[i] + GAMMA * np.max(readout_j1_batch[i]))

            train.run(feed_dict={x: s_j_batch, y: y_batch, a: a_batch})

        if epsilon > 0.05:
            epsilon -= 0.01

我感謝您的每一個幫助和想法!

對於那些感興趣的人,我進一步調整了參數和模型,但最大的改進是切換到隱藏層中有3層和大約50個神經元的簡單前饋網絡。 對我而言,它在相當不錯的時間匯聚。

Btw進一步的調試提示表示贊賞!

所以很久以前我寫了這個問題,但是它仍然有一些興趣和對運行代碼的請求我最終決定創建一個github存儲庫

因為它是很久以前我寫的,所以它不會開箱即用,但它應該不是那么難以運行。 所以這里是深q網絡和我當時寫的例子,然后工作,希望你喜歡: 鏈接到深q庫

很高興看到一些貢獻,如果你修復它並讓它運行發出拉動請求!

我已經實現了一個沒有CNN層的簡單玩具DQN,它可以工作。 以下是我實施過程中的一些發現,希望對您有所幫助。

  1. 根據DeepMind的論文,他們沒有使用max pooling層,原因是圖像將變為位置不變,這對游戲不利。 代理人的位置對於游戲信息至關重要。 DQN架構

  2. 如果你想跳過CNN首次使用健身房環境(就像我為玩具實施所做的那樣),在我的開發過程中,我發現了以下幾件事:

    • 通過單熱編碼對您的環境狀態進行編碼,這將提高培訓效率。
    • 我只使用具有[狀態數,動作數]形狀的權重矩陣來進行矩陣乘法,輸入一熱編碼狀態。 沒有偏見,沒有激活功能(它會增加訓練時間,我認為,在我添加其他層或任何東西后它永遠不會工作)。

這是我發現對我的實現工作至關重要的兩件事,我不完全理解它背后的原因,希望我的回答可以給你一點點洞察力。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM