Nachdem ich die folgenden Artikel gelesen hatte, war ich beeindruckt, dass DQN (Deep Q-Network) interessant zu sein scheint. Das kürzlich besprochene über Alpha-Go ist auch eine Erweiterung von DQN ... oder? (Ich verstehe nicht) Geschichte von DQN + Deep Q-Network in Chainer geschrieben DQN (Deep Q Network) Lernen mit invertiertem Pendel Spielen mit maschinellem Lernen mit Chainer: Können Sie das Lernen von Zusatzspielen mit Chainer verbessern?
Deshalb habe ich versucht, es mit TensorFlow zu implementieren ... (-_-;)? ?? ?? Ich bin mir nicht sicher. Nein, das Problem ist, dass ich es versuche, ohne die Theorie und Formeln zu verstehen. Ich denke, es gibt zu wenige Beispiele für TensorFlow. Vorerst habe ich versucht, es nachzuahmen, daher würde ich es begrüßen, wenn Sie Kommentare abgeben könnten, wenn es Missverständnisse oder Korrekturen gibt. "Dieser Bereich ist korrekt" und "Dieser Bereich ist in Ordnung" sind ebenfalls sehr hilfreich.
Andere Websites, auf die verwiesen wird: Deep-Q learning Pong with Tensorflow and PyGame Ich habe wahrscheinlich auf den Quellcode in der oberen Hälfte dieser Seite verwiesen.
Betrachten Sie das folgende Spiel.
TensorFlow 0.7 Ubuntu 14.04 GCE vCPU x8-Instanz
Ich werde den Quellcode unten einfügen, aber ich werde den Teil erklären.
def inference(x_ph):
with tf.name_scope('hidden1'):
weights = tf.Variable(tf.truncated_normal([NUM_IMPUT, NUM_HIDDEN1], stddev=stddev), name='weights')
biases = tf.Variable(tf.zeros([NUM_HIDDEN1], dtype=tf.float32), name='biases')
hidden1 = tf.matmul(x_ph, weights) + biases
with tf.name_scope('hidden2'):
weights = tf.Variable(tf.truncated_normal([NUM_HIDDEN1, NUM_HIDDEN2], stddev=stddev), name='weights')
biases = tf.Variable(tf.zeros([NUM_HIDDEN2], dtype=tf.float32), name='biases')
hidden2 = tf.matmul(hidden1, weights) + biases
with tf.name_scope('output'):
weights = tf.Variable(tf.truncated_normal([NUM_HIDDEN2, NUM_OUTPUT], stddev=stddev), name='weights')
biases = tf.Variable(tf.zeros([NUM_OUTPUT], dtype=tf.float32), name='biases')
y = tf.matmul(hidden2, weights) + biases
return y
Es gibt zwei versteckte Ebenen, und die Anzahl der Einheiten beträgt 100 bzw. 100. Die Nummer dieser Seite ist angemessen. (Ich versuche es, während ich damit spiele) Geben Sie nur eine Zahl ein, die die aktuelle Position angibt. Es gibt zwei Ausgänge, die erwarteten Belohnungen für +1 und +2 (glaube ich). Ich habe viele variable Initialisierungen gesehen, die mit Null initialisiert wurden, aber nicht funktionierten, also zufällige Initialisierung. (Gibt es ein Problem?) Die Aktivierungsfunktion funktioniert nicht gut, wenn ich relu verwende, und wenn ich sie ohne die Aktivierungsfunktion verbinde, funktioniert sie ein wenig mit Matomo, so dass es keine bleibt. (Gibt es ein Problem?)
def loss(y, y_ph):
return tf.reduce_mean(tf.nn.l2_loss((y - y_ph)))
Die Verlustberechnung scheint quadratisch und halbiert zu sein. Implementieren Sie sie daher mit der entsprechenden API.
def getNextPositionReward(choice_position):
if choice_position % 8 == 0:
next_position_reward = -1.
elif choice_position % 2 == 0:
next_position_reward = 1.
else:
next_position_reward = 0.
return next_position_reward
Eine Funktion, die eine Strafe zurückgibt, wenn der nächste Platz ein Vielfaches von 8 ist, und eine Belohnung, wenn es ein Vielfaches von 2 ist.
def getNextPosition(position, action_reward1, action_reward2):
if random.random() < RANDOM_FACTOR:
if random.randint(0, 1) == 0:
next_position = position + 1
else:
next_position = position + 2
else:
if action_reward1 > action_reward2:
next_position = position + 1
else:
next_position = position + 2
return next_position
Der Teil, der die beiden Belohnungen vergleicht und überlegt, ob er +1 oder +2 vorrücken soll. Zum Zeitpunkt des Trainings versuche ich, ein bestimmtes zufälliges Element einzugeben und fortzufahren.
for i in range(REPEAT_TIMES):
position = 0.
position_history = []
reward_history = []
while(True):
if position >= GOAL:
break
choice1_position = position + 1.
choice2_position = position + 2.
next_position1_reward = getNextPositionReward(choice1_position)
next_position2_reward = getNextPositionReward(choice2_position)
reward1 = sess.run(y, feed_dict={x_ph: [[choice1_position]]})[0]
reward2 = sess.run(y, feed_dict={x_ph: [[choice2_position]]})[0]
action_reward1 = next_position1_reward + GAMMA * np.max(reward1)
action_reward2 = next_position2_reward + GAMMA * np.max(reward2)
position_history.append([position])
reward_history.append([action_reward1, action_reward2])
position = getNextPosition(position, action_reward1, action_reward2)
sess.run(train_step, feed_dict={x_ph: position_history, y_ph: reward_history})
Schulungsteil (Auszug). Es gibt zwei Möglichkeiten: Vergleichen Sie die Belohnungen und wählen Sie die mit der höheren Belohnung aus. Die Belohnung ist die Summe der Maximalwerte von "der Belohnung (sicher), die an der nächsten Position erhalten wird" und "dem vorhergesagten Wert der Belohnung, die (wahrscheinlich) danach erhalten wird". Stellen Sie außerdem eine Liste der beiden Belohnungen und Ihre aktuelle Position für überwachtes Lernen zusammen. Dies wird ungefähr 1000 Mal wiederholt. ⇒ Ich mache mir darüber Sorgen. Ich glaube, ich mache einen großen Fehler.
Werfen wir einen Blick auf die Flugbahn, wie sie sich nach dem Training tatsächlich bewegt hat.
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98]
Es gibt nur eine gerade Zahl zurück. Ich trete perfekt auf ein Vielfaches von 8! Ich habe das Gefühl, positive Belohnungen zu erhalten, aber ich habe nicht das Gefühl, negative zu vermeiden. Als ich verschiedene Dinge ausprobiert habe, wie zum Beispiel den negativen Wert der Belohnung zu erhöhen, scheint der obige Wert unterschiedlich zu sein, so dass es den Anschein hat, dass der Wert kein fester Wert ist, aber er hat sich nicht ideal bewegt ... ・ ・. Der Verlust ist übrigens konvergiert.
import tensorflow as tf
import numpy as np
import random
# definition
NUM_IMPUT = 1
NUM_HIDDEN1 = 100
NUM_HIDDEN2 = 100
NUM_OUTPUT = 2
LEARNING_RATE = 0.1
REPEAT_TIMES = 100
GOAL = 100
LOG_DIR = "tf_log"
GAMMA = 0.8
stddev = 0.01
RANDOM_FACTOR = 0.1
def inference(x_ph):
with tf.name_scope('hidden1'):
weights = tf.Variable(tf.truncated_normal([NUM_IMPUT, NUM_HIDDEN1], stddev=stddev), name='weights')
biases = tf.Variable(tf.zeros([NUM_HIDDEN1], dtype=tf.float32), name='biases')
hidden1 = tf.matmul(x_ph, weights) + biases
with tf.name_scope('hidden2'):
weights = tf.Variable(tf.truncated_normal([NUM_HIDDEN1, NUM_HIDDEN2], stddev=stddev), name='weights')
biases = tf.Variable(tf.zeros([NUM_HIDDEN2], dtype=tf.float32), name='biases')
hidden2 = tf.matmul(hidden1, weights) + biases
with tf.name_scope('output'):
weights = tf.Variable(tf.truncated_normal([NUM_HIDDEN2, NUM_OUTPUT], stddev=stddev), name='weights')
biases = tf.Variable(tf.zeros([NUM_OUTPUT], dtype=tf.float32), name='biases')
y = tf.matmul(hidden2, weights) + biases
return y
def loss(y, y_ph):
return tf.reduce_mean(tf.nn.l2_loss((y - y_ph)))
def optimize(loss):
optimizer = tf.train.AdamOptimizer(LEARNING_RATE)
train_step = optimizer.minimize(loss)
return train_step
def getNextPositionReward(choice_position):
if choice_position % 8 == 0:
next_position_reward = -1.
elif choice_position % 2 == 0:
next_position_reward = 1.
else:
next_position_reward = 0.
return next_position_reward
def getNextPosition(position, action_reward1, action_reward2):
if random.random() < RANDOM_FACTOR:
if random.randint(0, 1) == 0:
next_position = position + 1
else:
next_position = position + 2
else:
if action_reward1 > action_reward2:
next_position = position + 1
else:
next_position = position + 2
return next_position
if __name__ == "__main__":
x_ph = tf.placeholder(tf.float32, [None, NUM_IMPUT])
y_ph = tf.placeholder(tf.float32, [None, NUM_OUTPUT])
y = inference(x_ph)
loss = loss(y, y_ph)
tf.scalar_summary("Loss", loss)
train_step = optimize(loss)
sess = tf.Session()
summary_op = tf.merge_all_summaries()
init = tf.initialize_all_variables()
sess.run(init)
summary_writer = tf.train.SummaryWriter(LOG_DIR, graph_def=sess.graph_def)
for i in range(REPEAT_TIMES):
position = 0.
position_history = []
reward_history = []
while(True):
if position >= GOAL:
break
choice1_position = position + 1.
choice2_position = position + 2.
next_position1_reward = getNextPositionReward(choice1_position)
next_position2_reward = getNextPositionReward(choice2_position)
reward1 = sess.run(y, feed_dict={x_ph: [[choice1_position]]})[0]
reward2 = sess.run(y, feed_dict={x_ph: [[choice2_position]]})[0]
action_reward1 = next_position1_reward + GAMMA * np.max(reward1)
action_reward2 = next_position2_reward + GAMMA * np.max(reward2)
position_history.append([position])
reward_history.append([action_reward1, action_reward2])
position = getNextPosition(position, action_reward1, action_reward2)
sess.run(train_step, feed_dict={x_ph: position_history, y_ph: reward_history})
summary_str = sess.run(summary_op, feed_dict={x_ph: position_history, y_ph: reward_history})
summary_writer.add_summary(summary_str, i)
if i % 10 == 0:
print "Count: " + str(i)
# TEST
position = 0
position_history = []
while(True):
if position >= GOAL:
break
position_history.append(position)
rewards = sess.run(y, feed_dict={x_ph: [[position]]})[0]
choice = np.argmax(rewards)
if choice == 0:
position += 1
else:
position += 2
print position_history
Wir freuen uns auf Ihren Rat und Ihre Nutzlosigkeit.
dsanno gab uns in den Kommentaren einige Ratschläge. Vielen Dank. Ich werde das versuchen.
Bei dieser Problemeinstellung gibt es keine versteckte Ebene. Ich denke, dass Sie mit nur einer Ebene von embedded_lookup mit 100 Eingabewerten (ein heißer Vektor, der Ihren aktuellen Standort darstellt) und 2 Ausgabewerten lernen können.
Ich sehe ich sehe··· Ich verstehe Embedding_lookup immer noch nicht, also lasse ich es beiseite und mache die Eingabe zu einem One-Hot-Vektor und versuche es ohne versteckte Ebene.
def inference(x_ph):
with tf.name_scope('output'):
weights = tf.Variable(tf.truncated_normal([NUM_IMPUT, NUM_OUTPUT], stddev=stddev), name='weights')
biases = tf.Variable(tf.zeros([NUM_OUTPUT], dtype=tf.float32), name='biases')
y = tf.matmul(x_ph, weights) + biases
Unten finden Sie eine Funktion zum Erstellen eines One-Hot-Vektors.
def onehot(idx):
idx = int(idx)
array = np.zeros(GOAL)
array[idx] = 1.
return array
[0, 2, 4, 6, 7, 9, 10, 12, 14, 15, 17, 18, 20, 22, 23, 25, 26, 28, 30, 32, 34, 36, 38, 39, 41, 42, 44, 46, 47, 49, 50, 52, 53, 54, 55, 57, 58, 60, 62, 63, 65, 66, 68, 70, 71, 73, 74, 76, 78, 79, 81, 82, 84, 86, 88, 90, 92, 94, 95, 97, 98, 99]
Es ist so ähnlich. Es ist nicht perfekt, aber ich habe das Gefühl, ich versuche, Vielfache von 8 zu vermeiden, während ich so viel wie möglich auf Vielfache von 2 trete.
Mit ReLu gibt es keine Obergrenze für die Ausgabe und es scheint inkompatibel zu sein. Machen Sie also tanh oder relu6 mit einer Obergrenze zu einer Aktivierungsfunktion
Ich habe es mit 100.100 versteckten Ebeneneinheiten versucht, während ich eine Eingabe beibehalten habe. Dies unterscheidet sich nicht wesentlich von der Funktion ohne Aktivierung.
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98]
Wenn Sie davon ausgehen können, dass die Lösung periodisch ist, verwenden Sie tf.sin für die Aktivierungsfunktion (verwenden Sie beispielsweise sin für die erste Stufe und relu für die zweite Stufe). Ich habe es mit 100.100 versteckten Ebeneneinheiten versucht, während ich eine Eingabe beibehalten habe.
def inference(x_ph):
with tf.name_scope('hidden1'):
weights = tf.Variable(tf.zeros([NUM_IMPUT, NUM_HIDDEN1], dtype=tf.float32), name='weights')
biases = tf.Variable(tf.zeros([NUM_HIDDEN1], dtype=tf.float32), name='biases')
hidden1 = tf.sin(tf.matmul(x_ph, weights) + biases)
with tf.name_scope('hidden2'):
weights = tf.Variable(tf.truncated_normal([NUM_HIDDEN1, NUM_HIDDEN2], stddev=stddev), name='weights')
biases = tf.Variable(tf.zeros([NUM_HIDDEN2], dtype=tf.float32), name='biases')
hidden2 = tf.nn.relu(tf.matmul(hidden1, weights) + biases)
with tf.name_scope('output'):
weights = tf.Variable(tf.truncated_normal([NUM_HIDDEN2, NUM_OUTPUT], stddev=stddev), name='weights')
biases = tf.Variable(tf.zeros([NUM_OUTPUT], dtype=tf.float32), name='biases')
y = tf.matmul(hidden2, weights) + biases
return y
[0, 2, 4, 6, 8, 9, 10, 12, 14, 15, 17, 18, 20, 22, 23, 25, 26, 28, 29, 30, 31, 33, 34, 36, 38, 39, 41, 43, 44, 46, 47, 49, 50, 51, 53, 55, 57, 58, 60, 62, 63, 64, 66, 68, 69, 71, 73, 74, 76, 78, 79, 81, 82, 83, 84, 85, 87, 89, 90, 92, 94, 95, 97, 98]
Ich trete auf die ersten 8, aber ich habe das Gefühl, auch hier mein Bestes zu geben.
Ein wenig korrigiert und die Anzahl der versteckten Ebeneneinheiten auf 500.100 angepasst.
[0, 2, 4, 6, 7, 9, 10, 12, 14, 15, 17, 18, 20, 22, 23, 25, 26, 28, 30, 31, 33, 34, 36, 38, 39, 41, 42, 44, 46, 47, 49, 50, 52, 54, 55, 57, 58, 60, 62, 63, 65, 66, 68, 70, 71, 73, 74, 76, 78, 79, 81, 82, 84, 86, 87, 89, 90, 92, 94, 95, 97, 98]
Ist es perfekt Ich habe überhaupt nicht daran gedacht, sin () zu benutzen. Nochmals vielen Dank, dsanno.
Als ich von künstlicher Intelligenz hörte, hatte ich die Illusion, dass ich, wenn ich es vorerst tat, selbst an alles denken würde, aber mir wurde klar, dass die Eigenschaften der Eingabedaten und des Erstellers richtig darüber nachdenken mussten. ..
Recommended Posts