tensorflow
क्यू-लर्निंग
खोज…
न्यूनतम उदाहरण
क्यू-लर्निंग मॉडल-मुक्त सुदृढीकरण सीखने का एक प्रकार है। क्यू-लर्निंग में हम चाहते हैं कि एजेंट यह अनुमान लगाए कि एक राज्य (राज्य, क्रिया) की जोड़ी कितनी अच्छी है ताकि वह प्रत्येक राज्य में अच्छे कार्यों का चयन कर सके। यह एक एक्शन-वैल्यू फ़ंक्शन (Q) का अनुमान लगाकर किया जाता है जो नीचे समीकरण में फिट बैठता है:
कहाँ है और एक राज्य और वर्तमान समय कदम पर कार्रवाई कर रहे हैं। R तत्काल इनाम है और डिस्काउंट फैक्टर है। और, s ' अगले राज्य में मनाया जाता है।
जैसा कि एजेंट पर्यावरण के साथ बातचीत करता है, यह एक ऐसी स्थिति को देखता है जो इसमें है, एक क्रिया करता है, इनाम पाता है और उस नए राज्य का निरीक्षण करता है जिसे वह स्थानांतरित कर चुका है। यह चक्र तब तक जारी रहता है जब तक कि एजेंट एक समाप्ति स्थिति तक नहीं पहुंच जाता है। चूंकि क्यू-लर्निंग एक ऑफ-पॉलिसी पद्धति है, इसलिए हम रिप्ले बफर में एक अनुभव के रूप में प्रत्येक (राज्य, एक्शन, रिवॉर्ड, नेक्स्टस्टेट) को बचा सकते हैं। इन अनुभवों को प्रत्येक प्रशिक्षण पुनरावृत्ति में नमूना लिया जाता है और इसका उपयोग हमारे अनुमान को बेहतर बनाने के लिए किया जाता है। यहां बताया गया है:
-
next_state
से अगले मान के लिए Q मान की गणना करके मान लें कि एजेंट उस राज्य में लालच से कार्रवाई करता है, इसलिए नीचे दिए गए कोड मेंnp.max(next_state_value)
। - अगले चरण का क्यू मान छूट गया है और एजेंट द्वारा देखे गए तत्काल इनाम में जोड़ा गया है: (राज्य, कार्रवाई, इनाम , राज्य ')
- यदि प्रकरण की समाप्ति में एक राज्य-कार्रवाई का परिणाम होता है, तो हम चरण 1 और 2 के बजाय
Q = reward
उपयोग करते हैं (एपिसोडिक लर्निंग)। इसलिए हमें बफर में जोड़े जाने वाले प्रत्येक अनुभव के लिए समाप्ति ध्वज को भी जोड़ना होगा: (राज्य, कार्रवाई, इनाम, next_state, समाप्त) - इस बिंदु पर, हमारे पास
reward
औरnext_state
से गणना की गई क्यू मूल्य है और हमारे पास एक और क्यू मूल्य है जो कि क्यू-नेटवर्क फ़ंक्शन सन्निकटन का आउटपुट है। धीरे-धीरे अवरोही का उपयोग करके q-नेटवर्क फ़ंक्शन सन्निकटन के मापदंडों को बदलकर और इन दो क्रिया मानों के बीच अंतर को कम करके, क्यू फ़ंक्शन सन्निकटन सही क्रिया मानों की ओर धर्मान्तरित होता है।
यहां गहन क्यू नेटवर्क का कार्यान्वयन है।
import tensorflow as tf
import gym
import numpy as np
def fullyConnected(name, input_layer, output_dim, activation=None):
"""
Adds a fully connected layer after the `input_layer`. `output_dim` is
the size of next layer. `activation` is the optional activation
function for the next layer.
"""
initializer = tf.random_uniform_initializer(minval=-.003, maxval=.003)
input_dims = input_layer.get_shape().as_list()[1:]
weight = tf.get_variable(name + "_w", shape=[*input_dims, output_dim],
dtype=tf.float32, initializer=initializer)
bias = tf.get_variable(name + "_b", shape=output_dim, dtype=tf.float32,
initializer=initializer)
next_layer = tf.matmul(input_layer, weight) + bias
if activation:
next_layer = activation(next_layer, name=name + "_activated")
return next_layer
class Memory(object):
"""
Saves experiences as (state, action, reward, next_action,
termination). It only supports discrete action spaces.
"""
def __init__(self, size, state_dims):
self.length = size
self.states = np.empty([size, state_dims], dtype=float)
self.actions = np.empty(size, dtype=int)
self.rewards = np.empty((size, 1), dtype=float)
self.states_next = np.empty([size, state_dims], dtype=float)
self.terminations = np.zeros((size, 1), dtype=bool)
self.memory = [self.states, self.actions,
self.rewards, self.states_next, self.terminations]
self.pointer = 0
self.count = 0
def add(self, state, action, reward, next_state, termination):
self.states[self.pointer] = state
self.actions[self.pointer] = action
self.rewards[self.pointer] = reward
self.states_next[self.pointer] = next_state
self.terminations[self.pointer] = termination
self.pointer = (self.pointer + 1) % self.length
self.count += 1
def sample(self, batch_size):
index = np.random.randint(
min(self.count, self.length), size=(batch_size))
return (self.states[index], self.actions[index],
self.rewards[index], self.states_next[index],
self.terminations[index])
class DQN(object):
"""
Deep Q network agent.
"""
def __init__(self, state_dim, action_dim, memory_size, layer_dims,
optimizer):
self.action_dim = action_dim
self.state = tf.placeholder(
tf.float32, [None, state_dim], "states")
self.action_ph = tf.placeholder(tf.int32, [None], "actions")
self.action_value_ph = tf.placeholder(
tf.float32, [None], "action_values")
self.memory = Memory(memory_size, state_dim)
def _make():
flow = self.state
for i, size in enumerate(layer_dims):
flow = fullyConnected(
"layer%i" % i, flow, size, tf.nn.relu)
return fullyConnected(
"output_layer", flow, self.action_dim)
# generate the learner network
with tf.variable_scope('learner'):
self.action_value = _make()
# generate the target network
with tf.variable_scope('target'):
self.target_action_value = _make()
# get parameters for learner and target networks
from_list = tf.get_collection(
tf.GraphKeys.TRAINABLE_VARIABLES, scope='learner')
target_list = tf.get_collection(
tf.GraphKeys.TRAINABLE_VARIABLES, scope='target')
# create a copy operation from parameters of learner
# to parameters of target network
from_list = sorted(from_list, key=lambda v: v.name)
target_list = sorted(target_list, key=lambda v: v.name)
self.update_target_network = []
for i in range(len(from_list)):
self.update_target_network.append(target_list[i].assign(from_list[i]))
# gather the action-values of the performed actions
row = tf.range(0, tf.shape(self.action_value)[0])
indexes = tf.stack([row, self.action_ph], axis=1)
action_value = tf.gather_nd(self.action_value, indexes)
# calculate loss of Q network
self.single_loss = tf.square(action_value - self.action_value_ph)
self._loss = tf.reduce_mean(self.single_loss)
self.train_op = optimizer.minimize(self._loss)
def train(self, session, batch=None, discount=.97):
states, actions, rewards, next_states, terminals =\
self.memory.sample(batch)
next_state_value = session.run(
self.target_action_value, {self.state: next_states})
observed_value = rewards + discount * \
np.max(next_state_value, 1, keepdims=True)
observed_value[terminals] = rewards[terminals]
_, batch_loss = session.run([self.train_op, self._loss], {
self.state: states, self.action_ph: actions,
self.action_value_ph: observed_value[:, 0]})
return batch_loss
def policy(self, session, state):
return session.run(self.action_value, {self.state: [state]})[0]
def memorize(self, state, action, reward, next_state, terminal):
self.memory.add(state, action, reward, next_state, terminal)
def update(self, session):
session.run(self.update_target_network)
डी क्यू नेटवर्क में एजेंट के अभिसरण को बेहतर बनाने के लिए कुछ तंत्रों का उपयोग किया जाता है। नमूना अनुभव के बीच किसी भी अस्थायी संबंध को रोकने के लिए रिप्ले बफर से अनुभवों को बेतरतीब ढंग से नमूना करने पर जोर दिया गया है। एक अन्य तंत्र next_state
लिए क्यू-मूल्य के मूल्यांकन में लक्ष्य नेटवर्क का उपयोग कर रहा है। लक्ष्य नेटवर्क शिक्षार्थी नेटवर्क के समान है लेकिन इसके मापदंडों को बहुत कम बार संशोधित किया जाता है। इसके अलावा, लक्ष्य नेटवर्क को ढाल वंश द्वारा अद्यतन नहीं किया जाता है, इसके बजाय हर बार एक समय में इसके मापदंडों को शिक्षार्थी नेटवर्क से कॉपी किया जाता है।
नीचे दिए गए कोड, इस एजेंट का एक उदाहरण है जो एक कारपूल वातावरण में कार्रवाई करना सीख रहा है ।
ENVIRONMENT = 'CartPole-v1' # environment name from `OpenAI`.
MEMORY_SIZE = 50000 # how many of recent time steps should be saved in agent's memory
LEARNING_RATE = .01 # learning rate for Adam optimizer
BATCH_SIZE = 8 # number of experiences to sample in each training step
EPSILON = .1 # how often an action should be chosen randomly. This encourages exploration
EPXILON_DECAY = .99 # the rate of decaying `EPSILON`
NETWORK_ARCHITECTURE = [100] # shape of the q network. Each element is one layer
TOTAL_EPISODES = 500 # number of total episodes
MAX_STEPS = 200 # maximum number of steps in each episode
REPORT_STEP = 10 # how many episodes to run before printing a summary
env = gym.make(ENVIRONMENT) # initialize environment
state_dim = env.observation_space.shape[
0] # dimensions of observation space
action_dim = env.action_space.n
optimizer = tf.train.AdamOptimizer(LEARNING_RATE)
agent = DQN(state_dim, action_dim, MEMORY_SIZE,
NETWORK_ARCHITECTURE, optimizer)
eps = [EPSILON]
def runEpisode(env, session):
state = env.reset()
total_l = 0.
total_reward = 0.
for i in range(MAX_STEPS):
if np.random.uniform() < eps[0]:
action = np.random.randint(action_dim)
else:
action_values = agent.policy(session, state)
action = np.argmax(action_values)
next_state, reward, terminated, _ = env.step(action)
if terminated:
reward = -1
total_reward += reward
agent.memorize(state, action, reward, next_state, terminated)
state = next_state
total_l += agent.train(session, BATCH_SIZE)
if terminated:
break
eps[0] *= EPXILON_DECAY
i += 1
return i, total_reward / i, total_l / i
session = tf.InteractiveSession()
session.run(tf.global_variables_initializer())
for i in range(1, TOTAL_EPISODES + 1):
leng, reward, loss = runEpisode(env, session)
agent.update(session)
if i % REPORT_STEP == 0:
print(("Episode: %4i " +
"| Episod Length: %3i " +
"| Avg Reward: %+.3f " +
"| Avg Loss: %6.3f " +
"| Epsilon: %.3f") %
(i, leng, reward, loss, eps[0]))