संपादित करें (1/3/16): corresponding github issueमजबूती सीखने के कार्यक्रम में सक्रियण के बिना टेन्सफोर्लो ऑप्टिमाइज़र का उपयोग कैसे करें जो प्रत्येक पुनरावृत्ति के बाद नियंत्रण लौटाता है?
मैं समारोह सन्निकटन के साथ एक क्यू-लर्निंग एजेंट को लागू करने के Tensorflow (अजगर इंटरफेस) का उपयोग कर रहा स्टोकेस्टिक ढाल-वंश का उपयोग कर प्रशिक्षित किया। प्रयोग के प्रत्येक पुनरावृत्ति पर एजेंट में एक चरण कार्य को कहा जाता है कि नए इनाम और सक्रियण के आधार पर अनुमानक के पैरामीटर अपडेट करते हैं, और फिर प्रदर्शन करने के लिए एक नई क्रिया चुनते हैं।
- एजेंट अपने राज्य-एक्शन मूल्य भविष्यवाणियों की गणना करता है एक कार्रवाई का चयन करने के:
यहाँ समस्या (सुदृढीकरण सीखने शब्दजाल के साथ) है।
- फिर नियंत्रण में एक और कार्यक्रम है जो पर्यावरण में एक कदम अनुकरण करता है।
- अब एजेंट के चरण समारोह को अगले पुनरावृत्ति के लिए बुलाया जाता है। मैं अपने लिए ग्रेडियेंट की गणना करने के लिए टेन्सफोर्लो के ऑप्टिमाइज़र क्लास का उपयोग करना चाहता हूं। हालांकि, इसके लिए राज्य-क्रिया मूल्य भविष्यवाणियों की आवश्यकता होती है जिन्हें मैंने अंतिम चरण और उनके ग्राफ़ की गणना की थी। तो:
- यदि मैं पूरे ग्राफ पर ऑप्टिमाइज़र चलाता हूं, तो उसे राज्य-क्रिया मान भविष्यवाणियों को दोबारा बदलना होगा।
- लेकिन, यदि मैं एक चर के रूप में भविष्यवाणी (चुने हुए क्रिया के लिए) को संग्रहीत करता हूं, तो उसे ऑप्टीमाइज़र को प्लेसहोल्डर के रूप में खिलाएं, अब इसमें ग्रेडियेंट की गणना करने के लिए आवश्यक ग्राफ नहीं है।
- मैं इसे सब एक ही sess.run() कथन में नहीं चला सकता, क्योंकि मुझे अगले अवलोकन और इनाम (लक्ष्य के लिए लक्ष्य में उपयोग करने के लिए) को नियंत्रण छोड़ना है और चयनित कार्रवाई को वापस करना है लॉस फंकशन)।
तो, वहाँ एक रास्ता है कि मैं कर सकते हैं (सुदृढीकरण सीखने शब्दजाल के बिना):
- कंप्यूट मेरी ग्राफ का हिस्सा, मान 1 लौटने।
- मूल्य 2
- की गणना करने के लिए कॉलिंग प्रोग्राम पर वापसी मूल्य 1 अगले पुनरावृत्ति में, मूल्य 1 की गणना करने वाले ग्राफ़ के भाग को पुन: संकलित किए बिना ग्रेडियेंट वंश के लिए मेरे हानि फ़ंक्शन के हिस्से के रूप में मान 2 का उपयोग करें।
बस ढ़ाल हार्डकोड: यह वास्तव में सरल approximators मैं अब उपयोग कर रहा हूँ के लिए आसान होगा, लेकिन वास्तव में अगर असुविधाजनक होगा
, मैं स्पष्ट समाधान पर विचार किया है मैं एक बड़े संकल्पक नेटवर्क में विभिन्न फिल्टर और सक्रियण कार्यों के साथ प्रयोग कर रहा था। यदि संभव हो तो मैं वास्तव में ऑप्टिमाइज़र क्लास का उपयोग करना चाहता हूं।
एजेंट के भीतर से पर्यावरण सिमुलेशन को कॉल करें: This system ऐसा करता है, लेकिन यह मेरा अधिक जटिल बना देगा, और मॉड्यूलरिटी और संरचना को बहुत हटा देगा। तो, मैं यह नहीं करना चाहता।
मैंने कई बार एपीआई और व्हाइटपेपर के माध्यम से पढ़ा है, लेकिन एक समाधान के साथ आने लगते हैं। मैं ग्रेडियेंट की गणना करने के लिए ग्राफ़ में लक्ष्य को खिलाने के किसी तरीके से आने का प्रयास कर रहा था, लेकिन वह ग्राफ स्वचालित रूप से बनाने के लिए एक तरीके से नहीं आ सकता था।
यदि यह पता चला है कि यह अभी तक टेंसरफ्लो में संभव नहीं है, तो क्या आपको लगता है कि इसे एक नए ऑपरेटर के रूप में लागू करने के लिए बहुत जटिल होगा? (मैंने कुछ वर्षों में सी ++ का उपयोग नहीं किया है, इसलिए टेंसरफ्लो स्रोत थोड़ा डरावना दिखता है।) या क्या मैं टॉर्च जैसे कुछ स्विचिंग से बेहतर होगा, जिसमें प्रतीकात्मक भेदभाव के बजाय अनिवार्य भिन्नता ऑटोग्रैड है?
इस पर मेरी सहायता करने के लिए समय निकालने के लिए धन्यवाद। मैं इसे जितना संभव हो उतना संक्षिप्त बनाने की कोशिश कर रहा था।
संपादित करें: कुछ और खोज करने के बाद मैं this previously asked question पर आया। यह मेरी तुलना में थोड़ा अलग है (वे टॉर्च में प्रत्येक पुनरावृत्ति से दो बार एलएसटीएम नेटवर्क को अपडेट करने से बचने की कोशिश कर रहे हैं), और अभी तक कोई जवाब नहीं है।
'''
-Q-Learning agent for a grid-world environment.
-Receives input as raw rbg pixel representation of screen.
-Uses an artificial neural network function approximator with one hidden layer
2015 Jonathon Byrd
'''
import random
import sys
#import copy
from rlglue.agent.Agent import Agent
from rlglue.agent import AgentLoader as AgentLoader
from rlglue.types import Action
from rlglue.types import Observation
import tensorflow as tf
import numpy as np
world_size = (3,3)
total_spaces = world_size[0] * world_size[1]
class simple_agent(Agent):
#Contants
discount_factor = tf.constant(0.5, name="discount_factor")
learning_rate = tf.constant(0.01, name="learning_rate")
exploration_rate = tf.Variable(0.2, name="exploration_rate") # used to be a constant :P
hidden_layer_size = 12
#Network Parameters - weights and biases
W = [tf.Variable(tf.truncated_normal([total_spaces * 3, hidden_layer_size], stddev=0.1), name="layer_1_weights"),
tf.Variable(tf.truncated_normal([hidden_layer_size,4], stddev=0.1), name="layer_2_weights")]
b = [tf.Variable(tf.zeros([hidden_layer_size]), name="layer_1_biases"), tf.Variable(tf.zeros([4]), name="layer_2_biases")]
#Input placeholders - observation and reward
screen = tf.placeholder(tf.float32, shape=[1, total_spaces * 3], name="observation") #input pixel rgb values
reward = tf.placeholder(tf.float32, shape=[], name="reward")
#last step data
last_obs = np.array([1, 2, 3], ndmin=4)
last_act = -1
#Last step placeholders
last_screen = tf.placeholder(tf.float32, shape=[1, total_spaces * 3], name="previous_observation")
last_move = tf.placeholder(tf.int32, shape = [], name="previous_action")
next_prediction = tf.placeholder(tf.float32, shape = [], name="next_prediction")
step_count = 0
def __init__(self):
#Initialize computational graphs
self.q_preds = self.Q(self.screen)
self.last_q_preds = self.Q(self.last_screen)
self.action = self.choose_action(self.q_preds)
self.next_pred = self.max_q(self.q_preds)
self.last_pred = self.act_to_pred(self.last_move, self.last_q_preds) # inefficient recomputation
self.loss = self.error(self.last_pred, self.reward, self.next_prediction)
self.train = self.learn(self.loss)
#Summaries and Statistics
tf.scalar_summary(['loss'], self.loss)
tf.scalar_summary('reward', self.reward)
#w_hist = tf.histogram_summary("weights", self.W[0])
self.summary_op = tf.merge_all_summaries()
self.sess = tf.Session()
self.summary_writer = tf.train.SummaryWriter('tensorlogs', graph_def=self.sess.graph_def)
def agent_init(self,taskSpec):
print("agent_init called")
self.sess.run(tf.initialize_all_variables())
def agent_start(self,observation):
#print("agent_start called, observation = {0}".format(observation.intArray))
o = np.divide(np.reshape(np.asarray(observation.intArray), (1,total_spaces * 3)), 255)
return self.control(o)
def agent_step(self,reward, observation):
#print("agent_step called, observation = {0}".format(observation.intArray))
print("step, reward: {0}".format(reward))
o = np.divide(np.reshape(np.asarray(observation.intArray), (1,total_spaces * 3)), 255)
next_prediction = self.sess.run([self.next_pred], feed_dict={self.screen:o})[0]
if self.step_count % 10 == 0:
summary_str = self.sess.run([self.summary_op, self.train],
feed_dict={self.reward:reward, self.last_screen:self.last_obs,
self.last_move:self.last_act, self.next_prediction:next_prediction})[0]
self.summary_writer.add_summary(summary_str, global_step=self.step_count)
else:
self.sess.run([self.train],
feed_dict={self.screen:o, self.reward:reward, self.last_screen:self.last_obs,
self.last_move:self.last_act, self.next_prediction:next_prediction})
return self.control(o)
def control(self, observation):
results = self.sess.run([self.action], feed_dict={self.screen:observation})
action = results[0]
self.last_act = action
self.last_obs = observation
if (action==0): # convert action integer to direction character
action = 'u'
elif (action==1):
action = 'l'
elif (action==2):
action = 'r'
elif (action==3):
action = 'd'
returnAction=Action()
returnAction.charArray=[action]
#print("return action returned {0}".format(action))
self.step_count += 1
return returnAction
def Q(self, obs): #calculates state-action value prediction with feed-forward neural net
with tf.name_scope('network_inference') as scope:
h1 = tf.nn.relu(tf.matmul(obs, self.W[0]) + self.b[0])
q_preds = tf.matmul(h1, self.W[1]) + self.b[1] #linear activation
return tf.reshape(q_preds, shape=[4])
def choose_action(self, q_preds): #chooses action epsilon-greedily
with tf.name_scope('action_choice') as scope:
exploration_roll = tf.random_uniform([])
#greedy_action = tf.argmax(q_preds, 0) # gets the action with the highest predicted Q-value
#random_action = tf.cast(tf.floor(tf.random_uniform([], maxval=4.0)), tf.int64)
#exploration rate updates
#if self.step_count % 10000 == 0:
#self.exploration_rate.assign(tf.div(self.exploration_rate, 2))
return tf.select(tf.greater_equal(exploration_roll, self.exploration_rate),
tf.argmax(q_preds, 0), #greedy_action
tf.cast(tf.floor(tf.random_uniform([], maxval=4.0)), tf.int64)) #random_action
'''
Why does this return NoneType?:
flag = tf.select(tf.greater_equal(exploration_roll, self.exploration_rate), 'g', 'r')
if flag == 'g': #greedy
return tf.argmax(q_preds, 0) # gets the action with the highest predicted Q-value
elif flag == 'r': #random
return tf.cast(tf.floor(tf.random_uniform([], maxval=4.0)), tf.int64)
'''
def error(self, last_pred, r, next_pred):
with tf.name_scope('loss_function') as scope:
y = tf.add(r, tf.mul(self.discount_factor, next_pred)) #target
return tf.square(tf.sub(y, last_pred)) #squared difference error
def learn(self, loss): #Update parameters using stochastic gradient descent
#TODO: Either figure out how to avoid computing the q-prediction twice or just hardcode the gradients.
with tf.name_scope('train') as scope:
return tf.train.GradientDescentOptimizer(self.learning_rate).minimize(loss, var_list=[self.W[0], self.W[1], self.b[0], self.b[1]])
def max_q(self, q_preds):
with tf.name_scope('greedy_estimate') as scope:
return tf.reduce_max(q_preds) #best predicted action from current state
def act_to_pred(self, a, preds): #get the value prediction for action a
with tf.name_scope('get_prediction') as scope:
return tf.slice(preds, tf.reshape(a, shape=[1]), [1])
def agent_end(self,reward):
pass
def agent_cleanup(self):
self.sess.close()
pass
def agent_message(self,inMessage):
if inMessage=="what is your name?":
return "my name is simple_agent";
else:
return "I don't know how to respond to your message";
if __name__=="__main__":
AgentLoader.loadAgent(simple_agent())
एक [GitHub मुद्दे] मेड (https://github.com/tensorflow/tensorflow/issues/672)। –