Próbuję zapoznać się z Q-learning i Deep Neural Networks, obecnie próbuję implementować Playing Atari with Deep Reinforcement Learning.Dlaczego moja sieć Deep Q nie opanowała prostego Gridworld (Tensorflow)? (Jak ocenić Deep-Q-Net)
Aby przetestować moją implementację i pogawędzić z nią, pomyślałem, że wypróbuję prosty gridworld. Gdzie mam N x N Grid i zacznij w lewym górnym rogu i kończy się w prawym dolnym rogu. Możliwe działania to: lewo, góra, prawo, dół.
Mimo że moja implementacja stała się bardzo podobna do this (mam nadzieję, że jest dobra), nie wydaje się, aby cokolwiek się nauczyć. Patrząc na całkowite kroki, które trzeba ukończyć (myślę, że średnia wyniosłaby 500 z siłą 10x10, ale są tam również bardzo niskie i wysokie wartości), to szwy są bardziej losowe niż cokolwiek innego.
Próbowałem go bez warstw splotu i bawiłem się wszystkimi parametrami, ale szczerze mówiąc, nie mam pojęcia, czy coś z moją implementacją jest zła, czy musi trenować dłużej (pozwoliłem jej trenować przez dość czas) lub co jeszcze. Ale przynajmniej szwy na zbiegają się tutaj fabuła wartości utrata jednej sesji treningowej:
Więc co jest problemem w tym przypadku?
Ale także, a może, co ważniejsze, jak mogę "debugować" te Deep-Q-Nets, w nadzorowanym szkoleniu są zestawy szkoleniowe, testowe i walidacyjne i na przykład z precyzją i przywołaniem można je ocenić. Jakie mam opcje uczenia bez nadzoru z użyciem Deep-Q-Nets, aby następnym razem sam mógłbym to naprawić?
Wreszcie oto kod:
Jest to sieć:
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)
I tu szkolenia:
# 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
Doceniam każdą pomoc i pomysły może masz!
Moim pierwszym instynktem są warstwy nawinięć, a maksymalne łączenie powoduje, że agent traci szczegóły dotyczące lokalizacji siatek/obiektów/graczy, co ma znaczenie w sieci. Być może spróbuj użyć puli średniej zamiast puli maksymalnej? – Adam
Zobacz mój awnser ale w każdym razie dzięki miło mieć więcej wnętrz ale IT może nie warto spróbować zobaczyć trochę czasu :) – natschz
Dobre pytanie, walczę z tym samym problemem przez około 5 tygodni i nie mogę się dowiedzieć, co jest nie tak. Sieć jest zbieżna poprzez sprawdzenie wartości strat, ale nagroda w postaci 100 kroków wciąż jest zbyt niska. Być może potrzebuję wykonać więcej pracy przy debugowaniu DQN, uprościć sieć jest wyborem (po prostu dodaję zbyt wiele rzeczy do sieci: CNN/Duel-DQN/Double DQN ...). –