Download Reinforcement Learning Course Subtitles | Machine Learning Tutorial Captions
Reinforcement Learning Course - Full Machine Learning Tutorial
freeCodeCamp.org
SRT - Most compatible format for video players (VLC, media players, video editors)
VTT - Web Video Text Tracks for HTML5 video and browsers
TXT - Plain text with timestamps for easy reading and editing
Scroll to view all subtitles
welcome to the reinforcement learning
jump start series i'm your host phil
tabor if you don't know me i'm a
physicist and former semiconductor
engineer turned machine learning
practitioner
in this series of tutorials you're going
to learn everything you need to know to
get started with reinforcement learning
you don't need any prior exposure all
you really need is some basic
familiarity with python
as far as requirements for this course
they are pretty light you will need the
open ai gym because we're going to be
taking advantage of that rather
extensively you'll also need the atari
extension for that so we can play games
like breakout space invaders you'll also
need the box 2d extension so we can do
the new lander environment
and beyond that you will need the
tensorflow library as well as pytorch
and i'm going to have tutorials in both
tensorflow and pi torch with a bit of a
stronger emphasis on tensorflow
i'm going to teach the course in
somewhat of a top-down fashion meaning
we're going to get to the really
important and exciting new stuff like
deep q learning and policy gradient
methods first
after that we'll kind of back up and
take a look at things like sarsa double
q learning and we'll even get into how
to make your own reinforcement learning
environments when we code up our own
grid world and then solve it with
regular q learning
if you missed something in the code
don't worry i keep all this code on my
github which i will link in the
pin comment down below i'll also link
the relevant timestamps for all the
material in case you want to jump around
because maybe some topics interest you
more or you want to get some additional
background information from the
explainer videos
questions comments leave them down below
i will address all of them let's get to
it
in this video you're going to learn
everything you need to know to implement
q-learning from scratch
you don't need any prior exposure to
q-learning you don't even really need
much familiarity with reinforcement
learning you get everything you need in
this video
if you're new here i'm phil and i'm here
to help you get started with machine
learning i upload three videos a week so
make sure to subscribe so you don't miss
out
imagine you've just gotten the
recognition you deserve in the form of
offers for a machine learning
engineering position from google
facebook and amazon
all three are offering you a boatload of
money and your dreams are big balling or
interrupted by the realization that
starting salary is just well the
starting salary you've got friends at
each of the three companies so you reach
out to find out about the promotion
schedules with each
facebook offers two hundred fifty
thousand dollars to start with a ten
percent raise after three years but with
a forty percent probability that you'll
quit
google offers two hundred thousand
dollars to start with the twenty percent
raise after three years but with only a
25 probability that you'll quit
amazon offers 350 000 to start with a
five percent raise after five years with
a sixty percent chance that you'll end
up washing out
so what should you take
all three of our big money but future
raises are far from certain
this is the sort of problem
reinforcement learning is designed to
solve
how can an agent maximize long-term
rewards in environments with
uncertainties
learning is a powerful solution because
it lets agents learn from the
environment in real time and quickly
learn novel strategies for mastering the
task at hand
q learning works by mapping pairs of
states and actions to the future rewards
the agent expects to receive
it decides which actions to take based
on a strategy called epsilon greedy
action selection
basically the agent spends some time
taking random actions to explore the
environment and the remainder of the
time selecting actions with the highest
known expected feature rewards
epsilon refers to the fraction of the
time the agent spends exploring and it's
a model hyperparameter between 0 and 1.
you can gradually decrease epsilon over
time to some finite value so that your
agent eventually converges on a mostly
greedy strategy
you probably don't want to set epsilon
at zero exactly since it's important to
always be testing the agent's model of
the environment after selecting and
taking some action the agent gets its
reward from the environment
what sets q-learning apart from many
reinforcement learning algorithms is
that it performs its learning operation
after each time step instead of at the
end of each episode as is the case with
policy gradient methods at this point
it's important to make a distinction
traditional q learning works by
literally keeping a table of state and
action pairs
if you're implementing this in python
you could use a dictionary with state
and action tuples as keys
this is only feasible in environments
with a limited number of discrete states
and actions
here the agent doesn't need to keep
track of its history since it can just
update the table in place as it plays
for the game the way the agent updates
his memories by taking the difference in
expected returns
between the actions it took with the
action that had the highest possible
future returns this ends up biasing the
agent's estimates over time towards the
actions that end up producing the best
possible outcomes when we're dealing
with environments that have a huge
number of states or state space that is
continuous then we really can't use a
table
in that case we have to use deep neural
networks to take these observations of
the environment and turn them into
discrete outputs that correspond to the
value of each action this is called deep
q learning the reason we have to use
neural networks is that they are
universal function approximators
it turns out the deep neural nets can
approximate any continuous function
which is precisely what we have the
relationship between states actions and
feature returns is a function that the
agent wants to learn so it can maximize
its future rewards deepq learning agents
have a memory of the states they saw the
actions they took and the rewards they
received
during each learning step the agent
samples a subset of this memory to feed
these states through its neural network
and compute the values of the actions it
took just like with regular q learning
the agent also computes the values for
the maximal actions and uses the
difference between the two as its loss
function to update the weights of the
neural network
so let's talk implementation
in practice we end up with two deep
neural networks
one network called the evaluation
network is to evaluate the current state
and see which action to take and another
network called the target network that
is used to calculate the value of
maximal actions during the learning step
the reasoning for why you need two
networks is a little complicated but
basically it boils down to eliminating
bias in the estimates of the values of
the actions
the weight of the target network are
periodically updated with the weights of
the evaluation network so that the
estimates of the maximal actions can get
more accurate over time if you're
dealing with an environment that gives
pixel images just like in the atari
library from the openai gym then you
will need to use a convolutional neural
network to perform feature extraction on
the images
the output from the convolutional
network is flattened and then fed into a
dense neural network to approximate the
values of each action for your agent if
the environment has movement as most do
then you have an additional problem to
solve
if you take a look at this image can you
tell which way the ball or paddle is
moving
it's pretty much impossible for you to
get a sense of motion from just a single
image and this limitation applies to the
deep q learning agent as well
this means you'll need a way of stacking
frames to give the agent a sense of
motion
so to be clear this means that the
convolutional neural network takes in
the batch of stacked images as input
rather than a single image
choosing an action is reasonably
straightforward generate a random number
and if it's less than the epsilon
parameter pick an action at random
if it's greater than the agent's epsilon
then feed the set of stacked frames
through the evaluation network to get
the values for all the actions in the
current state
find the maximal action and take it once
you get the new state back from the
environment add it to the end of your
stacked frames and store the stacked
frames actions and rewards in the
agent's memory then perform the learning
operation by sampling the agent's memory
it's really important to get a
non-sequential random sampling of the
memory so that you avoid getting trapped
in one little corner of parameter space
as long as you keep track of the state
transitions actions and rewards in the
same way you should be pretty safe
feed that random batch of data through
the evaluation and target networks and
the compute the loss function to perform
your loss minimization step for the
neural network that's really all there
is to deep cue learning a couple neural
networks a memory to keep track of
states and lots of gpu horsepower to
handle the training
speaking of which of course you'll need
to pick a framework preferably one that
lets you use a gpu for the learning
pytorch and tensorflow are both great
choices and both support model
checkpointing
this will be critical if you have other
stuff to do and can't dedicate a day or
so for model training
that's it for now make sure to share the
video if you found it helpful and
subscribe so you don't miss any future
reinforcement learning content i'll see
you in the next video
in this tutorial you're going to learn
how to use deep q learning to teach an
agent to play breakout in the tensorflow
framework you don't need to know
anything about deep q learning you don't
even need to know anything about
tensorflow you just have to follow along
let's get started
if you're new to the channel i'm phil a
physicist and former semiconductor
engineer turned machine learning
practitioner here at machine learning
with phil we do deep reinforcement
learning and artificial intelligence
tutorials three times a week so if
you're into that kind of thing hit that
subscribe button let's get to the video
so if you're not familiar with deep q
learning the basic idea is that the
agent uses a convolutional neural
network to turn the set of images from
the game into a set of feature vectors
those are fed into a fully connected
layer to determine the value of each of
the actions given some set of states in
this case a set of states is just going
to be a stack of frames because we want
the agent to have a sense of motion so
as we go along we'll be stacking up
frames passing them into our network and
asking the network hey what is the value
of either of the actions move left move
right or fire a ball we're going to
split this into two classes one of which
will house the deep q networks and the
other will house the agent and in the
agent class we're going to have other
stuff that we'll get to later
let's go ahead and start with our
imports we'll need os to handle model
saving
we'll need numpy to handle some basic
random functions
and of course tensorflow to build our
agent
so we'll start with our deepq network
the initializer is pretty
straightforward we're going to take the
learning rate number of actions
the
name of the network that is important
because we're gonna have two networks
one to select an action one to tell us
the value of an action
more on that later
the number of dimensions in the first
fully connected layer
the input dimensions of our environment
so
for the atari gym
sorry the atari library of the open ai
gym all of the images have 210 by 160
resolution and we're going to pass in a
set of frames to give the agent a sense
of motion we're going to pass in four
frames in particular so it's going to be
210 by default 210 160 by 4. we're going
to do some cropping later on we'll get
to that in a minute
we also need a directory to save our
model
so the next thing we need is the
tensorflow session this is what
instantiates everything into the graph
and each network wants to have its own
then we'll call the build network
function to add everything to the graph
once you've added everything to the
graph you have to initialize it very
important tensorflow will complain if
you don't do that so best to do that now
and the way you do that is by calling
the tf global variables initializer
function
other thing we need is a way of saving
our models as we go along and this is
critical because this deep queue network
takes forever to train i let it train
for about 10 hours and it averages a
score of two to three points
per set of uh whatever number of lies it
gets so
it's going to have to train for quite
some time so we're going to want to be
able to save it as we go along because
we have other stuff to do right
and of course you want a way of saving
your checkpoint files
next thing we need is a way of keeping
track of the parameters for each
particular network
and you do that like this
so what this will do is tell tensorflow
that we want to keep track of all of the
trainable variables for the network that
corresponds to whatever the name of this
particular network is we use this later
when we copy one network to another
next let's build our network
so we're gonna encase everything in a
scope that is based on the the network's
name
we're going to have placeholder
variables that tell us the inputs to our
model we're going to want to input the
stack of images from the
atari game we want to input the actions
that the agent took as well as the
target value for the q network we'll get
to that in a minute
and this convention of naming
naming placeholders and
layers you're going to see repeated
throughout the tensorflow library the
reason is that it it makes debugging
easier if you get an error it will tell
you the variable or layer that caused
the error very handy
and so you can probably tell by the
shape here that we are going to do a one
hot encoding of the actions
and the same thing for the q target so
the
convention of using none as the first
parameter in the shape
allows you to train a batch of stuff and
that's important because in virtually
every deep learning application you want
to pass in a batch of information right
in this case we're going to be passing
in batches of stacked frames
so we'll get to that in a moment next
thing we have to do is start to build
our
scroll down a little bit and start
building our convolutional neural
network so let's start building our
layers
the first one will have 32 filters
kernel size of 8x8
strides of 4 and a name of conf 1.
the other thing we need is an
initializer
now
we are going to use the initializer that
the deepmind team used in their paper
reason is that we want to learn from the
experts and may as well do what they do
if it's going to make our life
significantly easier
and that's going to be a variance
scaling initializer the scale of 2.
and then we want to activate that with a
relu function
that's right it's con1 activated
so our next layer is
pretty similar
it'll take the activated output of the
first layer
as input
that'll take 64 filters
if you're not familiar with what a
filter is you can check out my video on
convolutional neural networks
a kernel size of in this case four by
four
strides of two
name of conf two
and the
we can go ahead and
copy that initializer
why not
so that is our second convolutional
layer and we're gonna do something
similar for the third of course
and that will take
conf2 activated
128 filters
two by sorry a three by three kernel
good grief a stride of one and a name of
conf 3
and the same initializer
and of course we want to activate it as
well so the next step is once we have
the outputs of our convolutional net
neural network we want to flatten all of
them and pass them through a dense
network to get our q values or the
values of each state action pair let's
do that now
that's where our fc1 dimms come in
and
we need a
value activation
and oops we will do
the same initializer for the dense layer
so next up we need to determine the q
values
q and q learning just refers to the
value of a state action pair
it's just the nomenclature
and this will be the output of our
neural network
and of course we want to have one output
for each action
and this gets the same initializer
now we're not activating that yet uh we
want to
just get the linear values sorry the
linear activation of the output of our
network
so the next thing we need is the actual
value
of q
for each action
and remember actions is a placeholder
and next thing we need for every neural
network is a loss function
so we just want to have the squared
difference between
the
q value of the network outputs and
something called the q target the q
target let's get to that now so the
the way q learning works is that at each
time step it's a form of temporal
difference learning so every time step
it learns and it says hey i took some
action what was the maximal action i
could have taken and then it takes the
delta between whatever action it took
and the maximal action and uses that to
update the
the neural network as its loss function
so our training operation
is just a form of gradient descent uh
atom optimizer in this case
uh learning rate and you want to
minimize that loss function
let's give this more room
so that is almost it so that is our
network so the next thing we need is a
way of saving files right
and save and loading them as well
the reason we want this is as we said
these models take a notoriously long
time to train
and so we may want to start and stop as
we go along
and what this will do is it will look in
the checkpoint file and load up the
graph from that file
and save it
and load it into the graph of the
current session
and we're going to save frequently as we
train something like every 10 games
and all this function does is it takes
the current session and opposite to a
file
pretty handy so that is our deep q
network what this does again is it takes
a batch of images from the environment
in this case breakout passes it through
convolutional neural network to do the
feature selection that passes it through
a fully connected layer to determine the
value of each given action and then uses
the the maximum value of the next action
to determine its loss function and
perform training on that network network
via back propagation
next up we need an agent that includes
everything else all of the learnings all
the memories all that good stuff
so it's going to take something called
alpha that is the learning rate
gamma that's a discount factor a hyper
parameter of our model
the memory size number of actions and
epsilon that determines how often it
takes a random action
a batch size
a
parameter that tells us how often we
want to replace our target network
set of input dimms
we use the same as before 210 160 by
four
one moment my cat is whining we need the
directory to save the q next network
and we will need a directory to save the
q evaluation
and what this
as i said we'll have two networks one
that tells us the action to take the one
that tells us the value of that action
so let's go ahead and start our
initializer
so when we take random actions
we will need to know the action space
which is just the set of all possible
actions
and we need to know the number of
actions
we need our discount factor gamma this
tells the agent how much it wants to
discount future rewards
the memory size which tells us how many
transitions to store in memory
of course our epsilon
and epsilon greedy
and then we need our network to tell the
agent the value of the next action
so we'll pass in the alpha learning rate
number of actions
input dimms
the
name
and the checkpoint directory
okay so now we have our two networks the
next thing we need is a memory
so q learning works by saving the state
action reward and new state
transitions in its memory we're also
going to save the terminal flags that
tell the agent whether or not the game
is done
that'll go into the calculation of our
reward when we do the learning function
so we need a state memory
just a numpy array of zeros
we shape mem size and input dimms
and so this will save a
set of
four transitions four frames stacked
four frames by number of memories
and we also need an action memory
and this will handle the one this will
store the one hot encoding of our
actions
now
that is just one dimensional
this will just store the agent's memory
of the rewards
and then we need the terminal memory
so this just saves
the memory of the
done flex
and to save ram
we'll save that one as int8
and you know what we can do the same
thing with the
actions
and this is important because we're
going to be saving 25 000 or so
transitions on my pc this consumes about
47 gigabytes 48 gigabytes of ram i have
96 so it fits
uh if you have less you're gonna need a
significantly smaller memory size just
something to keep in mind
so next thing we need to do is to store
those transitions in memory
and this is of course pretty stateful
straightforward so we need the old state
the action the reward the new state
let's just call that state underscore
and a terminal flag so that'll just be
an integer zero or one
so the agent has some fixed memory signs
we want to fill up to that memory and
then when we exceed it we just want to
go back to the beginning and start
overriding it so the index
is just going to be mem counter which is
the
something i forgot let's put that up
here
so that will be the
counter that keeps track of the
number of memories that it has stored
so
for our actions we need to do the one
hot encoding
and when we pass in the action it'll
just be an integer
so making an array of zeros and setting
the index of the action you took to one
is a one hot encoding
and of course you want to increment the
memory counter
so the next thing we need is a way of
choosing actions so deep q learning
relies on what is called epsilon greedy
so epsilon is a parameter that tells it
how often to choose a random action
we're going to dk epsilon over time the
agent will start out acting purely
randomly for many many hundreds of games
and eventually the random factor will
start decreasing over time and the agent
will take more and more greedy actions
the greedy action is choosing the action
that has the highest value of the next
state
so this takes the state as input
we need a random number from the numpy
random number generator
and then we'll select an action at
random from the agent's action space
if we are going to take a greedy action
then we need to actually find out what
our next highest lead highest valued
action is
so we need to use our evaluation network
to run the
q eval
dot q values
tensor
using a feed dict of the
sorry the
i can't talk and type at the same time
of the current state as the q evaluation
network input
and then of course if you want the
maximum action you just need
numpy.arcmax of actions
and when you're done just return the
action
so now we come to the meat of the
problem we have to handle the learning
so learning has many parts to it the
basic idea is first thing we're going to
do is check to see if we want to update
the value of our target network and if
it's time to do that we're going to go
ahead and do that
the next thing we're going to do is
select a batch of random memories the
most important thing here is that these
memories are non-sequential if you
choose sequential memories then the
agent will get trapped in some little
nook and cranny a parameter space
and what you'll get is oscillations and
performance over time to actually have
robust learning you want to select
different transitions over the entirety
of the memory so
that's how you handle memory batching
and sampling and then you have to
calculate the
value of the
current action as well as the next
maximum action and then you plug that
into the bellman equation for the q
learning algorithm and run your update
function on your loss so let's go ahead
and do that
so
first thing we want to do is see if it's
time to replace our
network target network
if it is
go ahead and do that and we'll write the
update graph function momentarily
next thing we want to do is find out
where our memory ends
less than
mem size
else
this will allow us to randomly sample a
subset of the memory
and this will give us a
random choice in the range maximum
of size batch size
so next we need our state batches
these are just sorry these are just the
state transitions
we will need the
actions we took and remember we store
these as a one-hot encoding so we need
to go back to a
we need to go back to a
integer encoding so
we need to handle that
and the simplest way to do that is just
to do a numpy dot operation to just
multiply two vectors together
so next we need to calculate the values
of the
current set of states as well as these
set of next states
sorry sorry with qe valve
and the next so this will take the set
of next states the transit the
transitions
the next thing we want to do is
copy the qeval network
because we want the loss for all of the
non-optimal actions to be zero
next thing we need to do is calculate
the
value of q target
so for all of these states in the batch
for the actions we actually took
uh plus this quantity here
so the
maximum value of the next state
multiplied by this quantity terminal
batch so the reason is that if we if the
next state is the end of the episode you
just want to have the reward whereas if
it is not a terminal state the next
state then you want to actually take
into account the
discounted future rewards
so next we need to feed all of this
through our neural network
through our training operation
we need the
actions which is the action we actually
took
and we also need the target values
which we just calculated
so the next thing we need to do is to
handle the prospect of decreasing
epsilon over time remember epsilon is
the random factor that tells the agent
how often to take a random action the
goal of learning is to eventually take
the best possible actions so you want to
decrease that epsilon over time so we
handle that by allowing the agent to
play
some number of
moves randomly so we'll say 100 000
moves randomly
and we want to dictate some minimum
value because you never wanted to do
purely greedy actions because you never
know if your estimates are off so you
always want to be exploring to make sure
estimates are not off
and
you can decrease epsilon over time any
number of ways you can do it linearly
that's what deepmind did you can use
square roots you can use any number of
things i'm just going to do
this we're going to multiply it by some
fraction of one
a bunch of nines that'll give you a
really slow decrease of epsilon over
time so the agent takes a lot of random
actions and does a lot of exploration
sorry i flipped my sign there
i thought that didn't look right so yeah
if it tries to drop below 0.01 we're
going to go ahead and set it there
okay so that is the learning function
next up we have to handle the functions
to save the models
and this will just call the save
checkpoint
function
for the
respective networks
next function we need is a way of
updating our graph so what we want to do
is we want to copy the
evaluation network to the target network
and this is actually a little bit tricky
so what you want are the target
parameters
this is why we saved them earlier
and you want to perform a copy operation
on them
now
the reason this is non-trivial is
because you have to pass in a session
and the decision of which session to use
is non-trivial so you have to use the
session for the values that you're
trying to copy from not copy 2. so if
you had q next you would get
an error
which took me a little bit to figure out
so that is our agent class next up we
have to code a
a
main function so of course we have to
start again with our imports
i'm going to import jim
and we want to import a network
we will also need numpy to handle the
reshaping of the observation we're going
to truncate it to make the workload on
the neural the gpu a little bit lower so
import numpy
as np
if you want to save the
the uh games you can actually
use that with uh you can do that with
the wrappers so i won't put that in here
but i will put that in my github version
so you can just do a git pull on this
and you will have the way of
saving the games
so first thing we have to do is
pre-process our observations
and the reason you want to do this is
because you don't need all of the image
we don't need the score and we also
don't need color we just need one
channel
so i've already figured it out if you
take row 30 onward and all the columns
then you will get
a good image
and you want to reshape it like so the
next thing you have to handle
is a way of stacking the frames this is
because the agent can't get a sense of
motion by looking at only one picture
right nobody can get a sense of motion
from looking at one picture worse yet
the openai
atari library returns a sequence of
frames
where it could be a random number
between two three or four so to get a
sense of motion we have to actually
stack a set of frames and we're going to
handle that with this function
so we'll just keep a running stack of
frames the current frame to save
and the buffer size which just tells you
how many frames to save so at the top of
the episode you're not going to have
anything to save right there will be no
stacked frames
so you want to initialize it
so it'll be the buffer size by the shape
of each
individual frame
next you want to iterate over that
and say
each row which corresponds to each image
in your stack gets assigned to a frame
so otherwise it's not the beginning of
the episode and you want to
pop off the bottom observation
shift the set of frames down and append
the new observation to the end so
instead of one two three four it'll be
two three four and then frame five so
let's do that
equals
sorry zero two buffer size minus one
so this will shift everything down
and this will append the current frame
to the
end of the stack
next we have to do a reshape
and this is basically to make everything
play nicely with the neural network
all right now we're ready for our main
function
let's go ahead and save
scroll down
good grief
breakout v0 is the name of the
environment
this is just a flag to determine if we
want to load a checkpoint
sorry so yeah epsilon starts out at 1.0
so the agent takes purely random actions
our learning rate alpha
will be something small like zero zero
zero two five
and we've reshaped our input so it needs
to be 180 instead of 210
180 by 160 by four because we're going
to stack four frames
the breakout library sorry the breakout
game has
three actions
and a memory size of 25 000 which as i
said takes about 48 gigabytes of ram so
go ahead and scale that based on however
much you have if you have 16 gigs go
ahead and reduce it by down to something
like six or seven thousand
so the batch size tells us how many
batches of memories to include for our
training we'll use 32.
if low checkpoint is true then we want
to load the models
next thing we need is a way of keeping
track of the scores
we will need a
parameter for the number of games
stick with 200 to start with a stack
size of four
and an initial score of zero
so
the memory is originally initialized
with a bunch of zeros
that is perfectly acceptable but another
option something else we can do is we
can overwrite those zeros with actual
gameplay sampled from the environment so
why don't we do that so
and the actions are just chosen randomly
right it's just to give the agent some
idea of what is going on in the
environment
so you want to
reset at the top of every episode
you want to pre-process that observation
you want to
go ahead and stack the frames
and then player episode
so there's a bit of a
quirk here the
the agent saves its actions as zero one
or two but the actions in the
environment are actually one two and
three so we have to sample from that
interval and then
add one take the action subtract one and
then save the the transition in the
memory just a bit of a kluge
not a big problem
so then we want to
add that to our stack
go ahead and subtract off one from the
action
and store that transition in memory
and then finally set the old observation
to be the new one
let's go ahead and use a string print
statement
okay
now that we've loaded up our agent with
random memories
we can actually go ahead and play the
game
one thing i like to do is print out the
running average of the last 10 games so
that we get an idea of if the agent is
learning over not over time or not you
do it like this
and then just print that out
and i also like to know if epsilon is
still
one or if it has actually started to
decrease over time
and we also want to save the models
every 10 games
and if on any other game we just want to
print out the episode number
and the score
so we can actually scroll up here
copy this
so we're not done
whoops
there we go
so instead of a random choice it is
agent dot choose action
and that takes in the observation
oh but we did forget to do the same
thing here
grab those
and
put them there so the top of every
episode we reset the environment
pre-process the observation and stack
the frames quite critical
so
we still have to do the same thing with
adding and subtracting one we want to
save the transitions and the only other
difference is that we want to learn at
every step
at the end of the episode
we want to
go ahead and append our score so that
way we can keep track of our average
and if you want to get fancy you can go
ahead and add in a plotting function so
that when this is done learning you can
plot the learning over time and you
should see an upward slope over time and
if you want to plot the epsilons you
should see a gradual downward slope as
well so i'm gonna leave it here because
the model is still training on my
computer it's run about three thousand
iterations three thousand games that is
and it at best it gets two to three
points per set of five lives so it's
really going to need a couple days of
training to get up to anything
resembling competitive gameplay but once
it's done i'll upload another video that
explains how q learning works in depth
and in detail and i'll include the
performance from this particular model
in that video so you can check it out
then feel free to run this yourself when
i finish the model i will go ahead and
upload the trained version to my github
so you are free to download it if you
don't have
any hard any decent gpus to train this
with go ahead leave a comment down below
subscribe i will see you all in the next
video
welcome back everybody in this series of
videos we're going to code up a deep q
network in pytorch to play space
invaders from the atari open ai gym
library in this first video we're going
to code the convolutional neural network
class in the second video we'll code at
the aging class itself and in the third
we'll get to coding the main loop and
seeing how it all performs let's get to
it
so if you're not familiar with the deep
q network i would advise you to check
out my earlier video bite size machine
learning what is a deep q network it's a
quick little explainer video that gives
you the gist of it within about four and
a half minutes uh if you already know
then great we're ready to rock and roll
but if you don't
i'll give you the brief too long didn't
read so basic idea is that we want to
reduce some rather large state space
into something more manageable so we're
going to use a convolutional neural
network
to reduce the representation of our
estate space into something more
manageable and that'll be fed into a
fully connected neural network to
compute the q values in other words the
action values
for any particular given state
we're going to leverage two different
networks a network that is going to tell
us the value of the current state as
well as a network to tell us the value
of the successor states this is going to
be used to calculate the values of the
target and which is the purely greedy
action as well as the behavioral network
which is the current predicted state and
the difference between those two is used
in the loss function for our stochastic
gradient descent or root mean squared
propagator
so let's go ahead and get started um
we're going to start as usual
by doing our imports
and
there are quite a few
in pi torch
great library
one thing i really like about it is that
it's highly expressive you don't have a
whole lot of boilerplate code as you do
in something like tensorflow tensorflow
is enormously powerful uh and if you
wanna do
um
cross app type of software then that's
going to be really your only choice
for our purposes this is going to be
precise you want to use
and of course numpy
so
we're going to define a class for our
deep q network and that'll derive from
an end module
this is kind of how
uh
pytorch handles everything you want to
derive your class from the module
uh the base module uh so that way you
get access to all of the goodies
and we'll pass in our learning rate
alpha for our
stochastic gradient descent algorithm
all right so
the network is comprised of three
convolutional layers and two fully
connected layers
so the first one is just going to be a
two-dimensional convolution that's going
to take one input channel the reason is
that the
agent doesn't really care about color so
we're going to go ahead and make things
easier reduce our computational
requirements by going to a grayscale
representation
we'll take
32 filters with an 8 by 8 kernel
a stride of 4 and a padding of
1.
second layer
is going to be pretty similar
this one of course will take 32 channels
in give 64 channels out
and do a 4x4 kernel with a stride of two
and our third convolutional layer is
going to be of course two-dimensional as
well takes in 64
outputs 128 with a 3x3
kernel
uh that's it for the convolutions hey if
you don't know how convolutional neural
network works i'm going to go ahead and
link a video here that will give you the
uh
the the basic idea of of how those work
and if you would rather see how uh how
this stuff works in text form i don't
know if i mentioned this earlier but
there is an associated blog article my
website neuronet dot ai yeah i bought
that domain i'll link it in the
description go ahead and check it out
please
so our fully connected layer is the
following
and we're going to have to do a little
bit of magic here so
after running this stuff a bunch of
times
uh i know the dimensionality of the
images we're going to of the
convolutions we're going to get out and
what we want to know is
we're going to be taking a
set of filters uh you know convolved
images that have had filters applied to
them 128 to be exact and we want to
unroll them into a single flattened
image right to feed into our neural
network so that's going to be 128
channels that are 19 by 8 in size and
that's a magic number i got from just by
running the code in trial and error
and then our output layer is going to
take in those 512
units and output 6 y6 that's because we
have a total of 6 actions in the
game of space invaders you have a total
of 6 actions which are the subset of the
full 20 available in the atari library
basically the agent can do nothing it
can move left it can move right it can
shoot while standing still and it can
move left and right and shoot
when we get to the main video i'll go
ahead and show all those actions
we also need an optimizer
equals optim
rms prop
and we want to tell it to take the
parameters of our object for the weights
and our learning rate is going to be
alpha that we've passed in
our loss function is going to be a mean
square error loss
and the components of that will be the
target and the current predicted q
functions and of course the target is
just the greedy value right because q
learning is an off policy method that
uses
a
epsilon greedy behavioral policy to
update the purely greedy target policy
another thing we have to do in
pi torch is tell it which device we're
using so t.device
and that'll be cuda zero
if t dot cuda is
available
else
cpu
and what this is telling it is that if
the gpu is available go ahead and use it
which is of course always preferable
otherwise just use the cpu
and we
also have to tell it
to actually
send the network to the device
um maybe i'm using 0.4 i don't know if
in 1.0 that's actually required but as
of the time i'm coding this up it's
required so
uh something we have to live with
okay so this is the sum and the whole of
our network
only thing where that remains to do is
to feed forward our observation
and that will take
the
opposite no not observation observation
not only can i not type i cannot speak
as well
i suck at life
i don't know why you guys listen to me
so what we want to do is
the observation vector uh is the
we're going to use a sequence of frames
and those frames are the reduced images
from the screen so when we get to the
third video on
um
[Music]
on actually playing the game you'll see
that you don't need the full frame to
actually figure out what's going on you
can actually truncate it to get a really
good idea
in particular the agent can only move
left and right a certain
amount so we go ahead and truncate the
sides uh you don't need the score at the
top because we're keeping track of the
score ourselves you don't need some of
the bottom so you can actually truncate
the image a little bit to reduce your
memory requirements and we're going to
convert it into a grayscale so we get
rid of two we're just going to average
the three channels to make them into one
and we also have to pass in a sequence
of frames right because if i only show
you one frame of video game you can't
tell what's going on you don't get a
sense of motion from a single frame
right you need at least two to get a
sense of motion uh we'll be using three
i believe in the original implementation
of this algorithm for um
for deepmind they used four we're going
to go ahead and use three just to be
different
um
i haven't i suspect that's a
hyperparameter it's not something i've
played with i encourage you to do that
oh another thing is that
we must train this on a gpu if you try
to do it on your cpu it's going to take
7 000 years so
uh if you do not have access to a gpu go
ahead and leave a comment below and i
will find a way to get my pre-trained
model to you so you can go ahead and
play around with this
i have a 1080 ti and not not top of line
anymore but it's still quite good for
this particular apps application
so
back to the topic we have to
convert our sequence of frames our obser
observation to a tensor and we
also want to send that to the device uh
this is a peculiarity of pi torch as far
as i'm aware i'm not the world's leading
expert but as far as i understand it you
have to tell it to send the network as
well as the variables to the device as
well
not a big deal just something to be
aware of
next thing we have to do is resize it so
when you are given a sequence of frames
in the open ai gym and really any other
format of image is going to be
height and width by channels whereas if
you look up here
this actually expects the channels to
come first
and so we have to reshape the array to
to accommodate that
so
pytorch's built-in function for that is
view
we want a minus one to handle any number
of stacked frames
one channel in the beginning and we're
going to pass in 185 by 195 image
[Music]
that doesn't seem right actually sorry
it's not 195 i'm like the original image
is 210 by 160 it can't be 180 595
total brain fart there it's 185 by 95
okay so we have
taken in our sequence of frames we've
converted it into a tensor and flat and
converted it into the proper proper
shape for our network the next thing we
want to do is
activate it and feed it forward so
we call the first convolutional layer on
our observation
and we use the value function to
activate it
and we
store that in the new variable
observation
and then
we learn how to type and then we do the
same thing with that output
pass it through the second convolutional
layer
and then we do the same thing again we
pass it to the third convolutional layer
um
and we're almost home free so the next
thing we have to do
is
we are outputting a 128 by 19 by eight
oh
set of arrays
the next thing we have to do is
oh by the way that noise is my pomodoro
timer if you're not using the pomodoro
technique i highly recommend it
it's an enormous productivity hack but
anyway
next thing we have to do is
take our sequence of
convolved images and flatten them to
feed into our
fully connected neural network so we
again use the view function
uh to do that not minus one for whatever
number of frames we pass in
19 by eight is what we get out and i
found that out through experimentation
and we know it's 128 channels because we
dictate that
here right here 128 output channels
so boom we've flattened it and the only
thing that remains is to feed it forward
and we'll use a value activation
function there
fc1
fully connected layer one
and then
it's not observation but it's actions
self dot
fc2 observation so we'll feed it through
the final
fully convolved layer and store that as
a variable called actions and go ahead
and
return it
and the reason we're doing that is
because
what we're getting out is a q value for
each of our actions and we want to pass
that back now keep in mind that we're
passing in a sequence of frames and so
we're going to get back is a
matrix it's not going to be a single
array of six values it's going to be six
values times whatever number of rows of
images you pass in so if we pass in
three images it's going to have three
rows and six columns and that'll be
important later when we actually get to
choosing the actions
speaking of which i'm going to cut it
short here we've already i've already
rambled for about 12-13 minutes uh in
part two we're going to take a look at
coding of the agent class i have
structured it this way because the agent
actually has two networks so it made
sense to kind of stick the network in
its own class
we'll get to coding up the agent's init
function how to handle its memory how to
store transitions how to choose actions
and how to actually implement the
learning function that's a much longer
project so we'll stick that in its own
video and then in part three we're going
to get to actually coding up the main
loop and seeing how it performs hey if
you liked the video make sure to like
the video hey if you don't like it go
ahead the thumbs down i don't really
care let me know what you think
questions comments leave them down below
if you made it this far please consider
subscribing i look forward to seeing all
of you in the next video
welcome back everybody in the previous
video we got to coding the convolutional
neural network class for our deep q
learning agent that's going to play
space invaders if you haven't seen that
yet go ahead and click the link to go
ahead and watch that first otherwise you
probably won't know what's going on
if you're if you're the type of person
that would prefer to have a
written set of instructions go ahead and
click the link down below i'll link to
the associated blog article for this
particular tutorial series
when we last left off we just finished
returning the set of actions which is
the set of q values for our sequence of
frames
so of course in this video we're going
to go ahead and get started
coding up the agent class which is where
all the magic is going to happen
uh oh and of course as always i have
left the code for this in my github
under the youtube directory it gets its
own directory because there's a few
different files here
i'll link that below as well and if you
aren't following me on github you
probably should because that's where i
post all of my stuff
okay next up we have the
agent class right
and this is just going to derive from
the base object class nothing fancy here
we need a basic init function
and this is going to take gamma which is
our
discount factor so the agent
has a choice of how to value future
rewards
in general gets discounted by some value
because a reward now is worth more than
a reward in the future
just like with us we need epsilon for
epsilon greedy action selection
the alpha for the learning rate
the max memory size
a
variable to keep track of how low we
want epsilon to go
something to keep track of how long we
replace of how often we're going to
replace our target network i'll get to
that in a moment
for in a few minutes
and the action space and that's just a
list
of variables from zero through five
those correspond to all the possible
actions for our agent
and you just set these
to the appropriate variables
uh
being careful not to turn on your caps
lock key
so what these all are are just hyper
parameters for our agent we don't need
to store alpha because we're just going
to pass it into the network
and then never touch it again
storing the action space allows us to
accommodate the epsilon greedy action
selection later
the mems size
is
used for
efficiency purposes so we're going to
keep track of state action reward
transitions you don't want to store an
infinite number of them you only want to
store a subset
you don't need to store all of them
anyway there's no real practical benefit
since we're just sampling a subset
anyway so
we just use some rather large
memory um to keep track of all of the
state transitions
that we care about
keep track of how many steps
and the learn step counter
that is
to keep track of how many times the
agent has called the learn function that
is used for target network replacement
if you're not familiar with it target
network replacement is when you swap the
parameters from the evaluation network
to the
target network
my experience has been that it doesn't
actually help things so i'm not going to
do it i'm going to code it in because
it's
an important part of the topic but in
this particular case i haven't found it
to be helpful
but i haven't played with it too much i
saw that it does quite well without it
so why break it
so i'm going to store the memory as a
list and the reason i'll use a list
instead of
a numpy array is because the
associated cost of stacking numpy rays
is really really high so it's much much
faster to store a list of lists and then
convert to a numpy array when you learn
and that's much faster than keeping
track of a set of numpy arrays and just
stacking them the stack operation is
incredibly computationally prohibitive
so
for something like this that's already
computationally expensive doesn't make
any sense
[Music]
and keep track of the total number of
memory stored so that way you don't
overwrite the array
we want to keep track of how often we
want to replace the target network
and then we need our two networks qe val
and that is just
passing the alpha that is just the
agent's estimate of the current set of
states
and q next is the agent's estimate of
the successor set of states so recall in
deep q learning
we calculate the value the max value of
the successor state as our greedy action
that's our our actual target policy and
our behavior policy that we used to
generate data is epsilon greedy
that's it for our constructor
the next thing we have to worry about is
storing memory transitions
so
transition
so we are interested in the current
state
the action taken
the reward received
and the resulting state
because those are the things that that
allow the agent to learn so
we have to make sure that we
aren't over our memory so if the
mem
counters less than self.mem size
then just go ahead and append that
as a list
and again we're doing this because
it is much cheaper computationally to
append a list than it is to actually
stack a numpy array
if we have
filled up our memory then we want to
uh overwrite the position in memory that
is uh determined by the modulus
dot mem size so this will guarantee we
are bounded by zero all the way up to
our mem size
and of course this is a list of lists
it's just an action reward state
underscore
and we want to increment the memory
counter
pretty simple huh pretty straightforward
next up we have the
function to choose an action and this
will take the observation
and again just to remind you as we
discussed in the first video we're
passing in a sequence of observations
because we want to capture some
information about the temporal
dependence of what's going on again with
one frame you can't tell if the aliens
are moving left or right and so you
don't know if you should move left or
right
um of course you know which way your
bullets go you know which way there is
go but
as far as movement is concerned you need
at least one frame
so
as always
we're going to be using
numpy to calculate a random number for
us to our epsilon greedy action
selection
and you want to get the
value
of all of the actions for the current
set of states itself
q eval dot forward
so what we're doing now is forward
propagating that stack of frames through
the neural network the convolutional
neural network and the fully connected
layer to get the value
of each of each of the actions given
that you're in some set of states
denoted by the observation
so if rain is less than one minus
epsilon
then
you want to take the
arg max write the maximum action
and recall that we have stored the
actions as a matrix they're returned as
a matrix because you have
the number of rows that correspond to
the number of frames you pass in and
each of the columns correspond to each
of the six actions
so you want to take the
first
first axis
and if you're taking a random action
then you just choose something at random
from the action space list
and
go ahead and increment your steps
and return the action that you've chosen
the way i the reason i use one minus
epsilon is um
[Music]
you can use the probability epsilon
you can use probability one minus
epsilon this is really more of a soft uh
soft epsilon kind of strategy
rather than purely greedy but it doesn't
really matter this is going to give you
the probability of choosing the maximum
action
of epsilon plus epsilon over six because
they're
of course the greedy action is the
subset of all actions so there's a one
over six probability that when you take
the
quote-unquote non-greedy action you'll
actually end up getting the greedy
action
all right
next thing we have to worry about is how
the agent is going to learn and this is
really the meat of everything so
we are doing batch learning so you want
to pass in a batch size
and
the reason we're doing batch learning is
um
[Music]
a number of different reasons so you
want to break correlations
uh state transitions you you
it's even okay if the the batch overlaps
different episodes what you want to get
is a good sub sampling
of
the
overall
parameter space so that way you don't
get trapped in a local minima so you
randomly sample these
state transitions through your memory
otherwise you could end up if you replay
the whole memory you could end up
getting trapped in some local minimum
it's a way to improve the efficiency of
the algorithm to converge to a purely
optimal strategy excuse me
and thursday
all right
first thing we have to do since we're
using batch learning
is uh
we have to zero out our gradients and
what this means is that
the gradients can accumulate from step
to step the network like pi torch
library can keep track of it we don't
want that if you do that if you don't do
the zero grad then you'll end up with
um
basically accumulating for every single
batch and that's really full learning
rather than batch learning
next thing we have to check for is
if we're going to replace a target
network
so if it's not none and
if it's time to do it
release now replace target
account equals zero then we want to
actually replace our target network what
we do there is
we take advantage of the pi torch
representation of our network
in that case it's just
we can convert our entire network into a
dictionary which is really cool so
itself
qnext dot load state dict
so it's going to load
uh a state to the network from a
dictionary
which network the evaluation
network
which we're going to convert to a state
dictionary
we're not actually going to use this in
our implementation but i include it here
for completeness
uh next up uh we want to know
uh we want to select a random sub-sample
of the memory so
we want to make sure we don't go all the
way past the end of our array
so if
our current memory counter plus batch
size is less than our total memory
well then we're free to go ahead and
select
any point
of our memory
because we know we're not going to go
beyond it
range
otherwise if
there is an overlap then we want memstar
to just be an int in the range
[Music]
good grief
i hate that
minus one just to be safe
uh okay so
that is how we choose where to start
just a random number somewhere between
zero and the max memory if we have
enough leftover
in the memory for the bat to accommodate
the batch otherwise subtract that off
and select something from that subset
then we're going to go ahead and get
that mini batch
and convert that to a
numpy array so
i suspect this is not the most efficient
way of doing this
and the reason is that
you run into some difficulties in the
way in which you pass things into the
torch library it has a certain set of
expectations that
are kind of finicky um not to say it's
bad it's just something that i wasn't
uh expecting but
it works nonetheless
so what we want to do next is feed
forward both of our networks we want to
know what is the value of our current
state and what is the value of the
successor state after we take the action
whatever action we're looking at in our
batch
so that's just q eval forward
what are we feeding forward
here's where we got some hackiness we
got to convert it into a list and the
reason is that our
memory is a numpy array
of numpy objects because the
observation vectors are numpy objects so
if you don't convert it into a list
then you have a numpy array of nd array
objects and tensor
pi torch will complain
we don't want tensor we don't want pi
torch to complain so
we want to access all
all rows
right our entire batch and the state is
just the zeroth element
and you want
all of the variable you want all of the
pixels
so you need the second set of columns
there and
we want to send this to the device
self dot
q eval dot device
and this ensures that the
this network this set of variables gets
sent to our gpu as well
the next thing we need is the
value of the successor states
and that is just all the
rows
third column
and all of the
um all of the
members of that array
[Music]
and here i've just
uh
i gotta quit using the visual studio
code this is annoying but um
scroll up here so all i have done here
is
um i'm putting it on qeval.device
because the device for both the
evaluation and the
uh
next network are the same so i only have
one gpu if i had two gpus then this
would matter
it doesn't matter so
you can just call it that
next thing we want to know is what is
the max action for our current for our
next state right because the
update rule actually calculates takes
into account the purely greedy action
for the successor state uh maybe if i
can find an image of it i'll flash it
here on the screen to make life easy but
next thing we have to know is the max
action
and we use the arg max function for that
and remember we want to take the first
dimension because we're
the actions q next q predicted and q
next are actually our actions that's
what we get from the feed forward
and that is batch size times
number of actions and we want the number
of actions so that's first dimension
and i am a little bit
in or attentive here about sending it to
the device just to make sure nothing
gets
off the device because this stuff slows
to a crawl if you run on the cpu
we need to get our rewards
and that is uh obtained from our memory
all the rows and the second element
too many parentheses
and
one thing we want is our loss function
to be zero for every action except for
that max action so
we have q target equal q predicted
but we want q target for all of our our
entire match but the max action
to be rewards plus self dot gamma times
the actual value of that
action
so t.max just gives you the value of the
maximum element and argmax gives you the
index
and you want to find the maximum action
the value of it
so those are our target and predicted
values that's what we use to update our
loss function the next thing we have to
handle is the epsilon decrement so we
want the agent
to gradually converge on a purely greedy
strategy for its
behavior policy
and
the way you do that is by gradually
decreasing epsilon over time i don't
like to let it
simply go to
um start decreasing right away so i have
some set number of steps i let it run
first
and i use a linear decrease over time
you can use exponential
quadratic you can use whatever form you
want
it's not
it's my knowledge it's not super
critical but i could be completely wrong
this seems to work as we'll see in the
third video
so if we don't have enough left then
just set it to epsilon end
scroll up here
and we're almost done so we have
everything we need we have everything we
need to compute our loss which is this
q target
and q predicted
those are the values of q predicted is
the value of the current set of states
and q target is related to q next right
it's the q target is the max action
for the next successor state
and so we're almost there so the loss
it's just
the mean squared error loss if you
recall from the first video where we
defined the
loss function
and
as is the
torch style you have to send it to the
device
and then we want to back propagate with
loss backward
and we just want to step
perform one iteration and go ahead and
increment our learn step
counter
and that's basically it so there was a
lot of code there let's go back and take
a look really quick so first thing you
want to do is zero your gradients
so that way we're doing actual batch
optimization instead of full
optimization
then we want to check to see if we're
gonna if it's if we are going to replace
the target network and if it is time and
if it is load the state dictionary from
the q eval on to the q next network
next up
calculate the start of the bat of the uh
memory sub sampling i'm making sure to
get some subset of the array
go ahead and sample that batch of memory
and convert it to a numpy array
oh pomodoro timer
so if you guys
aren't using the pomodoro method
to work i highly recommend it go look
that up if you don't know what it is but
anyway
convert that to a numpy array and then
go ahead and feed forward the
the current state and the successor
state
using the memory sub sample
um making sure it is sent to your device
next thing we have to know is the
maximum action for the successor state
and calculate the rewards that the agent
was given set the q target to q
predicted because you want the loss for
every state except
the loss for every action except the max
action to be zero
and then update the value of q target
for the max action to be equal to
rewards plus gamma times the actual
value of that max action
next up
make sure that you're using some way of
decrementing epsilon over time such that
it converges to some small value
that
makes the agent
settle on an mostly greedy strategy in
this clay in this case i'm using five
percent of the time for a
random action
finally go ahead and calculate the loss
function back propagated
step your optimizer and increment your
step counter
and that is all she wrote for the learn
function and the aging class slightly
more code than in the network class but
still fairly
we have a typo there still fairly
straightforward
i hope this has been informative and in
part three we're going to go ahead and
code up the main loop and see how all
this performs i look forward to seeing
you in the next video
any comments questions suggestions go
ahead and leave them below if you made
it this far please consider subscribing
i look forward to seeing you all in the
next video
and welcome back everybody to part three
of coding a deep q learning agent in the
open ai gym atari library
uh in parts one and two we took a look
at the
deep neural network class as well as the
aging class for our agent and in part
three we're going to finally put it all
together into the main loop to play the
game and see how our agent does
let's get started
so we begin as usual with our typical
imports we're going to need the gym of
course
and we're going to import our
our model class so from model we'll
import
deep
sorry dq model
and agent
and
i also have a utility function i'm not
going to go over the code it's just a
trivial function to post the uh to print
to plot
the
decaying epsilon and the running average
of previous five scores
from utils import
plot learning
and
uh oh and by the way so
if you haven't seen parts one and two go
ahead check those out
and
if you want the code for this please
check out my github if you would like to
see a
blog article that details all this in
text if you missed something in the
speech
then go ahead and click the link down
below
so it's giving me some issue
uh oh it's not deep cue model this is
the the downside of talking and typing
at the same time i'm not that talented
so
uh we want to go ahead and make our
environment
and that space invaders
v0
uh another thing to know is that there
are implementations of the environment
where instead of being passed back an
image of the screen you're passed back
like a ram image something like that
i've never used it sounds kind of
interesting it might be something for
you to check out and leave a comment
down below if you've played with have
any experience with it
or if you think it sounds cool
so we want to make our agent and i'm
going to call it brain big brain
pinky in the brain baby gamma i have
0.95
an epsilon of 1.0
and
i'm using epsilon 1.0 because it starts
out taking purely random actions and
converges on a mostly greedy strategy
learning rate of 0.03
max memory size
5000 transitions and
we're not going to do any replacement
so you may have noticed uh when we were
building our agent that the memory was
instantiated as an empty list
if you're going to use numpy arrays one
thing you would do is just create an
array of zeros and the shape of you know
your images
as well as the total number of memories
i'm going to do something slightly
different so
one way to help agents learn is to
actually have them watch videos of
humans playing and in fact the
uh deepmind team taught
alpha
alpha zero go to play by showing a board
configurations and saying which which
player won so you it's perfectly
legitimate to leverage the experience of
humans i'm not going to play the game
for the agent but what i'm going to do
is allow the agent to play the game at
totally random he's just going to play a
set number of games to fill up its
memory uh using totally random actions
so it's a bit of a hack but i kind of i
don't know to me it seems legitimate but
some people may have frowned upon it i
don't really care
it's how i chose to solve the problem
and it seems to work fairly well
so brain dot mem size we have to
reset your environment
reset your done flag
and play an episode
so here i'll let you know the action so
zero is no action
one is fire two is move right
three is move left
four is move right fire
five is move left fire so that's zero
through five total of six actions
choose one at random
env.actionspace.sample
if you want to verify that these do that
go ahead and code up a simple loop you
know while loop while not done
take action zero and render it and see
what it does
so next you want to go ahead
and
take that action
and the other thing i do is
the
um and i'm on the fence about doing this
i haven't tested it but in my experience
with other environments
in more basic algorithms that
my experience is that it makes sense to
penalize the agent for losing
so
uh you don't want the agent will
naturally try to maximize its score but
you want it to know that losing is
really bad so
if you're done and the
and this may be something i change on
the github so if you go to the github
and see this isn't there it means that i
tested it and decided it was stupid and
but as of right now i think it's okay
i'm always open to change my mind though
so i want to let it know that
losing really really sucks
and i want to store that transition
and
uh here's a bit of a magical part so
as i said in the in the first video in
the convolutional neural network we want
to reshape it down from three channels
into one because the
the asian doesn't really care about
color it only cares about
is an enemy there or not right and it
can get that information from black and
white so i'm going to take the mean over
the three channels
to get
down to a single channel and i'm also
going to go ahead and truncate it and
the reason is that there isn't a whole
lot of information around the borders of
the screen that the agent needs so we
can get away with reducing our memory
requirements
without losing anything meaningful and
i'm going to go ahead and flash in some
images here of what that looks like
but what i'm going to do is take the ops
observation vector and i'm going to take
15 to
230 to 125
and the mean is performed over access to
and we also want to store our action and
reward
uh you guys can't see that there so we
store the action and reward as well as
let's go ahead and copy this
we also want to copy
we also want to store
the successor state
oh good grief
life is so hard there we go
and that's observation underscore which
is which is the successor state
and then
set your observation to observation
underscore
and then when you're done
just let yourself know
okay
okay and we are almost there so next
thing you want to do is keep track of
the scores you want to know how well the
agent is doing
um
i have this variable epsilon history oh
uh keep track of the
history of epsilons as it decreases over
time because we want to know the
relationship between the score and the
epsilon
and we'll run it for
50 games
and you'll take a batch size of 32
memories
the batch size is it an important hyper
parameter but what you find is that
using a larger batch size may get you a
little bit better performance it slows
down training tremendously so on my
system with an i7 7820x 32 gigs of ram
1080 ti batch size of 32
means that 50 games is gonna run in
about half an hour and it takes quite a
bit of time
using a larger batch size doesn't seem
to produce a whole lot better
performance
but it certainly slows it down by more
than a factor of two so
there's non-linear scaling there
and we want to know
that we're starting game
i plus one with an epsilon of something
dot uh say four significant figures
right not epsilon
and we want to go ahead and append
the
agents epsilon at the beginning of the
episode
reset our done flag
and reset our environment
and okay so the next thing we want to do
is as i said
why is this unhappy
invalid syntax
oh no i've offended it what have i done
oh forgot a comma
there we go so next thing we want to do
is construct our sequence of frames as i
said we're going to pass in some
sequence of frames to allow it to get
some conception of movement in the
system so
i have a rather ugly way of doing this
as usual
but the first thing i want to pass into
it is the
first
the first
observation vector from the beginning of
the game
and i have broken something again
what have i broken
frames done by some
oh of course
of course okay
so the score for this episode is zero
um
i want to keep track of the last action
so
this is something i'm not sure about i
must confess to you guys the
documentation on the open ai gym is
rather lackluster what it says is that
each action will be repeated for k
frames where k is the set two three or
four
uh so i guess it gets repeated some
random number of times so
since i don't know how many times and i
want to keep passing in a consistent set
of observation vectors of frames
i will
do something hacky so i'll keep track of
the last action and i will only update
my action every third action so i want
to pass in a sequence of three frames
and repeat the action three times i'm
kind of forcing the issue
again it seems to work i don't think
it's the best implementation but this is
you know just my quick and dirty
implementation
so
if we have three frames
go ahead and choose an action based on
those and reset your frame variable
to an empty list
otherwise
go ahead and do what you just did
scroll down
so then we want to go ahead and take
that action
keep track of our score
[Music]
and append
our new
observation
uh
i'm just gonna
copy that
yeah
copy that and then
um i am going to go ahead and tell it
that losing is very bad we don't like
losers
and this al dot lives thing is the
number of lives the agent has
ale is just the
um emulator in which the opening atar
openai jim's atari library is built
and next we have to store a transition
i'm going to copy that code precisely
because i have fat fingers and
apparently screw things up so
copy that
and then
[Music]
underscore
brain.learn
batch size
keep track of our action
and here you can put in a render if you
want to see what it's doing
um if not then
at the end of the
episode end of the episode
you want to append a score
which we're going to plot later
and i like to print the score so i can
kind of get an idea of how the agent's
doing
and
we need to make a list of the
x variable
for our plotting function
again for the plotting function
just go ahead and check out my github
for that
that's the easiest way
and
i'm going to set a
file name
[Music]
i'm just gonna call it test for now
plus string um
num game something like that
uh
plus
dot png
so we have a file name then we're going
to plot that
we want to plot the scores the epsilon
history and the file and pass in the
file name so that it saves it
and that's all she wrote for the
for the main loop uh
i've gone ahead and run that so i'm
going to go ahead and flash in the
results here
so as you can see the epsilon decreases
somewhat linearly over time not somewhat
completely linearly and as it does so
the agent's performance gradually
increases over time and keep in mind
here i am plotting the previous uh the
average of the previous five games
the reason i do that is to account for
significant variations in game to game
play right so the agent is always going
to choose some proportion of random
actions and that means it can randomly
choose to move left or right into the
enemies bullets so there's always some
games that's going to get cut short
so
the the general trend in the performance
is up until the very end when it
actually takes a bit of a dive and i've
seen this over many many different
iterations i suspect this has to do with
the way that it is navigating through
parameter space it'll find pretty good
pockets and then kind of shift
into a related
other local minima which isn't quite as
good
if you let it run long enough this will
eventually go back up
but it does have some oscillatory
behavior to it but you can see that it
increases its score quite dramatically
and uh in this particular set of runs i
saw scores in excess of 700 points which
is actually pretty good for an agent um
so let's go ahead and take a look at
what it looks like with the target
network replacement
so here you can see a dramatically
different behavior so in this case uh
epsilon decreases and the score actually
decreases over time
and uh
you know actually i don't quite know why
it does this so the
the oscillations down there are almost
certainly from the target network
replacements uh it could be a fluke but
i have run this several times where i
see this type of behavior where uh with
the target network replacement it
totally takes a nosedive i don't think i
screwed up my implementation please
leave a comment below if you saw
something it looks off but as far as i
can tell it looks it's implemented
correctly you just copy one state dick
to another no real big mystery there uh
but that's why i choose to leave it off
you get a significant variation in
performance um
more of the stories to go ahead and
leave the
target network replacement off and uh
that's it for this series so we have
made an agent to play the atari uh atari
game of space invaders uh you by
uh gradually decreasing epsilon over
time we get really good performance
uh several hundred points in fact
actually learns how to play the game
quite well i'm probably going to go
ahead and spin in a video of it playing
here so you can see how it looks
um if this has been helpful to you
please consider subscribing go ahead and
leave a comment below if you have one a
question suggestion anything uh go ahead
i answer and read all my comments um
and uh go ahead and smash that like
button guys so i hope to see you all in
the next video
and uh take care
in this video i'm going to tell you
everything you need to know to start
solving reinforcement learning problems
with policy gradient methods
i'm going to give you the algorithm and
the implementation details up front and
then we'll go into how it all works and
why you would want to do it let's get to
it
so here's a basic idea behind policy
gradient methods
a policy is just a probability
distribution the agent uses to pick
actions so we use a deep neural network
to approximate the agent's policy the
network takes observations of the
environment as input and outputs actions
selected according to a softmax
activation function
next generate an episode and keep track
of the states actions and rewards in the
agent's memory
at the end of each episode go back
through these states actions and rewards
and compete and compute the discounted
future returns at each time step use
those returns as weights and the actions
the agent took as labels to perform back
propagation and update the weights of
your deep neural network
and just repeat until you have a kick
ass agent simple yeah
so now we know the what let's unpack how
all this works and why it's something
worth doing
remember with reinforcement learning
we're trying to maximize the agent's
performance over time
let's say the agent's performance is
characterized by some function j and
it's a function of the weights theta of
the deep neural network
so our update rule for theta is that the
new theta equals the old theta plus some
learning rate times the gradient of that
performance metric
note that we want to increase
performance over time so this is
technically gradient ascent instead of
gradient descent
the gradient of this performance metric
is going to be proportional to some
overstates for the amount of time we
spend in any given state and a sum over
actions for the value of the state
action pairs and the gradient of the
policy where of course the policy is
just the probability of taking each
action given we're in some state
this is really an expectation value and
after a little manipulation we arrive at
the following expression
when you plug that into the update rule
for theta you get this other expression
there are two important features here
this g sub t term is the discounted
feature returns we referenced in the
opening and this gradient of the policy
divided by the policy is a vector that
tells us the direction and policy space
that maximizes the chance that we repeat
the action a sub t
when you multiply the two you get a
vector that increases the probability of
taking actions with high expected future
returns
this is precisely how the agent learns
over time and what makes policy gradient
methods so powerful
this is called the reinforce algorithm
by the way
if we think about this long enough some
problems start to appear
for one it doesn't seem very sample
efficient
at the top of each episode we reset the
agent's memory so it effectively
discards all its previous experience
aside from the new weights that
parameterize its policy it's kind of
starting from scratch
after every time it learns
worse yet if the agent has some big
probability of selecting any action in
any given state how can we control the
variation between the episodes
for large state spaces aren't there way
too many combinations to consider well
that's actually a non-trivial problem
with policy gradient methods and part of
the reason our agent wasn't so great at
space invaders
obviously no reinforcement learning
method is going to be perfect and we'll
get to the solution to both of these
problems here in a minute
but first let's talk about why we would
want to use policy gradients at all
given these shortcomings
the policy gradient method is a pretty
different approach to reinforcement
learning
many reinforcement learning algorithms
like deep q learning for instance rely
on estimating the value of a state or
state action pair
in other words the agent wants to know
how valuable each state is so that its
epsilon greedy policy can let it select
the action that leads to the most
valuable states
the agent repeats this process over and
over occasionally choosing random
actions to see if it's missing something
the intuition behind epsilon greedy
action selection is really
straightforward
figure out what the best action is and
take it
sometimes do other stuff to make sure
you're not wildly wrong
okay that makes sense but this assumes
that you can accurately learn the action
value function to begin with
in many cases the value or action value
function is incredibly complex and
really difficult to learn on realistic
time scales
in some cases the optimal policy itself
may be much simpler and therefore easier
to approximate
this means the policy gradient agent can
learn to beat certain environments much
more quickly than if it relied on an
algorithm like deep q learning
another thing that makes policy gradient
methods attractive is what if the
optimal policy is actually deterministic
in really simple environments with an
obvious deterministic policy like a grid
world example keeping a finite epsilon
means that you keep on exploring even
after you've found the best possible
solution
obviously this is sub-optimal
for more complex environments the
optimal policy may very well be
deterministic but perhaps it's not so
obvious and you can't guess at it
beforehand
in that case one could argue that deep q
learning would be great because you can
always decrease the exploration factor
epsilon over time and allow the agent to
settle on a purely greedy strategy
this is certainly true but how can we
know how quickly to decrease epsilon
the beauty of policy gradients is that
even though they are stochastic they can
approach a deterministic policy over
time
actions that are optimal will be
selected more frequently and this will
create a sort of momentum that drives
the agent towards that optimal
deterministic policy
this really isn't feasible in action
value algorithms that rely on epsilon
greedy or its variations
so what about a shortcomings as we said
earlier there are really big variations
between episodes since each time the
agent visits the state it can choose a
different action which leads to
radically different future returns
the agent also doesn't make very good
use of its prior experience since it
discards them after each time it learns
while they seem like show stoppers they
have some pretty straightforward
solutions
to deal with the variance between
episodes we want to scale our rewards by
some baseline the simplest baseline to
use is the average reward from the
episode and we can further normalize the
g factor by dividing by the standard
deviation of those rewards this helps
control the variance in the returns so
that we don't end up with wildly
different step sizes when we when we
perform our update to the weights of the
deep neural network
dealing with the sample and efficiency
is even easier while it's possible to
update the weights of the neural net
after each episode nothing says this has
to be the case we can let the agent play
a batch of games so it has a chance to
visit his state more than once before we
update the weights for our network this
introduces an additional hyper parameter
which is the batch size for our updates
but the trade-off is that we end up with
a much faster convergence to a good
policy
now it may seem obvious but increasing
the batch size is what allowed me to go
from no learning at all in space
invaders with policy gradients to
something that actually learns how to
improve its gameplay
so that's policy gradient learning in a
nutshell we're using a deep neural
network to approximate the agent's
policy and then using gradient ascent to
choose actions that result in larger
returns
it may be sample inefficient and have
issues with scaling the returns but we
can deal with these problems to make
policy gradients competitive with other
reinforcement learning algorithms like
dq learning
if you've made it this far check out the
video where i implement policy gradients
in tensorflow if you like the video make
sure to like the video subscribe
comment down below and i'll see you in
the next video
what's up everybody in this tutorial
you're going to learn how to land a
spaceship on the moon using policy
gradient methods you don't need to know
anything about reinforcement learning
you don't need to know anything about
policy gradient methods you just have to
follow along let's get started
so before we begin let's take a look at
the basic idea of what we want to
accomplish
policy gradient methods work by
approximating the policy of the agent
the policy is just the probability
distribution that the agent uses to
select actions so we're going to use a
deep neural network to approximate that
probability distribution and we're going
to be feeding in the input observations
from the environment and getting out a
probability distribution as an output
the agent learns by replaying its memory
of the rewards it received during the
episode and calculating the discounted
future rewards that followed each
particular time step those discounted
feature rewards act as weights in the
update of our deep neural network so
that the agent assigns a higher
probability to actions whose
feature rewards are higher
so we'll start with our imports
and we're going to want os to handle
file operations
numpy to handle numpy type operations
and of course tensorflow to develop our
agent we're going to stick everything in
one class
whose initialize function takes the
learning rate
the discount factor gamma
the
number of actions
for the lunar lander environment that's
just for
the
size of the first
hidden layer of the neural network we'll
default that to 64.
the
size of the second hidden layer of the
deep neural network will also default
that to 64.
we also need the input dimms
and in this case that is 8 so the
observation isn't a pixel image it is
just a vector that represents the state
of the environment
we also want a checkpoint directory
and this will be useful for saving our
model later
so this action space will be what we use
to
select actions later on
and we're going to need a number of
other
administrative type stuff so for
instance the
state memory
is just what the agent will use to keep
track of the states it visited
likewise for the action memory we want
to keep track of the actions the agent
took
and the rewards it received along the
way
we also need the layer one size
and the layer two size
what else we okay so now we can move on
to the administrative stuff with
tensorflow so
tensorflow handles everything in what
are called sessions
so we have to define one of those
we're gonna need a function to build the
network and when we return from the
network we're going to want to
initialize all of the variables so this
build network function is only called
once it will load up all of the
variables and operations under the
tensorflow graph and then we have to
initialize those
variables with some initial values which
will be done at random
we also need a way of saving the model
because your pc may not be fast enough
to run this in a you know short enough
amount of time so you can do this in
chunks by saving and then reloading it
as you have time
we also need a
file to save the checkpoints in
so our next order of business
is to actually construct this network
so we don't need any inputs for that
but we do need a set of placeholders and
the placeholders serve as placeholders
for our inputs it just tells the
tensorflow graph that hey we're going to
be passing in some variables we don't
know what they are yet we may not
necessarily even know their shape or
size
but we know what type they are and we
want to give them names so if something
goes wrong we can debug later
so this input will just be the eight
element vector that represents the
agent's observation of the environment
and if you're not really familiar with
tensorflow
this idiom of saying shape equals a list
whose first element is none
tells tensorflow that we do not know the
batch size of the data we're going to be
loading
so the inputs could be
10 states it could be 100 it could be a
thousand it could be any number of
states and so that none just tells
tensorflow hey we don't know what shape
it's going to be so
you know just take whatever
and this
label is going to be the actions the
agent took during the course of the
episode this will be used in calculating
our loss function
similarly
we have something called g
and g is just the generic name
for the agents discounted future rewards
following each time step
this is what we will use to
bias the agent's loss function towards
increasing the probability of actions
who
generate the most returns over time
so now we're going to construct our
network
so
the first layer will just be the input
and the number of it'll take of course
number of input and input dimms on
input and then output
the
player one size
and the
activation is just going to be a value
function
and then we have to worry about
initializing this so when we call the
tf.global variables initializer it's
going to initialize all of the layers
and variables with some values we can
dictate how it does that and we can
think very carefully about it so
if you've dealt with deep neural
networks in some cases you can get
vanishing or exploding gradients that
cause the
values the network predicts to you know
go to you know either really large or
really small values it produces junk
essentially
there is a
function that will initialize the values
of all the layers such that
they are relatively comparable and we
have
a minimal risk of that happening
and that's called a xavier initializer
and i'm going to want to copy that
because we're going to use that more
than once
so of course the second layer
just takes the first layer's input
has l2 size as the number of units
with a
value activation
and of course the same initializer
and l3 will be the output of our network
however
we don't want to activate it just yet so
this quantity is related to the
probability sorry the policy of the
agent but the policy must have the
uh property that the sum of the
probabilities of taking an action you
know the sum of the probabilities for
all the actions must equal one and it's
the softmax function that has that
property and we're going to separate it
out so that we can just
so that it is a little bit more clean in
terms of the
the code a little bit more readable for
us
but the self.actions variable is what
will actually
calculate the probabilities of selecting
some action and that is just the softmax
of the
l3
and the name of that is probabilities
finally we need to well not finally but
next we need to calculate the
the loss function
so
we'll stick that in a separate scope
and uh what we need is the negative log
probability so
excuse me the
calculation involves the natural log of
the policy and you want to take the
gradient of the natural log of something
so we need a function that matches that
property
so we'll call it neg log
probability
and that's the sparse
soft max cross entropy
with logits
try saying that five times fast
so log x is just l three
and this is important because this is
part of the reason we separated out l
three in actions because when you're
passing in
the logits you don't want it to already
be activated because the negative the
sparse soft max cross entropy will
handle the
softmax activation function
and the labels will just be the label
that we pass in
from the placeholder and then of course
be the actions the agent took
and so the loss is then that quantity
neglog probability
multiplied by the returns g
next we need the training operation
and that of course is just our gradient
descent type algorithm in this case
we'll use the
atom optimizer
the learning rate of whatever we dictate
in the constructor
and we want to minimize that loss
so that is the sum and hole of the deep
neural network we need to we need to
code
the next question we have is how can we
select actions for the agent
so
the
agent is attempting to model its own
probability distribution for selecting
actions so that means what we want to do
is take a state as input pass it through
the network and get out that
probability distribution at the end
given by the variable self.actions
and then we can use numpy to select a
random action according to that
probability distribution
and we're just going to go ahead and
reshape this
bill it is
so when you run an operation through the
tensorflow graph you need to specify a
feed dictionary which gives the graph
all of the input placeholder variables
it's expecting so in this case it wants
self.input
and that takes state
as input
and it's going to return a tuple so
we're going to take the 0th element as
so we can get the correct
value that we want
and then we can select an action
according to
numpy random choice
from the action space using the
probabilities
as our distribution
and we just returned that action
the next problem we have to deal with is
storing an action
sorry the transitions and of course
we'll store
the state action and reward
and this will be useful when we learn
and since we're using lists here we're
just going to append the elements to the
end of the list
next we come to the meat of the problem
the learning function
and this doesn't require any input
so the basic idea here is that we are
going to convert these lists into numpy
arrays so we can more easily manipulate
them
and then we're going to
iterate through the agent's memory of
the rewards it received
and calculate the discounted sum
of rewards that followed each time step
so we're going to need two for loops and
a variable to keep track of the sum as
well as something to keep track of our
discounting
so let's deal with the memories first
that won't work will it
there we go
so now
we'll instantiate our g factor
and get in
shape of reward memory
we will iterate over the
length of that memory
which is just length of our episode
and so for each time step
we want to calculate the sum
of the rewards that follow that time
step
is that correct yes
next we take the sum
and discount it
then of course the discount
is just the
gamma to the k
where k is our time step
so then of course the
rewards following the teeth the teeth
teeth
the t time step is just g sum
so that's the sum that's the weighted
discounted rewards
the next thing we have to think about is
these rewards can vary a lot between
episodes so to promote stability in our
algorithm we want to scale these results
by some number
it turns out that a reasonable number to
use is the mean so we're going to
subtract off the mean of the rewards the
agent received during the episode and
then divide by the standard deviation
this will give us some nice
scaled and normalized numbers such that
the algorithm doesn't produce wacky
results
and since we're dividing by the standard
deviation we have to account for the
possibility that the standard deviation
could be zero
hence the conditional statement
next we have to run our training
operation
so the underscore tells us we don't
really care about what it returns
we have to run the training operation
the feed dictionary
that'll take an input which is just our
state memory
it will take the labels
and that is just the action memory
and it will take the
g factor which is just the g we just
calculated
now at the end of the episode
once we finish learning we want to reset
the agent's memory so that rewards from
one episode don't spill over into
another
so there are two more functions we need
these are administrative we need
a way to load the checkpoint
and we'll go ahead and print out loading
checkpoint
just so we know it's doing something
and then we have the saver object and we
want to restore
a session
from our checkpoint
file
next we want to save a checkpoint
we're not going to print here i take it
back reason is that we're going to be
saving a lot and i don't want to print
out a bunch of junk statements so
and what these are doing is just either
taking the the current graph as it is
right now and sticking it into a file or
conversely taking the graph out of the
file loading it into the graph for the
current session
so that is that
next we can move on to the main program
to actually test our
lander
so we'll need jim
and i didn't i don't know if i made it
clear at the beginning but you'll also
need the box 2d dash pi environment so
go ahead and do pip install box 2d dash
pi if you don't already have that
so we'll need to import our policy
gradient agent
i have this plot learning function i
always use you can find it on my github
along with this code of course
i don't elaborate on it but basically
what it does is it takes a sequence of
rewards
keeps track of it performs a running
average of say the last 20 25 whatever
amount you want and spits that out to a
file
we also have
a way of saving the renderings of the
environment so it runs much faster if
you don't actually render to the screen
while it's training but you can save
those renderings to files in mp4 files
so you can go back and watch them later
it's how i produce the
episodes you saw at the beginning of
this video
so first thing i'm going to do is
instantiate our agent
and we'll use a learning rate of zero
three zeros and a five
and i believe uh oh we'll need a gamma
we use something like 0.99
and all
and then all the other parameters we'll
just leave at the defaults
next we need to make our environment
and that's lunarlander v2
a way to keep track of the scores the
agent received
our initial score
and
number of episodes
so i achieved uh pretty good results
after 2500 episodes so we can
start with that
so the first thing we want to do is
iterate
over
our episodes
oh let me do this for you so
before we do that um i'll comment this
out but if you want to save the output
you do this env equals
wrappers dot monitor
pass in the environment wherever you
want to save it lunar lander
and then you want to use a lambda
function
to tell it
to render on
every episode
and this force equals true i believe
that just
tells it to overwrite if there's already
data in the directory
so at the top of every episode just
print out what episode number you're on
and the
current score
you set your done flag
and for subsequent episodes you'll want
to reset the score
reset your environment
and play an episode
first thing you want to do is select an
action
and that takes the observation as input
so we need to get the new observation
reward done flag and info by stepping
through the environment
once that's done you want to store the
transition
set the old observation to be the new
one so that you select an action based
on the new estate
and keep track of the reward you
received
at the end of every episode we want to
append
the score to the score history
and perform our learning operation
you also want to
save a checkpoint
after every operation ever after every
learning operation
and then when you're done dictate some
file name
dot png
and call my super secret
plot learning function
that just takes the score history
file name
and a window that tells it over how many
games you want to take the running
average
so now let's go to our terminal and see
how many mistakes i made one second
all right
so here we are let's go ahead and
give it a try
so i made some kind of error in the
policy gradient agent let's swing back
to that file and see where it is
one second
so here's the model
it does not have
input dimms that's because i forgot to
keep track of it
save
go back to our terminal and see how it
does
and i apparently called something i
should not have
this is line 27
it says
self.label placeholder got an unexpected
keyword argument named label
ah that's because
it is called name
that's what happens when i try to type
and talk at the same time
let me make sure i didn't call l1 size
l2 size something different no i did not
all right i will run that again
so now it's unhappy about the
choice of oh of course
so it's lunar
there's no dash in there
get rid of that
typos galore tonight
oh really
oh really
ah it's store transitions
yes
so it's actually store transitions so
let's call it that
and there we go
perfect
so now it's actually learning i'm not
going to sit here and wait for this to
do 2500 games because i've already run
this once before that's how i got the
kodi saw at the beginning
so
i'm going to go ahead and show you the
plot that it produces now so you can see
how it actually learns so
by the end it gets up to about an
average reward of around 200 and above
points that's considered solved if you
check the documentation on the openai
gym so congratulations we have solved
the lunar lander environment with the
policy gradient algorithm relatively
simple just a a deep neural network
that calculates the probability of the
agent picking an action
so i hope this has been helpful go ahead
and leave a comment down below
feel free to take this code from my
github fork it make it better do
whatever you want with it i look forward
to seeing you all in the next video
welcome back everybody to a new
reinforcement learning tutorial in
today's episode we're going to teach an
agent to play space invaders using the
policy gradient method let's get to it
for imports we start with the usual
suspects numpy and tensorflow
we start by initializing our class for
the policy gradient agent
we take the learning rate discount
factor number of actions number of
layers for the fully connected layer
the input shape channels
a directory for our checkpoints very
important as well as a parameter to
dictate which gpu we want tensorflow to
use if you only have one gpu or using
the cpu you don't need that parameter
save the relevant parameters and compute
the action space which is just a set of
integers
we want to subtract out the input
heights
and width from the input shapes and keep
track of the number of channels for use
later
our agent's memory will be comprised of
three lifts that keep track of the state
action and rewards
we want a configuration which just tells
tensorflow which gpu we want to use
as well as our session graph that uses
that config we call the build network
function
and then use the tf global variables
initializer
we need to keep track of the saver and a
checkpoint file for saving and loading
the model later
now if you don't know anything about
policy gradient methods don't worry
we're going to cover everything you need
to know as we go along the first thing
we're going to need is a convolutional
neural network to handle image
pre-processing that'll be connected to a
fully connected layer that allows the
agent to estimate what action it wants
to take in contrast to things like deep
q learning policy gradient methods don't
actually try to learn the action value
or value functions rather policy
gradients try to approximate the actual
policy of the agent
let's take a look at that
for our build network function we're
going to construct a convolutional
neural network with a few parameters
an input placeholder that has shape
batch size by input height and width as
well as the number of channels
we will also need an input for the
labels which just correspond to the
actions the agent takes that is shape
batch size
and a factor g which is just the
discounted future rewards following a
given time step that is shape batch size
our convolutional neural network is
going to be pretty straightforward if
you've seen any of my videos you can
kind of know what to expect the first
layer has 32 filters a kernel size of
eight by eight and a stride four
and we're going to want to use an
initializer for this i found that the
xavier initializer works quite well the
purpose of it is to keep the
to initialize all the parameters in such
a way that the
uh they the network doesn't have one
layer with parameters significantly
larger than any other
we want to do batch normalization i
mistyped the epsilon there should be one
by ten to the minus five
and you want to of course use a value
activation on the first convolutional
layer
and that commvault that activated output
serves as the input to the next layer
with 64 filters
kernel size of 4x4 and a stride of 2 and
again we'll use the
xavier initializer
of course we also want to do batch
normalization on this layer and at this
point i think i actually get the correct
epsilon for the
batch norm
and of course we want to use a value
activation on that batch normed output
as well
our third convolutional layer is more of
the same 2d convolution
with 128 filters
it will have a kernel size of 2x2 a
stride of 1
and we'll also use the same
initialization
again batch normalization
with an epsilon of 1 by 10 to the minus
5.
activate with a value
next we have to take into account our
fully connected layers so the first
thing we need to do is flatten the
output of the convolutions
because they come out as matrices we
need a list
go ahead and make the first fully
connected layer using fc1 as the number
of units value activation
and the second dense layer is going to
have units equal to the number of
actions for the agent which in this case
is just six
notice that we don't activate that but
we have a separate variable for the
actions which is the activated output of
the network and we're going to use a
soft max so that way we get
probabilities that add up to one
we need to calculate the negative log
probability with a sparse softmax
cross-entropy function with logits using
dense two as our logits and
labels
as of the actions as our labels the loss
is just that quantity multiplied by the
expected future rewards
and of course we want to reduce that
quantity
now for the training operation we're
going to use the rms prop optimizer with
a set of parameters i found these to
work quite well
this algorithm is pretty finicky so you
may have to play around the next thing
we have to do is
code up the action selection algorithm
for the agent in policy gradient methods
we're trying to actually approximate the
policy which means we're trying to
approximate the distribution by which
the agent chooses actions given it's in
some state s so what we need is a way of
computing those probabilities and then
sampling them
sampling the actions according to those
probabilities
we choose an action
by taking in an observation reshaping it
of course this will be a sequence of
frames
uh for high
and you want to calculate the
probabilities associated for
each action given that observation and
then you want to sample that probability
distribution
using the numpy random choice function
next up we have to take care of the
agent's memory so we're going to store
the observation action and reward in the
agent's list using a simple append
function
so one big problem we're going to have
to solve is the fact that policy
gradient methods are incredibly simple
and efficient these monte carlo methods
meaning that at the end of every episode
the agent is learning so it throws away
all of the
experience that required in prior
episodes so how do we deal with that
well one way to deal with that is to
actually queue up a batch of episodes
and learn based on that batch of
experiences
the trouble here is that when we take
the rewards that follow any given time
step we don't want to account for
rewards following the current episode so
we don't want rewards from one episode
spilling over into another so we have to
take care of that here
next up we handle the learning for the
agent we want to
we want to convert the state action and
reward memories into arrays so that we
can feed them into the numpad the excuse
me tensorflow learning function
into the sorry the tensorflow graph
we have to start by reshaping the state
memory into something feasible and then
we can calculate the expected feature
rewards starting from any given state so
what we're going to do is iterate over
the entire memory
and
take into account the rewards the agent
receives for all subsequent time steps
we also need to make sure that we're not
going to take into account rewards from
the next episode
next up we have the scale the expected
feature rewards this is to reduce
the variance in the problem so let's
make sure we don't have really really
large rewards so everything is just kind
of scaled
next up we call the training operation
with an appropriate feed dict of the
state memory action memory as labels and
the g for our g variable
finally since we're done we're going to
clear out the agent's memories
finally we just have some bookkeeping
functions to load and save checkpoints
you just call the saver restore function
that loads the checkpoint file into the
session
and the save checkpoint just dumps the
current session into the checkpoint file
another problem we have to solve is that
the agent doesn't get a sense of motion
from only a single image right if i show
you a single image you don't know if the
aliens are moving left or right or
really you don't know which direction
you're moving so we have to pass in a
sequence of frames to get a sense of
motion for our agent this is complicated
by the fact that the open ai gym atari
library in particular returns a set of
frames that are repeated so if you
actually cycle through the observations
over time you'll see that the frames
change or sorry don't change
uh based on an interval of one two or
three so we have to capture enough
frames to account for that fact as well
as to get a overall sense of movement so
that means four is going to be our magic
number for so for stacking frames
next we move into the main program we
import gym numpy
our model
as well as the
plot learning function which is a simple
utility you can find on my github as
well as the wrappers to record the
agent's gameplay if you so choose we
need to pre-process the observation by
truncating it and taking the average
next up we stack the frames so at the
beginning of the episode stack frames
will be none so you want to initialize
an empty array of zeros
and iterate over that array and set each
of those rows to be the current
observation
otherwise what you want to do is you
want to pop off the bottom observation
shift everything down and put the fourth
spot or the last spot to be the current
observation
down in the main function we have a
checkpoint flag if you want to load a
checkpoint
we want to initialize our agent with
this set of hyper parameters i found
these to work reasonably well you can
play around with them but it is
incredibly finicky so
your mileage may vary we need a file
name to save our plots
we'll also want to see if we want to
load a checkpoint
next we initialize our environment space
invaders of course
keep track of the score history score
number of episodes and our stack size of
four
one iterate over the number of episodes
resetting the done flag at the top of
each episode
we also want to keep track of the
running average score from the previous
20 games just so we got an idea if it's
actually learning
every 20 games we're gonna print out the
uh episode score and average score
otherwise every other every other
episode we're just going to print out
the episode number and the score
reset the environment and of course you
have to pre-process that observation
and then go ahead and set your stacked
frames to none because we're the top of
the episode and then call the stack
frames function so that we get four of
the initial observation
set the score to zero
and start iterating over the episode so
his first step is to choose an action
based on that set of stacked frames
go ahead and take that action and get
your new state action and reward
go ahead and pre-process that
observation
so that way you can stack it on the
stack of frames
next up you have to take care of the
agent's memory by storing that
transition
and finally you can increment your score
save the score at the end of the episode
and every 10 games are going to handle
learning and saving a checkpoint and
when you're all done go ahead and plot
the learning
now the agent is done we can take a look
at the actual plot it produces over time
this is how you know an agent is
actually learning what you'll see is
that there is some increase in the
average reward over time you'll see
oscillations up and down and that's
perfectly normal but what you want is an
overall upward trend now for this
particular set of algorithms it is
notoriously finicky with respect to
learning rates i didn't spend a huge
amount of time tuning them or playing
with them i just wanted to get something
good enough to show you guys how it
works and turn it over to your capable
hands for fine tuning but what you do
see is a definite increase over time as
the agent's average reward improves by
about 100 points or so that isn't going
to win any awards but it is definitely a
clear and unequivocal sign of learning
so there you have it that was policy
gradients in the space invaders
environment from the open ai gym i hope
you learned something make sure to check
out this code on my github you can fork
it you can copy it you can do whatever
you want with it
make sure to subscribe leave a comment
down below if you found this helpful i
look forward to seeing you all in the
next video
welcome back everybody to neuralnet.ai i
am your host phil tabor
previously a subscriber asked me hey
phil how do i create my own
reinforcement learning environment
i said well that's a great question i
don't have time to answer it in the
comments but i can make a video so here
we are
what we're going to do in the next two
videos is create our own open ai gym
compliant reinforcement learning
environment the grid world it's going to
be text based and if you're not familiar
with it the grid world is aptly named a
grid of size and by n where the agent
starts out in say the top left and
that's to navigate its way all the way
to the bottom right
the twist on this is going to be that
there will be two magic squares that
cause the agent to teleport across the
board the purpose of doing this is to
create a shortcut to see if the agent
can actually learn the shortcut kind of
interesting
the agent receives a reward of -1 with
each step except for the terminal step
or receives a reward of zero
therefore the agent will attempt to
maximize its reward by minimizing the
number of steps it takes to get off the
grid world
what other things two other concepts we
need are the concept of the state space
which is the set of all states minus the
terminal state and the state space plus
which is the set of all states including
the terminal state
this gives us a bit of a handy way to
find out the terminal state
as well as to find out if we're
attempting to make illegal moves
it also follows the nomenclature and
terminology from the sutton bardo book
reinforcement learning
which is an awesome resource you should
definitely check out if you have not
already
so in part one we're going to handle the
environment and in part two we're going
to get to the main loop and the agent
for which we will use q learning now
deep q learning because this is a very
straightforward environment we don't
need
a functional approximation we just need
the tabular representation of the
agent's estimate of the action value
function
so if you're not familiar with q
learning i do have a couple videos on
the topic
one where
the q learning agent solved the card
poll game as well as a an explainer type
video that talks about what exactly
q-learning is
so let's go ahead and get started
we only have a couple dependencies we're
not doing anything on the gpu so just
numpy and matplotlib
we want to close everything up into a
class called grid world
and our
initializer
will take the m and n which is the shape
of the grid as well as the magic squares
so we represent our grid
as an array of
zeros and shape m by n
we want
we want to learn to type uh we want to
learn to
sorry we want to keep tr
we want to keep track of the m and the
end
for
handy use later
so let's go ahead and define our state
space
and that's just going to be a list
comprehension
for all the states in the range
self.m times self.n
now the as i said the state space does
not include the terminal state and the
terminal state is the bottom right so we
have to go ahead and remove or pop off
that particular
state from the list
uh next up so
now let's go ahead and
again learn to type
go ahead and define our
state space plus
also we need to know the
the way that the actions map up to their
change on the environment so we'll call
that
the action space a little bit of a
misnomer but we can live with it for now
so moving up we'll translate the agent
up
one row which is distance m
and moving down will advance the agent's
position
downward by
also m
um
moving left we'll translate the agent
one step we'll decrement the agent's
position by one
and moving right we'll
increase it by one
we also want to keep track of the set of
possible actions
you could use the keys in the action
space dictionary but
let's go ahead and use a separate
structure
and we'll use a list
up down left and right the reason is
that the q learning agent
a q learning algorithm sorry
can it can choose actions at random so
it is handy to have a list from which
you can choose randomly
uh next we need to add the magic squares
because that's a little bit more
complicated than
it may seem
and finally when we initialize the grid
we want to set the agent to the top left
position
let's go ahead and add those magic
squares
so
of course we want to store that
in our
object now there's a little bit of
hokiness that i must explain so
the agent is represented by a zero when
we print out the grid to the terminal
and uh md squares are represented by a
one
and so excuse me and so that means we
need something other than 0 and 1 to
represent these magic squares
i want to when i render the environment
i want to know where the entrance and
where the exit is
so we use different values for
the entrance and exit so that way we can
render it correctly
so
just by royal decree we set i which
would be the representation of the
of the magic square in the grid world to
2 to start
and we're going to go ahead and iterate
over the magic squares
so now what we need to know
is
uh
what position we are in
so
you
sorry it's the color is off indicating
something is wrong i have screwed
something up royally
which i do not see
because i am blind
anyway so
the
the x position is just going to be the
floor of the
current square and the
number of rows and y will be the
modulus of
the number of columns
so then the grid we want to set that x
and y position to i
and since we want to have a different
representation for the entrance and exit
go ahead and set the
increment i by one recall that the
magic squares are is represented as a
dictionary so we're iterating over the
keys and the values are the destinations
so the keys are the source values are
destinations
so
next we want to find out
precisely that
what the destinations are
set that in and then set the grid that
square
to i and then increment i again
and i'm only going to do
i'm only going to do
two magic squares you can do any number
but in this case we're just gonna do two
so
okay so the next thing we need to know
is if we are in the terminal state
and
as i said earlier the state space and
state space plus concepts give us a very
easy way of doing that so
let's go ahead and take care of that so
since the state space plus is all the
states and the state space is all the
states
minus the terminal state we know that
the difference between these two sets
is the terminal state so
state in
state space
plus
and
not in
the state space
how does that look
let me scroll down a bit okay
so
next up
let us
go ahead and get the agent row and
column
and we're going to use the same logic as
above
so next we want to set the state
so that will take the new state as input
and we're going to go ahead and assume
that the new state is allowed so the
agent
if it is along the left edge and
attempts to move left it just receives a
reward of minus one and doesn't actually
do anything
likewise if it's on the top row and
attempts to move up it doesn't actually
do anything it just gets a reward of
minus one for wasting its time
so we want to get
uh sorry the
row and column
and set that space
to zero because zero denotes an empty
square
and the agent position then is the new
state
and again we want to get the new x a new
y
there is a typo there let's fix that
and then set that position
to one because that is how we represent
the agent by royal decree
so the next thing we have to know
is if we're attempting to move off the
grid that's not allowed
the agent can only
stay on the grid so let's take care of
that
so we want to take the new and old
states as input
and the first thing we want to know is
if we're attempting to move off the grid
world entirely
that's ah
so
i hate these editors so
uh if we are if the new state is not in
the new state space plus we are
attempting to move off the grid so you
return true
otherwise
if the old state
modulus
m equals zero
and new state
modulus
um self.m equals self.m minus one
then we return true
and
for brevity i could explain this but the
video is running long already so for
brevity
the reason this is true is left as an
exercise to the reader bet you didn't
know this was going to be like a college
course
so now
uh basically what we're trying to do
here i'll just give you a hint what
we're trying to do here is determine if
we're trying to move off the grid either
to the left or to the right we don't
want to wrap around so
so if you're for instance if we have a
nine by nine grid it goes from zero to
eight so then if you add one
right you would get nine which would
teleport you to the other row
uh and the zeroth column you don't want
that what you want to do is waste spa
ways to move and receive a reward of
minus one so that's what we're doing
here
um
old state
modulus
good grief
so if
neither of those are true then you can
go ahead and return false
meaning you're not trying to move off
the grid
so let's see can you see that you can so
next function we need is
a way to actually step
so let's go ahead and do that let's say
the only thing we need is to take in the
action
so
the first thing you want to do
is get the x and y again
and here's where we're going to check to
make sure it's a legal move so the
resulting state
is then agent position
plus the mapping so the agent position
is whatever it is and recall that the
action space
is this dictionary here that maps the
actions to the translations in the grid
so we're doing down here then is saying
the new state is equal to the current
state plus whatever the
resulting translation is for whatever
action we're attempting to make
so
next thing we need to know is are we on
a magic square
and if we are
um
and if we are then the um
agent teleports to its new position
okay
so
next up we need to handle the reward
so it's minus one if not
um
is terminal
state
so it's minus one if we haven't
transitioned into the terminal state
otherwise it is zero
if we're not trying to move off the grid
then we can go ahead and set that state
self.set state
resulting state
and then we're ready to go ahead and
return
so in the openai gym uh whenever you
take a step it returns the new state the
reward
um
whether or not the game is over and some
debug information
so we're gonna do the same thing
resulting state reward
and
the
whether or not it is the terminal state
and our debug info is just going to be
none
so if we are attempting to move off the
grid what do we want to do nothing
so we want to return
agent position
um
and the
reward
and
whether or not it's terminal
and the null debug info
we're almost there so
next thing we need to know is
how do we reset the grid because at the
end of every episode we have to reset
right
first thing to do is set the agent
position to zero
reset the grid to zeros
and go ahead and add the magic squares
back in
and return the
agent position which is of course zero
oh wow that's real close all right so
next up
one last function i swear just one more
i promise all right
i wouldn't lie to you
all right next up
we want to provide a way of rendering
because hey that's helpful for debug
i like to print a whole big string of
you know dashes because it's party
[Music]
we want to iterate over the grid
for column in row
column equals
zero in other words if it's an empty
square we're just going to print a dash
and we're going to end it with a tab
if the column is 1 meaning we have an
agent there
we're going to print an x
to denote the agent
now
if the column is 2
then that is one of the entrances to
our magic squares
so print the
a in
with a
tab delimiter a tab end
if the column
equals three
you can print a out
and equals tab
um
and if the column
equals four
then we know we're at the
other magic square entrance
and finally if it's five then
we know we're at the
other
magic squares exit
after each
row we want to print a new line
and at the end we'll go ahead and print
another
chunk of pretty dashes
oh
ah yeah that's it that is it okay so
that is it for our agent class that only
took how long 20 some minutes wow okay
i hope you're still with me
basic idea here is to make your own
environment you need an initialize a
reset
a state space state space plus a way to
denote possible actions
a way to make sure the move is legal and
a way to actually affect that
environment
the step function needs to return the
new position the reward
whether or not the state is the new
state is terminal as well as some debug
information
you also need a way of resetting and
printing out your environment to the
terminal
so in part two we're actually going to
fire this baby up with a q learning
algorithm and see how she do
that's actually quite exciting it well
moderately exciting anyway it actually
learns it does quite well and it does
find the magic square
spoiler alert if you made it this far it
finds a magic square and gets out of the
minimum number of moves required
um
it's pretty cool to see so that will
come in the next video on vedna's day i
hope to see you all then
if you like the video make sure to leave
a thumbs up subscribe if you have not
already for more reinforcement learning
content and i will see you all in the
next video
welcome back everybody to a new tutorial
from neuralnet.ai i am your host phil
taber
if you're new to the channel i'm a
physicist former semiconductor process
engineer turned machine learning
practitioner
if you haven't subscribed yet go ahead
and hit the the subscribe button so you
don't miss any future reinforcement
learning tutorials
when we left off in our previous video
we just finished up the
bulk of our open ai gym compliant
reinforcement learning environment
today we're going to go ahead and code
up a q learning agent and the main loop
of the program to see how it all
performs
so let's go ahead and get started
so the uh first thing we are going to
need is the
um
is the
magic squares right
if you recall the magic squares are the
teleporters in the grid world that
either advance the agent forward or
backward
so the first one is going to be at
position 18 and dump out at position 54
so it'll move it forward
and the next one will be at let's say 63
and dump out at position 14. so
teleporter a will advance the agent
through the grid world and teleporter b
will send it back to
an earlier square
so we need to create our grid world
we use a nine by nine grid and pass in
the magic squares we just created
next up we have to worry about the model
hyper parameters so if you are not
familiar with that let me give you a
quick rundown these are the parameters
that control how fast the agent learns
and how much it chooses to value the
potential future rewards
so the first parameter is alpha that is
our learning rate
0.1
a gamma of 1.0 tells us that the agent
is going to be totally farsighted it
will count all future rewards equally
an epsilon of 1.0 this is of course the
epsilon for epsilon greedy action
selection
so it will start out
behaving pretty much randomly and
eventually converge on a purely greedy
strategy
so q learning is a tabular method where
you have a table of state and action
pairs and you want to find the value of
those state action pairs so to construct
that we have to iterate over the set of
states and actions
state space plus
and
emv dot possible actions
and you have to pick something for an
initial value it's really arbitrary but
the cool thing about picking zero is
that we're using something called
optimistic initial values what this
means is that since the agent takes or
receives a reward of minus one for every
step
it can never have a reward of zero right
because there's some distance between
the agent and the exit
so by setting the
initial estimate at zero you actually
encourage exploration of unexplored
states because if the agent takes a move
it realizes oh i get a reward of -1
that's significantly worse than 0. let
me try this other unexplored option so
over time it will gradually explore all
the available actions for any given
state
because it's been disappointed by all
the stuff it has previously tried just a
fun little fact
we want to play
50 000 games
we need a way of keeping track of our
rewards
numpy array will do just fine yes
so now let's iterate over the total
number of games
and um
thief
i like to print out a
marker to the terminal so that way i
know
it's actually working
so every five thousand games just print
that we're starting
the ith game
at the top of every episode you want to
reset your done flag you want to reset
your episode rewards
so you don't accumulate rewards from
episode episode and of course you want
to reset your environment
oh let me scroll down here
there we go
you want to reset your environment
just as you would with any open ai gym
type problem
next up
we begin each episode so while not done
we want to take a
random number
for our
epsilon greedy action selection
so
we're going to just make use of this max
action before we define it
q
observation
and
env.possible actions
and what that will do is
uh we're going to write it here
momentarily but what it's going to do
is it is going to
find the maximum action for a given
state
so the random number is less than one
minus epsilon we want to do that can you
guys see that yep
otherwise
we want to take
a random sample of the action space so
we have to write these two functions
let's do that quite quickly
so the
action space sample is pretty
straightforward
we can just return a random choice from
the
list of possible actions and that's the
reason we chose a list as that data
structure just to make it easy
next up we have the max action max
yeah max action function
but that doesn't need to belong to the
class
that takes the q the state and the set
of possible actions
we want to take a numpy array of the
estimates agent
sorry the agent's estimate of the
present value of the expected future
rewards
for the stated stand in all possible
actions
a in actions
and then we want to find the maximum of
that
and that's just an index so we want oop
sorry that's just an index so we want to
return
the action that that actually
corresponds to
all right that's all well and good
we need more space
let's do a little bit more
there we go
so next
we want to actually take the action
so we get our new state observation
underscore reward done and info
envy.step action
and next up uh we have to calculate the
maximal action for this new state so
that we can insert that into
our
update equation for the q function
so let's do that
and we're not worried about epsilon
greedy here because we're not actually
taking that action
next up we have to update rq function
for the current action and state
and
that's where our alpha comes in
ward plus
make sure that is visible to you
reward plus
some quantity
which is gamma our discount factor times
q
observation underscore action underscore
so the new state and action
minus q observation
action
let me tab this over there we go
nice and compliant with the pep style
guides right
mostly
okay so this is the update equation for
the q function that will update the
agent's estimate
of the
value of the current state and action
pair
next up
we just need to let the agent know that
the uh environment has changed states so
you set observation to observation
underscore
and that is it for q learning in a
nutshell folks that's really that
straightforward
so the end of each episode we want to
decrease epsilon
so that way the agent eventually settles
on a purely greedy strategy
you can do this a number of ways you can
do it you know with a square root
function a log function
i'm just going to do it linearly
it's not that critical for something
like this
so
it's going to decrease it by 2 divided
by num games every every game so about
halfway through it'll be purely greedy
and at the end of every episode you want
to make sure you're keeping track of the
total rewards which is something i
forgot up here
yeah so one thing i did forget is to
keep track of the
total reward for the episode don't
forget that very important
and at the end of all the episodes
you want
to plot the total rewards
and that is it for the coding portion oh
one other thing i take it back so let's
scroll up here i do want to show you the
environment so
let's just do that env dot render
and the
purpose of doing that is so that you can
see how many moves it takes the agent to
escape from the grid world
that will tell us if it's doing good or
not right because there's a minimum
minimum number of moves it takes to
escape
so i'm going to fire up the terminal and
go ahead and get that started
one second
and here we are in the terminal
let's go ahead and run that
and you can see here that we start at
the top left so it takes one
two
moving to a out is free
so 3
4 5 6 7 8 9 10 11. sorry 11 and the 12th
move is free because it's the exit to
the maze sorry to the grid world so
total reward of minus 11 is the best the
agent can possibly do
it's gone ahead and plotted so let's
check that out and here is the plot and
you can see that indeed the agent starts
out
rather poorly
exploring finding sub-optimal routes
through the grid world but eventually
and about halfway through here at um
2500 or so sorry 25 000 you can see that
it settles on at least a constant value
let's prove that it is
the maximum value of minus 11 and you
can see that
it's 10.97 that is
close enough for government work so you
see that the agent
is able to actually solve the maze sorry
the grid world i keep calling it amaze
is able to solve the grid world using
the q learning algorithm now this isn't
surprising you know we would expect this
uh what's novel here is that we have
created our own reinforcement learning
environment that uses a very similar
format to the open ai gym
so anytime you want to create a new
environment you can use
you can fire this video up and use the
you know set of code here
just as a template for your own projects
i'm going to put this up on my github
i'll link that down below and i'm also
going to write up a tutorial for uh in
text form and upload it to neuralnet.ai
i don't know if all that done tonight
i'll update the description with it
that's if you are a
you know if you consume text more easily
than than video then you can go ahead
and check that out i hope this has been
helpful
uh make sure to leave a comment
subscribe if you haven't already and i
hope to see you all in the next video
welcome back data manglers thanks for
tuning in for another episode from
neuralnet.ai
if you're new to the channel i'm phil
tabor a physicist and former
semiconductor engineer turned machine
learning practitioner
i'm on a mission to teach the next
generation of data engineers so we can
stay one step ahead of our robot
overlords
if you're not subscribed be sure to do
that now so you don't miss any future
reinforcement learning content
we've touched on reinforcement learning
many times here on the channel
as it represents our best chance at
developing something approximating
artificial general intelligence
we've covered everything from monte
carlo methods to deep q q-learning to
policy gradient methods using both the
pi torch and tensorflow frameworks
what we haven't discussed on this
channel is the what and the how of
reinforcement learning
that oversight ends today
right now
okay maybe a few seconds from now but
either way we're going to cover the
essentials of reinforcement learning
but first let's take a quick step back
you're probably familiar with supervised
learning which has been successfully
applied to fields like computer vision
and linear regression
here we need mountains of data all
classified by hand just to train a
neural network
while this is proven quite effective it
has some pretty significant limitations
how do you get the data how do you label
it
these barriers put many of the most
interesting problems in the realm of
mega corporations and this does us the
individual practitioners no good
to top it off it's not really
intelligence
you and i don't have to see thousands of
examples of a thing to understand what
that thing is
most of us learn actively by doing
sure we can shortcut the process by
reading books or watching youtube videos
but ultimately we have to get our hands
dirty to learn if we abstract out the
important concepts here we see that the
essential stuff is the environment that
facilitates our learning the actions
that affect that environment and the
thing that does the learning the agent
no jacket or labels required
enter reinforcement learning this is our
attempt to take those ingredients and
incorporate them into artificial
intelligence
the environment can be anything from
text-based environments like card games
to classic atari games to real to the
real world
at least if you're not afraid of skynet
starting an all-out nuclear war that is
our ai interacts with this environment
through some set of actions which is
usually discrete move in some direction
or fire at the enemy for instance
these actions in turn cause some
observable change in the environment
meaning the environment transitions from
one state to another
so for example in the space invaders
environment in the open ai gym
attempting to move left caused the agent
to move left with 100 probability
that need not be the case though
in the frozen lake environment
attempting to move left can result in
the agent moving right or up or down
even
so just keep that in mind that these
state transitions are probabilistic and
their probabilities don't have to be one
hundred percent merely their sum the
most important part of the environment
is the reward or penalty the agent
receives
if you take only one thing away from
this video it should be that the design
of the reward is the most critical
component of creating effective
reinforcement learning systems
this is because all reinforcement
learning algorithms seek to maximize the
reward of the agent
nothing more nothing less
in fact this is where the real danger of
ai is
it's not that it would be malicious but
that it would be ruthlessly rational
the classic example is the case of an
artificial general intelligence whose
reward is centered around how many paper
clips it churns out sounds innocent
right
well if you're a paper clip making bot
and you figure out that humans consume a
bunch of resources that you need to make
paper clips
then those pesky humans are in the way
of an orderly planetary scale office
that's problematic for all involved
what this means is we must think long
and hard about what we want to reward
the agent for and even introduce
penalties for undertaking actions that
endanger human safety at least and
systems that will see action in the real
world
perhaps less dramatic although no less
important are the implications for
introducing inefficiencies in your agent
consider the game of chess
you might be tempted to give the agent a
penalty for losing pieces but this would
potentially prevent the agent from
discovering gambits where it sacrifices
a piece for a longer term positional
advantage
the alpha zero engine a chess playing
artificial intelligence is notorious for
this
it will sacrifice multiple pawns and yet
still dominate the best traditional
chess engines we have to offer
[Music]
so we have the reward the actions and
the environment what are the agent
itself
the agent is the part of the software
that keeps track of these state
transitions actions and rewards and
looks for patterns to maximize its total
reward over time
the algorithm that dictates how the
agent will act in any given situation or
state of the environment is called its
policy
it is expressed as a probability of
choosing some action a
given the environment is in some state s
please note these probabilities are not
the same as the state transition
probabilities
the mathematical relationship between
state transitions rewards and the policy
is known as the bellman equation and it
tells us the value meaning the expected
future reward of a policy for some state
of the environment
reinforcement learning often though not
always means maximizing or solving that
bellman equation more on that in future
videos
this desire to maximize reward leads to
a dilemma
should the agent maximize his short-term
reward by exploiting the best-known
action or should it be adventurous and
choose actions whose reward appears
smaller or maybe even unknown
this is known as the explore exploit
dilemma and one popular solution is to
choose the best known action most of the
time and occasionally choose a
sub-optimal action to see if there's
something better out there
this is called an epsilon greedy policy
when we think of reinforcement learning
we're often thinking about the algorithm
the agent uses to solve the bellman
equation
these generally fall into two categories
algorithms that require a full model of
their environment and algorithms that
don't
what does this mean exactly to have a
model of the environment
as i said earlier actions cause the
environment to transition from one state
to another with some probability
having a full model of the environment
means knowing all the state transition
probabilities with certainty
of course it's quite rare to know this
beforehand and so the algorithms that
require a full model are of somewhat
limited utility
this class of algorithms is known as
dynamic programming if we don't have a
model or a model of the environment is
incomplete we can't use dynamic
programming
instead we have to rely on the family of
model-free algorithms
one popular such algorithm is q learning
or deep q learning which you studied on
this channel
these rely on keeping track of the state
transitions actions and rewards to learn
the model of the environment over time
in the case of q-learning these
parameters are saved in a table and in
the case of deep q learning the
relationships between them are expressed
as an approximate functional
relationship which is learned by a deep
neural network
that's really all there is at least at a
high level
so to recap
reinforcement learning is a class of
machine learning algorithms that help an
autonomous agent navigate a complex
environment
the agent must be given a sequence of
rewards or penalties to learn what is
required of it the agent attempts to
maximize this reward over time or
mathematical terms to solve the bellman
equation
the algorithms that help the agent
estimate future rewards fall into two
classes
those that require we know the state
transition probabilities for the
environment beforehand and those that
don't
since knowing these probabilities is a
rare luxury we often rely on model-free
algorithms like deep queue learning
if you'd like to know more please check
out some of the other videos on this
channel
i hope this has been helpful please
leave a comment a like and subscribe if
you haven't already look forward to
seeing you all in the next video
welcome back to the free reinforcement
learning course from neuralnet.ai
i'm your host phil tabor
if you're not subscribed be sure to do
that now and hit the bell icon so you
get notified for each new module in the
course
in module 1 we covered some essential
concepts in reinforcement learning so if
you haven't seen it go ahead and check
it out now so this module makes more
sense
if you have seen it you may remember
that reinforcement learning basically
boils down to an agent interacting with
some environment and receiving some
rewards in the process
these rewards tell the agent what's good
and bad and the agent uses some
algorithm to try to maximize rewards
over time
in practice what we get is a sequence of
decisions by the agent and each decision
doesn't just influence its immediate
reward rather each decision influences
all future rewards
in mathematical terms we have a sequence
of states actions and rewards that one
could call a decision process
if each state in this process is purely
a function of the previous state and
action of the agent then this process is
called a markov decision process or mdp
for short
these are an idealized mathematical
abstraction that we use to construct the
theory of reinforcement learning
for many problems this assumption can be
broken to various degrees
how much that really matters is often a
complicated question and one we're just
going to dodge for now
regardless in most cases the assumption
that a process obeys the markov property
is good enough and we can use all the
resulting mathematics
for reinforcement learning problems
by now i've said that a reinforcement
learning agent seeks to maximize rewards
over time
so how does this fit into a markov
decision process
from the agent's perspective it receives
some sequence of rewards over time and
that sequence of rewards can be used to
construct the expected return for the
agent
then the return at some time step t
is just the sum of the rewards that
follow
all the way up to some final time
capital t
this final time step naturally
introduces the concept of episodes which
are discrete periods of gameplay that
are characterized by state transitions
actions and rewards
upon taking this final time step the
agent enters some terminal state which
is unique
this means that no matter how we end the
episode the terminal state is always the
same
no future rewards follow after we reach
the terminal state so the agent's
expected reward for that terminal state
is precisely
zero
with a bit of creativity we call tasks
that can be broken into episodes
episodic tasks
of course not all tasks are episodic
many are in fact continuous this is a
bit of a problem since if the final time
step is at infinity the total reward
could also be infinite this makes the
concept of maximizing rewards
meaningless so we have to introduce an
additional concept
the fix and we use this for both
episodic and continuing tasks is the
idea of discounting
this basically means the agent values
future rewards less and less
this discounting follows a power law
where each time step results in more and
more discounting
this hyperparameter gamma is called the
discount rate and you've no doubt seen
this before in our videos on
reinforcement learning
if you use this form for the expected
return and do some simple factoring you
derive a really useful fact
there is a recursive relationship
between rewards at subsequent time steps
this is something we'll exploit
constantly in reinforcement learning
so we have an agent that is engaged in
some discrete processes receiving
rewards and trying to maximize its
expected feature returns
if you remember from the first lecture
the algorithm that determines how the
agent is going to act is called its
policy
since the agent has a set of defined
rules for how it's going to act in any
given state
it can use a sequence of states actions
and rewards to figure out the value of
any given state
the value of a state is the expected
return when starting in that state and
following the policy
it's given formally by the following
equation
in some problems like say q learning
we're more concerned with maximizing the
action value function which tells the
agent the value of taking some action
while in some given state and following
the policy thereafter
[Music]
remember how i said we can exploit the
recursive relationship between
subsequent returns
well if we plug that into the expression
for the value function we actually
discover that the value function itself
is defined recursively
this is called the bellman equation from
the first module and this is the
quantity many algorithms seek to
maximize
the bellman equation is really an
expectation value as it's a weighted
average of how likely each particular
sequence of states actions and rewards
is given the state transition
probabilities and the probability of the
agent selecting that action
much of the following material will
involve coming up with various schemes
to solve the bellman equation and evolve
the policy in such a way that the value
function increases over time
in the next module we'll take a look at
the explore exploit dilemma which is the
expression of the trade-off between long
and short-term rewards
i hope this has been helpful
questions comments suggestions leave
them below i read and answer all my
comments if you made it this far
consider subscribing so you get notified
when the rest of the course drops i look
forward to seeing you
in the next video
welcome to module 3 of the free
reinforcement learning course from
neural net dot ai i'm your host phil
taper if you're not subscribed make sure
to do that now so you don't miss the
rest of the course
in the previous video we learned about a
special type of process called the
markov decision process
there each state depends only on the
previous state and the action taken by
the agent
this leads to the recursive relationship
between the agent's estimate of returns
at successive time steps
this relationship extends to the agent's
estimate of the value function which is
given by the bellman equation
as we covered in module 1 reinforcement
learning for the most part boils down to
maximizing this value function
however it's not always so simple
surprise surprise
just like you and i have trade-offs in
real life
reinforcement learning agents are faced
with similar considerations
should the agent take the action that it
knows will immediately provide the most
reward or should it explore other
actions to see if it can do better this
conundrum is known as the explorer
exploit dilemma and every reinforcement
learning algorithm has to deal with this
fortunately there are many solutions and
we'll cover some of them here
one such solution is the idea of
optimistic initial values
when the agent starts playing the game
it has to use some initial estimate for
the value or action value function
this estimate is totally arbitrary but
if you know something about the reward
structure beforehand we can actually
initialize it in such a way as to
encourage exploration
suppose we have an environment like our
grid world and the video on creating our
own reinforcement learning environment
in that environment the agent receives a
reward of minus one for each step and so
the expected returns are always negative
or zero no matter the state of the
environment or the action the agent
takes
so what would happen if we tell the
agent that the value of all the state
action pairs are positive or even zero
on the first move the agent picks some
action randomly because all the actions
look identical
it receives a reward of -1 and updates
his estimates accordingly
so it's a bit disappointed it was
expecting chocolate cake and got a mud
pie
the next time it encounters that state
it will take a different action because
the other actions have an estimate of
zero reward for that state which is
better than the negative reward it
actually received this means that the
agent ends up exploring all the state
action pairs many times as each update
makes the agent's estimate more and more
accurate
we never had to explicitly tell the
agent to take exploratory actions
because it's greed drobit to take
exploratory actions after it became
disappointed with whatever action it
just took
again this is called optimistic initial
values
another feasible solution is to spend
some portion of the time choosing random
actions and the majority of the time
choosing greedy actions this is called
an epsilon greedy strategy and it's the
one we employ the most
it's quite robust as we can change the
random parameter over time so the agent
converges onto a nearly pure greedy
strategy
the proportion of the time the agent
spends exploring is a hyper parameter of
the problem and we typically call it
epsilon
one potential strategy is to start out
completely randomly and then use some
decay function to gradually increase the
proportion of greedy actions the agent
takes
the form of this function isn't
critically important it can be linear a
power law or really any other function
whether or not the agent converges to a
purely greedy strategy is going to
depend on the problem
for simple environments like the grid
world where we know the optimal solution
beforehand it makes quite a bit of sense
converged to a purely greedy strategy
however with a game like space invaders
a popular environment from the open ai
gym there are so many variables that
it's hard to be sure the agent has
settled on the truly optimal strategy
the solution there is to leave epsilon
at some small but finite value so the
agent is occasionally taking exploratory
actions to test its understanding of the
environment
all this discussion has made a very
important assumption
we've assumed the agent only uses a
single policy
the agent uses both the same policy to
update his estimate of the value
function as well as to generate actions
there's no rule this has to be the case
in fact an agent can leverage two
policies
it can use one policy to generate
actions and then use the data that
generates to update the value function
for some other policy
this is called off policy learning and
this is precisely what we use in
q-learning
the agent uses some epsilon greedy
strategy to generate steps in the markov
chain which is the sequence of state
action rewards and resulting states and
then uses that data to update the
estimate of the action value function
for the purely greedy action in effect
we're using an epsilon greedy strategy
to update our estimate of the purely
greedy strategy
needless to say this works quite well
and it's something we'll come back to in
later modules when we get to monte carlo
methods and temporal difference learning
that's it for now
reinforcement learning agents seek to
maximize their total reward but face a
dilemma of whether to maximize current
reward or take exploratory steps with
suboptimal actions in the hope of
optimizing long-term rewards
one solution is to bias the agent's
initial estimates in such a way that it
encourages exploration before settling
on a purely greedy strategy
another is to spend some proportion of
the time exploring and the majority of
the time exploiting the best known
action
and finally the agent can leverage two
policies one to generate data and the
other to update the estimate of the
action value or value function
in the next module we're going to get to
dynamic programming class of model based
reinforcement learning algorithms
make sure to subscribe so you don't miss
the remainder of this course and i look
forward to seeing you in the next video
welcome back everybody to machine
learning with phil i am your host dr
phil
when we last touched on the open ai gym
we did q-learning to teach the cartpole
robot how to dance basically how to
balance the pole
in this video we're going to take a look
at a related algorithm called sarsa so
they're related in the sense that
they're both types of temporal
difference learning algorithms the
difference being that
sarsa is an on policy method and q
learning is an off policy method
hey appearance by the cat um
if you if you don't know what that means
i highly encourage you to check out my
course reinforcement learning in motion
on manning publications i go in depth on
all this stuff
in that course uh enough plugging let's
get back to it so the other cool thing
is that it that sarsa as well as q
learning are model free meaning that you
do not need a complete model of your
environment to actually get some
learning done and that's important
because there's many cases in which you
don't know the full model of the
environment what does that mean it means
you don't know the state transition
probabilities so if you're in some state
s and take some action a what is the
probability you will end up in state s
prime and get reward r those
probabilities are not completely known
for all problems and so
algorithms that that handle that
uncertainty are critical for real-world
applications
another neat thing is uh that this is a
bootstrapped method meaning that it uses
estimates to generate other estimates
right so you don't need to know too much
about the system to get started you just
make some wild ass guesses and you get
moving let's take a look at the
algorithm
so uh your first step is to initialize
your learning rate alpha
uh and of course that's going to control
the rate of learning how quickly you
make adjustments to the q function uh
then you initialize the q function the q
function is just the agent's estimate of
its discounted future rewards
starting from a given state s and taking
an action a and it may have some
assumptions built in onto whether or not
you follow some particular policy or not
but that's a general gist
so you need to initialize your state and
choose some initial action based on that
state using an epsilon greedy strategy
from that function q
then you loop over the episode taking
the action getting your reward and your
new state s prime choose an action a
prime as a function of that state s
prime using epsilon greedy from your q
function and then go ahead and update
the q function according to the update
rule you see on the screen and then go
ahead and store your state prime into s
and your a prime into a and loop until
the episode is done again in the course
i go into many more details this is just
quick and dirty a bit of a teaser video
to get you guys
interested in the course and to give you
some useful information at the same time
so with that being said let's go ahead
and jump into the code i'm not going to
be doing typing on screen
but i will be showing you the relevant
code as we go along
and boom we are back in the code editor
so here i am using visual studio code um
even on linux this is a great editor if
you're not using it i highly recommend
it adam was a little bit buggy for me
and of course sublime is now is nag ware
so go ahead and give it a look if you
haven't already so
we need to define a function to
take the max action and that takes as
inputs the q function as well as the
state and you're just converting
the um
the q function into an array and to a
numpy array uh for each action in that
in that list
and finding the arg max of that now
recall that in numpy the arg max takes
the
returns the first element of a max so if
you have two actions that are tied it'll
give you the first one so of course in
the cart poll example our action space
is just moving left and right right if
you don't remember it's just a cart that
slides along the x-axis
trying to keep a pole vertical
of course this is a continuous space and
the q function is a discrete uh a
discrete mathematical construct right so
the states are discrete numbers and so
you have to do a little trick here to
discretize your space and so if you look
in the documentation for the cartpole
example you'll find the limits on these
variables and you can use that to create
a linear space based out of it
based on those limits and divide it up
into 10 different buckets right so that
way you get
you go from a continuous representation
to a discrete representation of your
state space
and then i define a small helper
function here
to get the state based on the
observation it just digitizes these
it digitizes those linear spaces using
the observation that you pass in from
the open ai gym
and it returns a four vector that is a
the buckets that correspond to the
value of the
element of the observation
the main program we want to use
small learning rate alpha 0.1
for a gamma something like 0.9 of course
the gamma is the discount factor it's
debatable whether or not you need it
here so
discounting in general is used when you
don't know the
we you don't know for certain you're
going to get some reward in the future
so it doesn't make sense to give it a
100 percent weight you could just as
easily here use a 1.0
because the state transition functions
in the cardboard example are
deterministic as far as i'm aware some
if i'm wrong please someone correct me
and of course the epsilon for the
epsilon greedy we're going to start out
at 1.0
you'll see why here in a second
and so you need to construct the set of
states which of course
just corresponds to the
integer representations of our
continuous space so you just have um
ranges from zero to zero to nine
and you construct a four vector out of
out of that right so you have zero zero
zero one one one et cetera et cetera et
cetera
and initialize your q function here i'm
going to initialize everything as
a zero right recall that we had to
we could initialize it arbitrarily but
for the terminal states you want that to
be zero because again the value of the
terminal state is zero and a is two in a
range of two because we only have two
actions move left move right
whoops
also i'm gonna run fifty thousand games
if you have a slower computer you might
wanna run fewer it takes quite a bit of
time to run and i'm going to track the
total rewards as we go along
so
just a little helper line here to print
out the the number of games you're
playing it's always good to know where
you are right you if it stops chugging
along you want to know if it's broken or
actually doing something useful
so you get your initial observation by
resetting the environment get your state
and calculate a random number and so you
take a maximum action if the random
number is less than one minus epsilon so
epsilon is starting out at one so if
random is less than zero otherwise
randomly sample your action space
done flag defaults and your rewards for
the episode to zero
then you loop over the episode until
you're done
and you go ahead and take the action a
getting your reward and the new
observation
the
state prime then is going to be the
get state of the observation right these
observation is a four vector of
continuous numbers that we have to
transform into a set of discrete
integers a four vector of discrete
integers then we go ahead and calculate
another random number and choose another
action based upon that
then calculate sum up the total rewards
and update the q function based on the
update rule i gave you in the slides and
of course set the state in action to the
new the s prime and a prime
and after each episode you're going to
decrease epsilon because you want this
you don't want the epsilon to be
permanently one right you want to
encourage some amount of exploration and
some amount of exploitation so epsilon
has to be a function of time
and just save your total rewards when
it's all done it's going to go ahead and
plot it out
and you should see something similar to
the following i'm going to go ahead and
run that now
and that is going to take a minute to
run and so here you have the output of
the source algorithm after running 50
000 iterations so what you see is first
of all a messy plot that's to be
expected with 50 000 games when you're
plotting every single point but what you
notice immediately is that there is a
general trend upward and when epsilon
reaches its minimum epsilon goes to zero
and it does a fully exploitative
strategy the algorithm actually does a
really good job of hitting 200 moves
most of the time recall that 200 moves
is the
um
200 moves is the maximum number of steps
for the cart pull problem uh because
good algorithms can get it to to balance
uh pretty much indefinitely so it would
never terminate so the open ai gym just
terminates at 200 steps so anything
close to that is pretty good now one
thing that's interesting is that it does
have a fair amount of variability it
doesn't actually
balance it 200 moves the entire time and
there are a number of reasons for this
perhaps you can speculate below i invite
you to speculate my thought process is
that the
the way we have discretized this space
isn't sufficient to characterize the
problem
in such a way that the algorithm can
learn something completely and totally
useful so it just doesn't have enough
information based on the ten thousand
ten of the four yeah ten thousand uh
states we've we've
discretized it into
uh and there could be other things that
matter you know uh you could have other
features for instance
combinations of velocities and positions
that matter so we could have under
engineered the problem slightly but for
just a quick little
chunk of
170 lines of code or so it's actually
quite good
so uh any questions be sure to leave
them below and hey if you've made it
this far and you haven't subscribed
please consider i'm going to be
releasing more and more content like
this i'm doing this full time now um
and i look forward to seeing you all in
the next video oh and by the way in the
next video we're going to be taking a
look at double q learning uh which is
yet another variation of these uh model
free bootstrap methods see you then
oh and one other thing if you want the
code for this i'll leave the code i'll
leave the link to my github
this is code for my course reinforcement
learning and motion i'm just showcasing
it here to show what you're going to
learn in the course so go ahead and
click the link in the description and
it'll take you to my github where you
can find that code as well as all the
code from the course
hope you like it see you guys in the
next video
welcome back everybody to machine
learning with phil i am your host dr
phil
in yesterday's video we took a look at
sarsa in the open ai gym getting the
cart pole to balance itself as promised
today we are looking at the algorithm of
double queue learning also in the
cartpole openaigm environment
so we touched on q-learning many many
months ago and the basic idea is that
q-learning is a
model-free bootstrapped off-policy
learning algorithm what that means is
model-free it does not need to know it
does not need the complete state
transition dynamics of the environment
to function it learns the game by
playing it bootstrapped in that it
doesn't need very many very much help
getting started it generates
estimates using its initial estimates
which are totally arbitrary except for
the
terminal states off policy meaning that
it is using a separate policy other than
it is using a behavioral policy and a
target policy to to both learn about the
environment and generate behavior
respectively
now when you deal with problems that uh
when you deal with algorithms that take
a maximizing approach to choosing
actions you always get something called
maximization bias so say you have some
set of states with many different
actions such that the action value
function for that state and all actions
is zero
then the
agent's estimate the q capital q of s a
can actually be
will actually have some uncertainty to
it and that uncertainty is actually a
spread in the values right and that
spread causes it to have some amount of
positive bias
and the max of the true values is zero
but the max of the capital q the agent's
estimate is positive hence you have a
positive bias and that can often be a
problem in
in reinforcement learning algorithms so
this happens because you're using the
same set of samples to max to determine
the maximizing action as well as the
value of that action and one way to
solve this problem is to use two
separate q functions to determine the
max action and the value and you
set up a relationship between them and
then you alternate between them as you
play the game so you're using one of
them to determine the max action one of
them to determine its value and you
alternate between them so that you
eliminate the bias over time
that's double q learning in a nutshell
the algorithm is the following so you
initialize your alpha and your epsilon
where alpha is your learning rate
epsilon is what you use for epsilon
greedy you want to initialize the q1 and
q2 functions for all states and actions
in your state in action space of course
that's arbitrary except for the terminal
states which must have a value of zero
and you loop over your set of episodes
and you initialize your state and for
each episode write each step within the
episode choose an action from uh using
your state using epsilon greedy strategy
in the sum of q1 and q2 so you have the
two separate q functions
so if you're using single queue learning
you would take the
max action over just one queue but since
you're dealing with two you have to
account for that somehow right you could
do a max you could do a sum
you could do an average in this case
we're going to take the sum of the two q
functions take that action get your
reward observe the new state and then
with the 0.5 probability either update
q1 or q2 according to this update rule
here and of course at the end of the
step go ahead and set your estate to the
new state and keep looping until the
game is done
so clear as mud i hope so by the way if
you want more reinforcement learning
content make sure to subscribe hit the
bell icon so you get notified
let's get to it so next up we have our
code
and here we are inside of our code
editor again i'm using visual studio
code to take a look at our double queue
learning script i'm not going to be
typing into the terminal i think that's
probably a little bit annoying i'm just
going to review the code as we go along
if you have seen my video on the source
algorithm there's going to be a fair
amount of overlap because we're solving
the same set of problems over again the
only real difference is
in that video we source it to calculate
the
action value function and in this case
we're using double q learning
again we have a max action function what
this does is tells us the max action for
a given state to construct that you make
a numpy array out of a list that is for
a given state both actions and as we
said in the video we're going to take
the sum of the q1 and q2 for a given
state for both actions
you want to take the arg max of that and
recall in numpy the arg max function
if there is a tie returns the first
element so if the left and right actions
both have identical action value
functions then it will return the left
action consistently
that may or may not be a problem it's
just something to be aware of
and once again we have to discretize the
spaces recall that the cart pull problem
which is just the cart sliding along a
track with a pole that is that must be
maintained vertically right
in the cart pole example we have a
continuous space the x and the theta can
be any number
within a given range and likewise for
the velocities
to deal with that we have a couple
options we could simply use neural
networks to approximate those functions
but in this case we're going to use
a little trick to discretize the space
so we're going to divide it up into 10
equal chunks and any number that falls
within a particular chunk will be
assigned an integer so you'll go from a
continuous to a
discrete representation of your four
vector the observation
along with that comes a get state
observat state
along with that comes a get state
function
that
you pass in the observation
and it just uses those
uh digitized spaces excuse me just use
those linear spaces
to use the numpy digitized function to
get the integer representation
of the respective elements of your
observation
i've also added a function to plot the
running average here i do this because
in the sarsa video we end up with a
little bit of a mess with 50 000 data
points this will plot a running average
over the prior 100 games
next up we have to initialize our hyper
parameters our learning rate of 0.1 this
just controls the step size in the
update equation the gamma is of course
the discount factor the agent uses in
its estimates of the future rewards
so i don't believe this should actually
be 0.9 i i left it here because it's not
super critical as far as i'm concerned
it should really be 1.0 and the reason
is that
the purpose of discounting is to account
for uncertainties and future rewards if
you have some sequence of rewards with a
probability of receiving them then it
makes no sense to
give each of those rewards equal weight
because you don't know if you're going
to get them in the cart poll example the
rewards are certain as far as i'm aware
the state transition probabilities are
one you know that if you move right
you're going to actually end up moving
right you know deterministically where
the pole and the cart are going to move
so it shouldn't be discounted as far as
i'm concerned epsilon is just the
epsilon factor for our for our epsilon
greedy
algorithm and
that's
pretty much it for hyperparameters of
the model next up we have to construct
our state space so what this means oh
baby's unhappy
the state space is of course the
um the representation of the digitized
space so we're going to have
for the cart position you're going to
have 10 buckets the velocity is 10
buckets and likewise for the thetas
theta position and theta velocity so
you're going to have 10 to the four
possible states so 10 000 states and
those are going to be numbered all the
way from 0 0 0 to 99.99 that's all we're
doing here is we're constructing the set
of states
next up we have to initialize our q
functions recall that the initialization
is arbitrary except for the terminal
state which must have a value of zero
the reason for this is that the
terminal state by definition has a
future value of zero because you stopped
playing the game right makes sense you
could initialize this randomly you could
initialize it with minus one plus one
doesn't really matter so long as the
terminal state is zero for simplicity
i'm initializing everything at zero
i'm going to play a hundred thousand
games the reason is that this algorithm
eliminates bias but at the expense of
convergence speed so you have to let it
run a little bit longer
uh an array for keeping track of the
total rewards and we're gonna loop over
a hundred thousand games printing out
every five thousand games to let us know
it's still running
always want to reset your done flag your
rewards and reset the episode at the top
and you're going to loop over the
episode getting your state
calculating a random number for your
epsilon greedy strategy you're gonna set
the action to be the max action of q1
and q2 if the random number is less than
one minus epsilon otherwise you're going
to randomly sample your action space in
any event you take that action get your
new state reward and done flag and go
ahead and tally up your reward and
convert that observation to a state s
prime
then go ahead and calculate a separate
random number the purpose of this random
number is to determine which q function
we're going to update you know we're
going to be using one to calculate
we're alternating between them because
we have to eliminate the
maximization bias right one is for
finding the max action one is for
finding the value of that action we
alternate between episodes by way of
this random number
in both cases you want to collect the
you want to calculate the max action
either q1 or q2 and use the update rule
i showed you in the slides to update the
estimates for q1 and q2
as you go
at the end of the episode sorry at the
end of the step excuse me you want to
reset the
old observation to the new one so that
way you can get
the state up here and at the end of the
episode you want to go ahead and
decrease epsilon if you're not familiar
with this
epsilon greedy is just a strategy for
dealing with the explore exploit dilemma
so an agent always has some estimate of
the future rewards based on its model of
the environment or its experience
playing the game if it's model free or
a model uh problem
right it can either explore or exploit
its best known actions so one way of
dealing with the dilemma of how much
time should you spend exploring versus
how much time should you spend
exploiting is to use something called
epsilon greedy meaning that some
percentage of the time you explore some
percentage of the time you exploit
and the way that you get it to settle on
a greedy strategy is to gradually
decrease that
exploration parameter epsilon over time
and that's what we're doing here
and of course you want to keep track of
the total rewards for that episode and
recall in the current poll example
the agent gets a reward of positive one
every time the poll stays
vertical so every move that it doesn't
flop over it gets one point
and at the end you're going to go ahead
and plot your running averages
so i'm going to go ahead and run that
and that'll take a minute uh while it's
running i want to ask you guys a
question so what type of material do you
want to see
from what i'm seeing in the data the
the reinforcement learning stuff is
immensely popular my other content not
so much so i'm going to keep focusing on
this type of stuff but are you happy
seeing the sutton bardo type
introductory material or do you want to
see more deep learning type material
right there's a whole host of dozens of
deep reinforcement learning algorithms
we can cover
but i'm actually quite content to cover
this stuff because
i believe that if you can't master the
basics then the deep learning stuff
isn't going to make sense anyway right
because you have the complexity of deep
learning on top of
the
complexity of the reinforcement learning
material on top of it
so if there's anything in particular you
guys want to see make sure to leave a
comment below and hey if you haven't
subscribed and you happen to like
reinforcement learning and machine
learning material please consider doing
so if you like the video make sure to
leave a thumbs up hey if you thought it
sucked go ahead and leave a thumbs down
and tell me why i'm happy to answer the
comments answer your objections and if
you guys have suggestions for
improvement i'm all ears
and here we are it is finally finished
with all hundred thousand episodes
and you can see here the running average
over the course of those games
as you would expect the agent begins to
learn fairly quickly
balancing the cart pull more and more
and more by about 60 000 games it starts
to hit the consistently hit the 200 move
threshold where it is able to balance
the cart pull all 200 moves of the game
now recall this was with a gamma of 1.0
i'm going to go ahead and rerun this
with a gamma of 0.9 and see how it does
so burn this image into your brain and
i'm going to go ahead and check it out
with a gamma of 0.9 and see if we can do
any better
and we are back with the second run
using a gamma of 0.9 and you can see
something quite interesting here
so it actually
only kind of ever reaches the 200 mark
uh
just for a handful of games and then
kind of stutters along actually
decreasing in performance as it goes
along so something funny is going on
here and to be frank i off the top of my
head i'm not entirely certain why so
i invite you all to speculate however
the
what's also interesting is that i this
is the second time i'm recording this i
recorded it earlier and didn't scroll
down the code so you ended up staring at
the same chunk of stuff had to redo it
and in that case i had a gamma of 0.9 as
well and it seemed to work just fine so
i suspect there's some significant
variation here to do with the random
number generator
um
it could just all be due to that right
this is a complex space and it
wanders around different portions this
could happen potentially because it
doesn't visit all areas of the parameter
space enough times to get a reasonable
estimate of the samples and there may be
some type of bias on where it visits
later on in the course of the episodes
although that sounds kind of unlikely to
me but either way that is double q
learning you can see how the
hyper parameters actually affect the
model it seems to have a fairly large
effect as you might expect
and the next video we're going to be
taking a look at double sarsa so if you
are not subscribed i ask you to please
consider doing so hit the notification
icon so you can see when i release that
video i look forward to seeing you all
in the next video
well i hope that was helpful everyone so
what did we learn we learned about
q-learning policy gradient methods sarsa
double q learning and even how to create
our own reinforcement learning
environments this is a very solid
foundation in the topic of reinforcement
learning and you're pretty well prepared
to go out and explore more advanced
topics so what are those more advanced
topics so right now the forefront are
things like deep deterministic policy
gradients which is as you might guess
from the name a more
advanced version of policy gradient
methods they're also actor critic
methods
uh behavioral cloning there's all sorts
of more advanced topics out there that
you're now pretty well equipped to go
explore
these are particularly useful in
environments where you have continuous
action spaces so all the environments we
studied in this set of tutorials have a
discrete action space meaning the agent
only moves
or takes some discrete set of actions
other environments such as the bipedal
walker
car racing things of that nature have
continuous state spaces so excuse me
continuous action spaces which require
different mechanisms to solve q learning
really can't handle it so you're now
free to go ahead and check that stuff
out if you've made it this far please
consider subscribing to my channel
machine learning with phil and i hope
this is helpful for all of you leave a
comment down below and make sure to
share this and i'll see you all
in the next video
Full transcript without timestamps
welcome to the reinforcement learning jump start series i'm your host phil tabor if you don't know me i'm a physicist and former semiconductor engineer turned machine learning practitioner in this series of tutorials you're going to learn everything you need to know to get started with reinforcement learning you don't need any prior exposure all you really need is some basic familiarity with python as far as requirements for this course they are pretty light you will need the open ai gym because we're going to be taking advantage of that rather extensively you'll also need the atari extension for that so we can play games like breakout space invaders you'll also need the box 2d extension so we can do the new lander environment and beyond that you will need the tensorflow library as well as pytorch and i'm going to have tutorials in both tensorflow and pi torch with a bit of a stronger emphasis on tensorflow i'm going to teach the course in somewhat of a top-down fashion meaning we're going to get to the really important and exciting new stuff like deep q learning and policy gradient methods first after that we'll kind of back up and take a look at things like sarsa double q learning and we'll even get into how to make your own reinforcement learning environments when we code up our own grid world and then solve it with regular q learning if you missed something in the code don't worry i keep all this code on my github which i will link in the pin comment down below i'll also link the relevant timestamps for all the material in case you want to jump around because maybe some topics interest you more or you want to get some additional background information from the explainer videos questions comments leave them down below i will address all of them let's get to it in this video you're going to learn everything you need to know to implement q-learning from scratch you don't need any prior exposure to q-learning you don't even really need much familiarity with reinforcement learning you get everything you need in this video if you're new here i'm phil and i'm here to help you get started with machine learning i upload three videos a week so make sure to subscribe so you don't miss out imagine you've just gotten the recognition you deserve in the form of offers for a machine learning engineering position from google facebook and amazon all three are offering you a boatload of money and your dreams are big balling or interrupted by the realization that starting salary is just well the starting salary you've got friends at each of the three companies so you reach out to find out about the promotion schedules with each facebook offers two hundred fifty thousand dollars to start with a ten percent raise after three years but with a forty percent probability that you'll quit google offers two hundred thousand dollars to start with the twenty percent raise after three years but with only a 25 probability that you'll quit amazon offers 350 000 to start with a five percent raise after five years with a sixty percent chance that you'll end up washing out so what should you take all three of our big money but future raises are far from certain this is the sort of problem reinforcement learning is designed to solve how can an agent maximize long-term rewards in environments with uncertainties learning is a powerful solution because it lets agents learn from the environment in real time and quickly learn novel strategies for mastering the task at hand q learning works by mapping pairs of states and actions to the future rewards the agent expects to receive it decides which actions to take based on a strategy called epsilon greedy action selection basically the agent spends some time taking random actions to explore the environment and the remainder of the time selecting actions with the highest known expected feature rewards epsilon refers to the fraction of the time the agent spends exploring and it's a model hyperparameter between 0 and 1. you can gradually decrease epsilon over time to some finite value so that your agent eventually converges on a mostly greedy strategy you probably don't want to set epsilon at zero exactly since it's important to always be testing the agent's model of the environment after selecting and taking some action the agent gets its reward from the environment what sets q-learning apart from many reinforcement learning algorithms is that it performs its learning operation after each time step instead of at the end of each episode as is the case with policy gradient methods at this point it's important to make a distinction traditional q learning works by literally keeping a table of state and action pairs if you're implementing this in python you could use a dictionary with state and action tuples as keys this is only feasible in environments with a limited number of discrete states and actions here the agent doesn't need to keep track of its history since it can just update the table in place as it plays for the game the way the agent updates his memories by taking the difference in expected returns between the actions it took with the action that had the highest possible future returns this ends up biasing the agent's estimates over time towards the actions that end up producing the best possible outcomes when we're dealing with environments that have a huge number of states or state space that is continuous then we really can't use a table in that case we have to use deep neural networks to take these observations of the environment and turn them into discrete outputs that correspond to the value of each action this is called deep q learning the reason we have to use neural networks is that they are universal function approximators it turns out the deep neural nets can approximate any continuous function which is precisely what we have the relationship between states actions and feature returns is a function that the agent wants to learn so it can maximize its future rewards deepq learning agents have a memory of the states they saw the actions they took and the rewards they received during each learning step the agent samples a subset of this memory to feed these states through its neural network and compute the values of the actions it took just like with regular q learning the agent also computes the values for the maximal actions and uses the difference between the two as its loss function to update the weights of the neural network so let's talk implementation in practice we end up with two deep neural networks one network called the evaluation network is to evaluate the current state and see which action to take and another network called the target network that is used to calculate the value of maximal actions during the learning step the reasoning for why you need two networks is a little complicated but basically it boils down to eliminating bias in the estimates of the values of the actions the weight of the target network are periodically updated with the weights of the evaluation network so that the estimates of the maximal actions can get more accurate over time if you're dealing with an environment that gives pixel images just like in the atari library from the openai gym then you will need to use a convolutional neural network to perform feature extraction on the images the output from the convolutional network is flattened and then fed into a dense neural network to approximate the values of each action for your agent if the environment has movement as most do then you have an additional problem to solve if you take a look at this image can you tell which way the ball or paddle is moving it's pretty much impossible for you to get a sense of motion from just a single image and this limitation applies to the deep q learning agent as well this means you'll need a way of stacking frames to give the agent a sense of motion so to be clear this means that the convolutional neural network takes in the batch of stacked images as input rather than a single image choosing an action is reasonably straightforward generate a random number and if it's less than the epsilon parameter pick an action at random if it's greater than the agent's epsilon then feed the set of stacked frames through the evaluation network to get the values for all the actions in the current state find the maximal action and take it once you get the new state back from the environment add it to the end of your stacked frames and store the stacked frames actions and rewards in the agent's memory then perform the learning operation by sampling the agent's memory it's really important to get a non-sequential random sampling of the memory so that you avoid getting trapped in one little corner of parameter space as long as you keep track of the state transitions actions and rewards in the same way you should be pretty safe feed that random batch of data through the evaluation and target networks and the compute the loss function to perform your loss minimization step for the neural network that's really all there is to deep cue learning a couple neural networks a memory to keep track of states and lots of gpu horsepower to handle the training speaking of which of course you'll need to pick a framework preferably one that lets you use a gpu for the learning pytorch and tensorflow are both great choices and both support model checkpointing this will be critical if you have other stuff to do and can't dedicate a day or so for model training that's it for now make sure to share the video if you found it helpful and subscribe so you don't miss any future reinforcement learning content i'll see you in the next video in this tutorial you're going to learn how to use deep q learning to teach an agent to play breakout in the tensorflow framework you don't need to know anything about deep q learning you don't even need to know anything about tensorflow you just have to follow along let's get started if you're new to the channel i'm phil a physicist and former semiconductor engineer turned machine learning practitioner here at machine learning with phil we do deep reinforcement learning and artificial intelligence tutorials three times a week so if you're into that kind of thing hit that subscribe button let's get to the video so if you're not familiar with deep q learning the basic idea is that the agent uses a convolutional neural network to turn the set of images from the game into a set of feature vectors those are fed into a fully connected layer to determine the value of each of the actions given some set of states in this case a set of states is just going to be a stack of frames because we want the agent to have a sense of motion so as we go along we'll be stacking up frames passing them into our network and asking the network hey what is the value of either of the actions move left move right or fire a ball we're going to split this into two classes one of which will house the deep q networks and the other will house the agent and in the agent class we're going to have other stuff that we'll get to later let's go ahead and start with our imports we'll need os to handle model saving we'll need numpy to handle some basic random functions and of course tensorflow to build our agent so we'll start with our deepq network the initializer is pretty straightforward we're going to take the learning rate number of actions the name of the network that is important because we're gonna have two networks one to select an action one to tell us the value of an action more on that later the number of dimensions in the first fully connected layer the input dimensions of our environment so for the atari gym sorry the atari library of the open ai gym all of the images have 210 by 160 resolution and we're going to pass in a set of frames to give the agent a sense of motion we're going to pass in four frames in particular so it's going to be 210 by default 210 160 by 4. we're going to do some cropping later on we'll get to that in a minute we also need a directory to save our model so the next thing we need is the tensorflow session this is what instantiates everything into the graph and each network wants to have its own then we'll call the build network function to add everything to the graph once you've added everything to the graph you have to initialize it very important tensorflow will complain if you don't do that so best to do that now and the way you do that is by calling the tf global variables initializer function other thing we need is a way of saving our models as we go along and this is critical because this deep queue network takes forever to train i let it train for about 10 hours and it averages a score of two to three points per set of uh whatever number of lies it gets so it's going to have to train for quite some time so we're going to want to be able to save it as we go along because we have other stuff to do right and of course you want a way of saving your checkpoint files next thing we need is a way of keeping track of the parameters for each particular network and you do that like this so what this will do is tell tensorflow that we want to keep track of all of the trainable variables for the network that corresponds to whatever the name of this particular network is we use this later when we copy one network to another next let's build our network so we're gonna encase everything in a scope that is based on the the network's name we're going to have placeholder variables that tell us the inputs to our model we're going to want to input the stack of images from the atari game we want to input the actions that the agent took as well as the target value for the q network we'll get to that in a minute and this convention of naming naming placeholders and layers you're going to see repeated throughout the tensorflow library the reason is that it it makes debugging easier if you get an error it will tell you the variable or layer that caused the error very handy and so you can probably tell by the shape here that we are going to do a one hot encoding of the actions and the same thing for the q target so the convention of using none as the first parameter in the shape allows you to train a batch of stuff and that's important because in virtually every deep learning application you want to pass in a batch of information right in this case we're going to be passing in batches of stacked frames so we'll get to that in a moment next thing we have to do is start to build our scroll down a little bit and start building our convolutional neural network so let's start building our layers the first one will have 32 filters kernel size of 8x8 strides of 4 and a name of conf 1. the other thing we need is an initializer now we are going to use the initializer that the deepmind team used in their paper reason is that we want to learn from the experts and may as well do what they do if it's going to make our life significantly easier and that's going to be a variance scaling initializer the scale of 2. and then we want to activate that with a relu function that's right it's con1 activated so our next layer is pretty similar it'll take the activated output of the first layer as input that'll take 64 filters if you're not familiar with what a filter is you can check out my video on convolutional neural networks a kernel size of in this case four by four strides of two name of conf two and the we can go ahead and copy that initializer why not so that is our second convolutional layer and we're gonna do something similar for the third of course and that will take conf2 activated 128 filters two by sorry a three by three kernel good grief a stride of one and a name of conf 3 and the same initializer and of course we want to activate it as well so the next step is once we have the outputs of our convolutional net neural network we want to flatten all of them and pass them through a dense network to get our q values or the values of each state action pair let's do that now that's where our fc1 dimms come in and we need a value activation and oops we will do the same initializer for the dense layer so next up we need to determine the q values q and q learning just refers to the value of a state action pair it's just the nomenclature and this will be the output of our neural network and of course we want to have one output for each action and this gets the same initializer now we're not activating that yet uh we want to just get the linear values sorry the linear activation of the output of our network so the next thing we need is the actual value of q for each action and remember actions is a placeholder and next thing we need for every neural network is a loss function so we just want to have the squared difference between the q value of the network outputs and something called the q target the q target let's get to that now so the the way q learning works is that at each time step it's a form of temporal difference learning so every time step it learns and it says hey i took some action what was the maximal action i could have taken and then it takes the delta between whatever action it took and the maximal action and uses that to update the the neural network as its loss function so our training operation is just a form of gradient descent uh atom optimizer in this case uh learning rate and you want to minimize that loss function let's give this more room so that is almost it so that is our network so the next thing we need is a way of saving files right and save and loading them as well the reason we want this is as we said these models take a notoriously long time to train and so we may want to start and stop as we go along and what this will do is it will look in the checkpoint file and load up the graph from that file and save it and load it into the graph of the current session and we're going to save frequently as we train something like every 10 games and all this function does is it takes the current session and opposite to a file pretty handy so that is our deep q network what this does again is it takes a batch of images from the environment in this case breakout passes it through convolutional neural network to do the feature selection that passes it through a fully connected layer to determine the value of each given action and then uses the the maximum value of the next action to determine its loss function and perform training on that network network via back propagation next up we need an agent that includes everything else all of the learnings all the memories all that good stuff so it's going to take something called alpha that is the learning rate gamma that's a discount factor a hyper parameter of our model the memory size number of actions and epsilon that determines how often it takes a random action a batch size a parameter that tells us how often we want to replace our target network set of input dimms we use the same as before 210 160 by four one moment my cat is whining we need the directory to save the q next network and we will need a directory to save the q evaluation and what this as i said we'll have two networks one that tells us the action to take the one that tells us the value of that action so let's go ahead and start our initializer so when we take random actions we will need to know the action space which is just the set of all possible actions and we need to know the number of actions we need our discount factor gamma this tells the agent how much it wants to discount future rewards the memory size which tells us how many transitions to store in memory of course our epsilon and epsilon greedy and then we need our network to tell the agent the value of the next action so we'll pass in the alpha learning rate number of actions input dimms the name and the checkpoint directory okay so now we have our two networks the next thing we need is a memory so q learning works by saving the state action reward and new state transitions in its memory we're also going to save the terminal flags that tell the agent whether or not the game is done that'll go into the calculation of our reward when we do the learning function so we need a state memory just a numpy array of zeros we shape mem size and input dimms and so this will save a set of four transitions four frames stacked four frames by number of memories and we also need an action memory and this will handle the one this will store the one hot encoding of our actions now that is just one dimensional this will just store the agent's memory of the rewards and then we need the terminal memory so this just saves the memory of the done flex and to save ram we'll save that one as int8 and you know what we can do the same thing with the actions and this is important because we're going to be saving 25 000 or so transitions on my pc this consumes about 47 gigabytes 48 gigabytes of ram i have 96 so it fits uh if you have less you're gonna need a significantly smaller memory size just something to keep in mind so next thing we need to do is to store those transitions in memory and this is of course pretty stateful straightforward so we need the old state the action the reward the new state let's just call that state underscore and a terminal flag so that'll just be an integer zero or one so the agent has some fixed memory signs we want to fill up to that memory and then when we exceed it we just want to go back to the beginning and start overriding it so the index is just going to be mem counter which is the something i forgot let's put that up here so that will be the counter that keeps track of the number of memories that it has stored so for our actions we need to do the one hot encoding and when we pass in the action it'll just be an integer so making an array of zeros and setting the index of the action you took to one is a one hot encoding and of course you want to increment the memory counter so the next thing we need is a way of choosing actions so deep q learning relies on what is called epsilon greedy so epsilon is a parameter that tells it how often to choose a random action we're going to dk epsilon over time the agent will start out acting purely randomly for many many hundreds of games and eventually the random factor will start decreasing over time and the agent will take more and more greedy actions the greedy action is choosing the action that has the highest value of the next state so this takes the state as input we need a random number from the numpy random number generator and then we'll select an action at random from the agent's action space if we are going to take a greedy action then we need to actually find out what our next highest lead highest valued action is so we need to use our evaluation network to run the q eval dot q values tensor using a feed dict of the sorry the i can't talk and type at the same time of the current state as the q evaluation network input and then of course if you want the maximum action you just need numpy.arcmax of actions and when you're done just return the action so now we come to the meat of the problem we have to handle the learning so learning has many parts to it the basic idea is first thing we're going to do is check to see if we want to update the value of our target network and if it's time to do that we're going to go ahead and do that the next thing we're going to do is select a batch of random memories the most important thing here is that these memories are non-sequential if you choose sequential memories then the agent will get trapped in some little nook and cranny a parameter space and what you'll get is oscillations and performance over time to actually have robust learning you want to select different transitions over the entirety of the memory so that's how you handle memory batching and sampling and then you have to calculate the value of the current action as well as the next maximum action and then you plug that into the bellman equation for the q learning algorithm and run your update function on your loss so let's go ahead and do that so first thing we want to do is see if it's time to replace our network target network if it is go ahead and do that and we'll write the update graph function momentarily next thing we want to do is find out where our memory ends less than mem size else this will allow us to randomly sample a subset of the memory and this will give us a random choice in the range maximum of size batch size so next we need our state batches these are just sorry these are just the state transitions we will need the actions we took and remember we store these as a one-hot encoding so we need to go back to a we need to go back to a integer encoding so we need to handle that and the simplest way to do that is just to do a numpy dot operation to just multiply two vectors together so next we need to calculate the values of the current set of states as well as these set of next states sorry sorry with qe valve and the next so this will take the set of next states the transit the transitions the next thing we want to do is copy the qeval network because we want the loss for all of the non-optimal actions to be zero next thing we need to do is calculate the value of q target so for all of these states in the batch for the actions we actually took uh plus this quantity here so the maximum value of the next state multiplied by this quantity terminal batch so the reason is that if we if the next state is the end of the episode you just want to have the reward whereas if it is not a terminal state the next state then you want to actually take into account the discounted future rewards so next we need to feed all of this through our neural network through our training operation we need the actions which is the action we actually took and we also need the target values which we just calculated so the next thing we need to do is to handle the prospect of decreasing epsilon over time remember epsilon is the random factor that tells the agent how often to take a random action the goal of learning is to eventually take the best possible actions so you want to decrease that epsilon over time so we handle that by allowing the agent to play some number of moves randomly so we'll say 100 000 moves randomly and we want to dictate some minimum value because you never wanted to do purely greedy actions because you never know if your estimates are off so you always want to be exploring to make sure estimates are not off and you can decrease epsilon over time any number of ways you can do it linearly that's what deepmind did you can use square roots you can use any number of things i'm just going to do this we're going to multiply it by some fraction of one a bunch of nines that'll give you a really slow decrease of epsilon over time so the agent takes a lot of random actions and does a lot of exploration sorry i flipped my sign there i thought that didn't look right so yeah if it tries to drop below 0.01 we're going to go ahead and set it there okay so that is the learning function next up we have to handle the functions to save the models and this will just call the save checkpoint function for the respective networks next function we need is a way of updating our graph so what we want to do is we want to copy the evaluation network to the target network and this is actually a little bit tricky so what you want are the target parameters this is why we saved them earlier and you want to perform a copy operation on them now the reason this is non-trivial is because you have to pass in a session and the decision of which session to use is non-trivial so you have to use the session for the values that you're trying to copy from not copy 2. so if you had q next you would get an error which took me a little bit to figure out so that is our agent class next up we have to code a a main function so of course we have to start again with our imports i'm going to import jim and we want to import a network we will also need numpy to handle the reshaping of the observation we're going to truncate it to make the workload on the neural the gpu a little bit lower so import numpy as np if you want to save the the uh games you can actually use that with uh you can do that with the wrappers so i won't put that in here but i will put that in my github version so you can just do a git pull on this and you will have the way of saving the games so first thing we have to do is pre-process our observations and the reason you want to do this is because you don't need all of the image we don't need the score and we also don't need color we just need one channel so i've already figured it out if you take row 30 onward and all the columns then you will get a good image and you want to reshape it like so the next thing you have to handle is a way of stacking the frames this is because the agent can't get a sense of motion by looking at only one picture right nobody can get a sense of motion from looking at one picture worse yet the openai atari library returns a sequence of frames where it could be a random number between two three or four so to get a sense of motion we have to actually stack a set of frames and we're going to handle that with this function so we'll just keep a running stack of frames the current frame to save and the buffer size which just tells you how many frames to save so at the top of the episode you're not going to have anything to save right there will be no stacked frames so you want to initialize it so it'll be the buffer size by the shape of each individual frame next you want to iterate over that and say each row which corresponds to each image in your stack gets assigned to a frame so otherwise it's not the beginning of the episode and you want to pop off the bottom observation shift the set of frames down and append the new observation to the end so instead of one two three four it'll be two three four and then frame five so let's do that equals sorry zero two buffer size minus one so this will shift everything down and this will append the current frame to the end of the stack next we have to do a reshape and this is basically to make everything play nicely with the neural network all right now we're ready for our main function let's go ahead and save scroll down good grief breakout v0 is the name of the environment this is just a flag to determine if we want to load a checkpoint sorry so yeah epsilon starts out at 1.0 so the agent takes purely random actions our learning rate alpha will be something small like zero zero zero two five and we've reshaped our input so it needs to be 180 instead of 210 180 by 160 by four because we're going to stack four frames the breakout library sorry the breakout game has three actions and a memory size of 25 000 which as i said takes about 48 gigabytes of ram so go ahead and scale that based on however much you have if you have 16 gigs go ahead and reduce it by down to something like six or seven thousand so the batch size tells us how many batches of memories to include for our training we'll use 32. if low checkpoint is true then we want to load the models next thing we need is a way of keeping track of the scores we will need a parameter for the number of games stick with 200 to start with a stack size of four and an initial score of zero so the memory is originally initialized with a bunch of zeros that is perfectly acceptable but another option something else we can do is we can overwrite those zeros with actual gameplay sampled from the environment so why don't we do that so and the actions are just chosen randomly right it's just to give the agent some idea of what is going on in the environment so you want to reset at the top of every episode you want to pre-process that observation you want to go ahead and stack the frames and then player episode so there's a bit of a quirk here the the agent saves its actions as zero one or two but the actions in the environment are actually one two and three so we have to sample from that interval and then add one take the action subtract one and then save the the transition in the memory just a bit of a kluge not a big problem so then we want to add that to our stack go ahead and subtract off one from the action and store that transition in memory and then finally set the old observation to be the new one let's go ahead and use a string print statement okay now that we've loaded up our agent with random memories we can actually go ahead and play the game one thing i like to do is print out the running average of the last 10 games so that we get an idea of if the agent is learning over not over time or not you do it like this and then just print that out and i also like to know if epsilon is still one or if it has actually started to decrease over time and we also want to save the models every 10 games and if on any other game we just want to print out the episode number and the score so we can actually scroll up here copy this so we're not done whoops there we go so instead of a random choice it is agent dot choose action and that takes in the observation oh but we did forget to do the same thing here grab those and put them there so the top of every episode we reset the environment pre-process the observation and stack the frames quite critical so we still have to do the same thing with adding and subtracting one we want to save the transitions and the only other difference is that we want to learn at every step at the end of the episode we want to go ahead and append our score so that way we can keep track of our average and if you want to get fancy you can go ahead and add in a plotting function so that when this is done learning you can plot the learning over time and you should see an upward slope over time and if you want to plot the epsilons you should see a gradual downward slope as well so i'm gonna leave it here because the model is still training on my computer it's run about three thousand iterations three thousand games that is and it at best it gets two to three points per set of five lives so it's really going to need a couple days of training to get up to anything resembling competitive gameplay but once it's done i'll upload another video that explains how q learning works in depth and in detail and i'll include the performance from this particular model in that video so you can check it out then feel free to run this yourself when i finish the model i will go ahead and upload the trained version to my github so you are free to download it if you don't have any hard any decent gpus to train this with go ahead leave a comment down below subscribe i will see you all in the next video welcome back everybody in this series of videos we're going to code up a deep q network in pytorch to play space invaders from the atari open ai gym library in this first video we're going to code the convolutional neural network class in the second video we'll code at the aging class itself and in the third we'll get to coding the main loop and seeing how it all performs let's get to it so if you're not familiar with the deep q network i would advise you to check out my earlier video bite size machine learning what is a deep q network it's a quick little explainer video that gives you the gist of it within about four and a half minutes uh if you already know then great we're ready to rock and roll but if you don't i'll give you the brief too long didn't read so basic idea is that we want to reduce some rather large state space into something more manageable so we're going to use a convolutional neural network to reduce the representation of our estate space into something more manageable and that'll be fed into a fully connected neural network to compute the q values in other words the action values for any particular given state we're going to leverage two different networks a network that is going to tell us the value of the current state as well as a network to tell us the value of the successor states this is going to be used to calculate the values of the target and which is the purely greedy action as well as the behavioral network which is the current predicted state and the difference between those two is used in the loss function for our stochastic gradient descent or root mean squared propagator so let's go ahead and get started um we're going to start as usual by doing our imports and there are quite a few in pi torch great library one thing i really like about it is that it's highly expressive you don't have a whole lot of boilerplate code as you do in something like tensorflow tensorflow is enormously powerful uh and if you wanna do um cross app type of software then that's going to be really your only choice for our purposes this is going to be precise you want to use and of course numpy so we're going to define a class for our deep q network and that'll derive from an end module this is kind of how uh pytorch handles everything you want to derive your class from the module uh the base module uh so that way you get access to all of the goodies and we'll pass in our learning rate alpha for our stochastic gradient descent algorithm all right so the network is comprised of three convolutional layers and two fully connected layers so the first one is just going to be a two-dimensional convolution that's going to take one input channel the reason is that the agent doesn't really care about color so we're going to go ahead and make things easier reduce our computational requirements by going to a grayscale representation we'll take 32 filters with an 8 by 8 kernel a stride of 4 and a padding of 1. second layer is going to be pretty similar this one of course will take 32 channels in give 64 channels out and do a 4x4 kernel with a stride of two and our third convolutional layer is going to be of course two-dimensional as well takes in 64 outputs 128 with a 3x3 kernel uh that's it for the convolutions hey if you don't know how convolutional neural network works i'm going to go ahead and link a video here that will give you the uh the the basic idea of of how those work and if you would rather see how uh how this stuff works in text form i don't know if i mentioned this earlier but there is an associated blog article my website neuronet dot ai yeah i bought that domain i'll link it in the description go ahead and check it out please so our fully connected layer is the following and we're going to have to do a little bit of magic here so after running this stuff a bunch of times uh i know the dimensionality of the images we're going to of the convolutions we're going to get out and what we want to know is we're going to be taking a set of filters uh you know convolved images that have had filters applied to them 128 to be exact and we want to unroll them into a single flattened image right to feed into our neural network so that's going to be 128 channels that are 19 by 8 in size and that's a magic number i got from just by running the code in trial and error and then our output layer is going to take in those 512 units and output 6 y6 that's because we have a total of 6 actions in the game of space invaders you have a total of 6 actions which are the subset of the full 20 available in the atari library basically the agent can do nothing it can move left it can move right it can shoot while standing still and it can move left and right and shoot when we get to the main video i'll go ahead and show all those actions we also need an optimizer equals optim rms prop and we want to tell it to take the parameters of our object for the weights and our learning rate is going to be alpha that we've passed in our loss function is going to be a mean square error loss and the components of that will be the target and the current predicted q functions and of course the target is just the greedy value right because q learning is an off policy method that uses a epsilon greedy behavioral policy to update the purely greedy target policy another thing we have to do in pi torch is tell it which device we're using so t.device and that'll be cuda zero if t dot cuda is available else cpu and what this is telling it is that if the gpu is available go ahead and use it which is of course always preferable otherwise just use the cpu and we also have to tell it to actually send the network to the device um maybe i'm using 0.4 i don't know if in 1.0 that's actually required but as of the time i'm coding this up it's required so uh something we have to live with okay so this is the sum and the whole of our network only thing where that remains to do is to feed forward our observation and that will take the opposite no not observation observation not only can i not type i cannot speak as well i suck at life i don't know why you guys listen to me so what we want to do is the observation vector uh is the we're going to use a sequence of frames and those frames are the reduced images from the screen so when we get to the third video on um [Music] on actually playing the game you'll see that you don't need the full frame to actually figure out what's going on you can actually truncate it to get a really good idea in particular the agent can only move left and right a certain amount so we go ahead and truncate the sides uh you don't need the score at the top because we're keeping track of the score ourselves you don't need some of the bottom so you can actually truncate the image a little bit to reduce your memory requirements and we're going to convert it into a grayscale so we get rid of two we're just going to average the three channels to make them into one and we also have to pass in a sequence of frames right because if i only show you one frame of video game you can't tell what's going on you don't get a sense of motion from a single frame right you need at least two to get a sense of motion uh we'll be using three i believe in the original implementation of this algorithm for um for deepmind they used four we're going to go ahead and use three just to be different um i haven't i suspect that's a hyperparameter it's not something i've played with i encourage you to do that oh another thing is that we must train this on a gpu if you try to do it on your cpu it's going to take 7 000 years so uh if you do not have access to a gpu go ahead and leave a comment below and i will find a way to get my pre-trained model to you so you can go ahead and play around with this i have a 1080 ti and not not top of line anymore but it's still quite good for this particular apps application so back to the topic we have to convert our sequence of frames our obser observation to a tensor and we also want to send that to the device uh this is a peculiarity of pi torch as far as i'm aware i'm not the world's leading expert but as far as i understand it you have to tell it to send the network as well as the variables to the device as well not a big deal just something to be aware of next thing we have to do is resize it so when you are given a sequence of frames in the open ai gym and really any other format of image is going to be height and width by channels whereas if you look up here this actually expects the channels to come first and so we have to reshape the array to to accommodate that so pytorch's built-in function for that is view we want a minus one to handle any number of stacked frames one channel in the beginning and we're going to pass in 185 by 195 image [Music] that doesn't seem right actually sorry it's not 195 i'm like the original image is 210 by 160 it can't be 180 595 total brain fart there it's 185 by 95 okay so we have taken in our sequence of frames we've converted it into a tensor and flat and converted it into the proper proper shape for our network the next thing we want to do is activate it and feed it forward so we call the first convolutional layer on our observation and we use the value function to activate it and we store that in the new variable observation and then we learn how to type and then we do the same thing with that output pass it through the second convolutional layer and then we do the same thing again we pass it to the third convolutional layer um and we're almost home free so the next thing we have to do is we are outputting a 128 by 19 by eight oh set of arrays the next thing we have to do is oh by the way that noise is my pomodoro timer if you're not using the pomodoro technique i highly recommend it it's an enormous productivity hack but anyway next thing we have to do is take our sequence of convolved images and flatten them to feed into our fully connected neural network so we again use the view function uh to do that not minus one for whatever number of frames we pass in 19 by eight is what we get out and i found that out through experimentation and we know it's 128 channels because we dictate that here right here 128 output channels so boom we've flattened it and the only thing that remains is to feed it forward and we'll use a value activation function there fc1 fully connected layer one and then it's not observation but it's actions self dot fc2 observation so we'll feed it through the final fully convolved layer and store that as a variable called actions and go ahead and return it and the reason we're doing that is because what we're getting out is a q value for each of our actions and we want to pass that back now keep in mind that we're passing in a sequence of frames and so we're going to get back is a matrix it's not going to be a single array of six values it's going to be six values times whatever number of rows of images you pass in so if we pass in three images it's going to have three rows and six columns and that'll be important later when we actually get to choosing the actions speaking of which i'm going to cut it short here we've already i've already rambled for about 12-13 minutes uh in part two we're going to take a look at coding of the agent class i have structured it this way because the agent actually has two networks so it made sense to kind of stick the network in its own class we'll get to coding up the agent's init function how to handle its memory how to store transitions how to choose actions and how to actually implement the learning function that's a much longer project so we'll stick that in its own video and then in part three we're going to get to actually coding up the main loop and seeing how it performs hey if you liked the video make sure to like the video hey if you don't like it go ahead the thumbs down i don't really care let me know what you think questions comments leave them down below if you made it this far please consider subscribing i look forward to seeing all of you in the next video welcome back everybody in the previous video we got to coding the convolutional neural network class for our deep q learning agent that's going to play space invaders if you haven't seen that yet go ahead and click the link to go ahead and watch that first otherwise you probably won't know what's going on if you're if you're the type of person that would prefer to have a written set of instructions go ahead and click the link down below i'll link to the associated blog article for this particular tutorial series when we last left off we just finished returning the set of actions which is the set of q values for our sequence of frames so of course in this video we're going to go ahead and get started coding up the agent class which is where all the magic is going to happen uh oh and of course as always i have left the code for this in my github under the youtube directory it gets its own directory because there's a few different files here i'll link that below as well and if you aren't following me on github you probably should because that's where i post all of my stuff okay next up we have the agent class right and this is just going to derive from the base object class nothing fancy here we need a basic init function and this is going to take gamma which is our discount factor so the agent has a choice of how to value future rewards in general gets discounted by some value because a reward now is worth more than a reward in the future just like with us we need epsilon for epsilon greedy action selection the alpha for the learning rate the max memory size a variable to keep track of how low we want epsilon to go something to keep track of how long we replace of how often we're going to replace our target network i'll get to that in a moment for in a few minutes and the action space and that's just a list of variables from zero through five those correspond to all the possible actions for our agent and you just set these to the appropriate variables uh being careful not to turn on your caps lock key so what these all are are just hyper parameters for our agent we don't need to store alpha because we're just going to pass it into the network and then never touch it again storing the action space allows us to accommodate the epsilon greedy action selection later the mems size is used for efficiency purposes so we're going to keep track of state action reward transitions you don't want to store an infinite number of them you only want to store a subset you don't need to store all of them anyway there's no real practical benefit since we're just sampling a subset anyway so we just use some rather large memory um to keep track of all of the state transitions that we care about keep track of how many steps and the learn step counter that is to keep track of how many times the agent has called the learn function that is used for target network replacement if you're not familiar with it target network replacement is when you swap the parameters from the evaluation network to the target network my experience has been that it doesn't actually help things so i'm not going to do it i'm going to code it in because it's an important part of the topic but in this particular case i haven't found it to be helpful but i haven't played with it too much i saw that it does quite well without it so why break it so i'm going to store the memory as a list and the reason i'll use a list instead of a numpy array is because the associated cost of stacking numpy rays is really really high so it's much much faster to store a list of lists and then convert to a numpy array when you learn and that's much faster than keeping track of a set of numpy arrays and just stacking them the stack operation is incredibly computationally prohibitive so for something like this that's already computationally expensive doesn't make any sense [Music] and keep track of the total number of memory stored so that way you don't overwrite the array we want to keep track of how often we want to replace the target network and then we need our two networks qe val and that is just passing the alpha that is just the agent's estimate of the current set of states and q next is the agent's estimate of the successor set of states so recall in deep q learning we calculate the value the max value of the successor state as our greedy action that's our our actual target policy and our behavior policy that we used to generate data is epsilon greedy that's it for our constructor the next thing we have to worry about is storing memory transitions so transition so we are interested in the current state the action taken the reward received and the resulting state because those are the things that that allow the agent to learn so we have to make sure that we aren't over our memory so if the mem counters less than self.mem size then just go ahead and append that as a list and again we're doing this because it is much cheaper computationally to append a list than it is to actually stack a numpy array if we have filled up our memory then we want to uh overwrite the position in memory that is uh determined by the modulus dot mem size so this will guarantee we are bounded by zero all the way up to our mem size and of course this is a list of lists it's just an action reward state underscore and we want to increment the memory counter pretty simple huh pretty straightforward next up we have the function to choose an action and this will take the observation and again just to remind you as we discussed in the first video we're passing in a sequence of observations because we want to capture some information about the temporal dependence of what's going on again with one frame you can't tell if the aliens are moving left or right and so you don't know if you should move left or right um of course you know which way your bullets go you know which way there is go but as far as movement is concerned you need at least one frame so as always we're going to be using numpy to calculate a random number for us to our epsilon greedy action selection and you want to get the value of all of the actions for the current set of states itself q eval dot forward so what we're doing now is forward propagating that stack of frames through the neural network the convolutional neural network and the fully connected layer to get the value of each of each of the actions given that you're in some set of states denoted by the observation so if rain is less than one minus epsilon then you want to take the arg max write the maximum action and recall that we have stored the actions as a matrix they're returned as a matrix because you have the number of rows that correspond to the number of frames you pass in and each of the columns correspond to each of the six actions so you want to take the first first axis and if you're taking a random action then you just choose something at random from the action space list and go ahead and increment your steps and return the action that you've chosen the way i the reason i use one minus epsilon is um [Music] you can use the probability epsilon you can use probability one minus epsilon this is really more of a soft uh soft epsilon kind of strategy rather than purely greedy but it doesn't really matter this is going to give you the probability of choosing the maximum action of epsilon plus epsilon over six because they're of course the greedy action is the subset of all actions so there's a one over six probability that when you take the quote-unquote non-greedy action you'll actually end up getting the greedy action all right next thing we have to worry about is how the agent is going to learn and this is really the meat of everything so we are doing batch learning so you want to pass in a batch size and the reason we're doing batch learning is um [Music] a number of different reasons so you want to break correlations uh state transitions you you it's even okay if the the batch overlaps different episodes what you want to get is a good sub sampling of the overall parameter space so that way you don't get trapped in a local minima so you randomly sample these state transitions through your memory otherwise you could end up if you replay the whole memory you could end up getting trapped in some local minimum it's a way to improve the efficiency of the algorithm to converge to a purely optimal strategy excuse me and thursday all right first thing we have to do since we're using batch learning is uh we have to zero out our gradients and what this means is that the gradients can accumulate from step to step the network like pi torch library can keep track of it we don't want that if you do that if you don't do the zero grad then you'll end up with um basically accumulating for every single batch and that's really full learning rather than batch learning next thing we have to check for is if we're going to replace a target network so if it's not none and if it's time to do it release now replace target account equals zero then we want to actually replace our target network what we do there is we take advantage of the pi torch representation of our network in that case it's just we can convert our entire network into a dictionary which is really cool so itself qnext dot load state dict so it's going to load uh a state to the network from a dictionary which network the evaluation network which we're going to convert to a state dictionary we're not actually going to use this in our implementation but i include it here for completeness uh next up uh we want to know uh we want to select a random sub-sample of the memory so we want to make sure we don't go all the way past the end of our array so if our current memory counter plus batch size is less than our total memory well then we're free to go ahead and select any point of our memory because we know we're not going to go beyond it range otherwise if there is an overlap then we want memstar to just be an int in the range [Music] good grief i hate that minus one just to be safe uh okay so that is how we choose where to start just a random number somewhere between zero and the max memory if we have enough leftover in the memory for the bat to accommodate the batch otherwise subtract that off and select something from that subset then we're going to go ahead and get that mini batch and convert that to a numpy array so i suspect this is not the most efficient way of doing this and the reason is that you run into some difficulties in the way in which you pass things into the torch library it has a certain set of expectations that are kind of finicky um not to say it's bad it's just something that i wasn't uh expecting but it works nonetheless so what we want to do next is feed forward both of our networks we want to know what is the value of our current state and what is the value of the successor state after we take the action whatever action we're looking at in our batch so that's just q eval forward what are we feeding forward here's where we got some hackiness we got to convert it into a list and the reason is that our memory is a numpy array of numpy objects because the observation vectors are numpy objects so if you don't convert it into a list then you have a numpy array of nd array objects and tensor pi torch will complain we don't want tensor we don't want pi torch to complain so we want to access all all rows right our entire batch and the state is just the zeroth element and you want all of the variable you want all of the pixels so you need the second set of columns there and we want to send this to the device self dot q eval dot device and this ensures that the this network this set of variables gets sent to our gpu as well the next thing we need is the value of the successor states and that is just all the rows third column and all of the um all of the members of that array [Music] and here i've just uh i gotta quit using the visual studio code this is annoying but um scroll up here so all i have done here is um i'm putting it on qeval.device because the device for both the evaluation and the uh next network are the same so i only have one gpu if i had two gpus then this would matter it doesn't matter so you can just call it that next thing we want to know is what is the max action for our current for our next state right because the update rule actually calculates takes into account the purely greedy action for the successor state uh maybe if i can find an image of it i'll flash it here on the screen to make life easy but next thing we have to know is the max action and we use the arg max function for that and remember we want to take the first dimension because we're the actions q next q predicted and q next are actually our actions that's what we get from the feed forward and that is batch size times number of actions and we want the number of actions so that's first dimension and i am a little bit in or attentive here about sending it to the device just to make sure nothing gets off the device because this stuff slows to a crawl if you run on the cpu we need to get our rewards and that is uh obtained from our memory all the rows and the second element too many parentheses and one thing we want is our loss function to be zero for every action except for that max action so we have q target equal q predicted but we want q target for all of our our entire match but the max action to be rewards plus self dot gamma times the actual value of that action so t.max just gives you the value of the maximum element and argmax gives you the index and you want to find the maximum action the value of it so those are our target and predicted values that's what we use to update our loss function the next thing we have to handle is the epsilon decrement so we want the agent to gradually converge on a purely greedy strategy for its behavior policy and the way you do that is by gradually decreasing epsilon over time i don't like to let it simply go to um start decreasing right away so i have some set number of steps i let it run first and i use a linear decrease over time you can use exponential quadratic you can use whatever form you want it's not it's my knowledge it's not super critical but i could be completely wrong this seems to work as we'll see in the third video so if we don't have enough left then just set it to epsilon end scroll up here and we're almost done so we have everything we need we have everything we need to compute our loss which is this q target and q predicted those are the values of q predicted is the value of the current set of states and q target is related to q next right it's the q target is the max action for the next successor state and so we're almost there so the loss it's just the mean squared error loss if you recall from the first video where we defined the loss function and as is the torch style you have to send it to the device and then we want to back propagate with loss backward and we just want to step perform one iteration and go ahead and increment our learn step counter and that's basically it so there was a lot of code there let's go back and take a look really quick so first thing you want to do is zero your gradients so that way we're doing actual batch optimization instead of full optimization then we want to check to see if we're gonna if it's if we are going to replace the target network and if it is time and if it is load the state dictionary from the q eval on to the q next network next up calculate the start of the bat of the uh memory sub sampling i'm making sure to get some subset of the array go ahead and sample that batch of memory and convert it to a numpy array oh pomodoro timer so if you guys aren't using the pomodoro method to work i highly recommend it go look that up if you don't know what it is but anyway convert that to a numpy array and then go ahead and feed forward the the current state and the successor state using the memory sub sample um making sure it is sent to your device next thing we have to know is the maximum action for the successor state and calculate the rewards that the agent was given set the q target to q predicted because you want the loss for every state except the loss for every action except the max action to be zero and then update the value of q target for the max action to be equal to rewards plus gamma times the actual value of that max action next up make sure that you're using some way of decrementing epsilon over time such that it converges to some small value that makes the agent settle on an mostly greedy strategy in this clay in this case i'm using five percent of the time for a random action finally go ahead and calculate the loss function back propagated step your optimizer and increment your step counter and that is all she wrote for the learn function and the aging class slightly more code than in the network class but still fairly we have a typo there still fairly straightforward i hope this has been informative and in part three we're going to go ahead and code up the main loop and see how all this performs i look forward to seeing you in the next video any comments questions suggestions go ahead and leave them below if you made it this far please consider subscribing i look forward to seeing you all in the next video and welcome back everybody to part three of coding a deep q learning agent in the open ai gym atari library uh in parts one and two we took a look at the deep neural network class as well as the aging class for our agent and in part three we're going to finally put it all together into the main loop to play the game and see how our agent does let's get started so we begin as usual with our typical imports we're going to need the gym of course and we're going to import our our model class so from model we'll import deep sorry dq model and agent and i also have a utility function i'm not going to go over the code it's just a trivial function to post the uh to print to plot the decaying epsilon and the running average of previous five scores from utils import plot learning and uh oh and by the way so if you haven't seen parts one and two go ahead check those out and if you want the code for this please check out my github if you would like to see a blog article that details all this in text if you missed something in the speech then go ahead and click the link down below so it's giving me some issue uh oh it's not deep cue model this is the the downside of talking and typing at the same time i'm not that talented so uh we want to go ahead and make our environment and that space invaders v0 uh another thing to know is that there are implementations of the environment where instead of being passed back an image of the screen you're passed back like a ram image something like that i've never used it sounds kind of interesting it might be something for you to check out and leave a comment down below if you've played with have any experience with it or if you think it sounds cool so we want to make our agent and i'm going to call it brain big brain pinky in the brain baby gamma i have 0.95 an epsilon of 1.0 and i'm using epsilon 1.0 because it starts out taking purely random actions and converges on a mostly greedy strategy learning rate of 0.03 max memory size 5000 transitions and we're not going to do any replacement so you may have noticed uh when we were building our agent that the memory was instantiated as an empty list if you're going to use numpy arrays one thing you would do is just create an array of zeros and the shape of you know your images as well as the total number of memories i'm going to do something slightly different so one way to help agents learn is to actually have them watch videos of humans playing and in fact the uh deepmind team taught alpha alpha zero go to play by showing a board configurations and saying which which player won so you it's perfectly legitimate to leverage the experience of humans i'm not going to play the game for the agent but what i'm going to do is allow the agent to play the game at totally random he's just going to play a set number of games to fill up its memory uh using totally random actions so it's a bit of a hack but i kind of i don't know to me it seems legitimate but some people may have frowned upon it i don't really care it's how i chose to solve the problem and it seems to work fairly well so brain dot mem size we have to reset your environment reset your done flag and play an episode so here i'll let you know the action so zero is no action one is fire two is move right three is move left four is move right fire five is move left fire so that's zero through five total of six actions choose one at random env.actionspace.sample if you want to verify that these do that go ahead and code up a simple loop you know while loop while not done take action zero and render it and see what it does so next you want to go ahead and take that action and the other thing i do is the um and i'm on the fence about doing this i haven't tested it but in my experience with other environments in more basic algorithms that my experience is that it makes sense to penalize the agent for losing so uh you don't want the agent will naturally try to maximize its score but you want it to know that losing is really bad so if you're done and the and this may be something i change on the github so if you go to the github and see this isn't there it means that i tested it and decided it was stupid and but as of right now i think it's okay i'm always open to change my mind though so i want to let it know that losing really really sucks and i want to store that transition and uh here's a bit of a magical part so as i said in the in the first video in the convolutional neural network we want to reshape it down from three channels into one because the the asian doesn't really care about color it only cares about is an enemy there or not right and it can get that information from black and white so i'm going to take the mean over the three channels to get down to a single channel and i'm also going to go ahead and truncate it and the reason is that there isn't a whole lot of information around the borders of the screen that the agent needs so we can get away with reducing our memory requirements without losing anything meaningful and i'm going to go ahead and flash in some images here of what that looks like but what i'm going to do is take the ops observation vector and i'm going to take 15 to 230 to 125 and the mean is performed over access to and we also want to store our action and reward uh you guys can't see that there so we store the action and reward as well as let's go ahead and copy this we also want to copy we also want to store the successor state oh good grief life is so hard there we go and that's observation underscore which is which is the successor state and then set your observation to observation underscore and then when you're done just let yourself know okay okay and we are almost there so next thing you want to do is keep track of the scores you want to know how well the agent is doing um i have this variable epsilon history oh uh keep track of the history of epsilons as it decreases over time because we want to know the relationship between the score and the epsilon and we'll run it for 50 games and you'll take a batch size of 32 memories the batch size is it an important hyper parameter but what you find is that using a larger batch size may get you a little bit better performance it slows down training tremendously so on my system with an i7 7820x 32 gigs of ram 1080 ti batch size of 32 means that 50 games is gonna run in about half an hour and it takes quite a bit of time using a larger batch size doesn't seem to produce a whole lot better performance but it certainly slows it down by more than a factor of two so there's non-linear scaling there and we want to know that we're starting game i plus one with an epsilon of something dot uh say four significant figures right not epsilon and we want to go ahead and append the agents epsilon at the beginning of the episode reset our done flag and reset our environment and okay so the next thing we want to do is as i said why is this unhappy invalid syntax oh no i've offended it what have i done oh forgot a comma there we go so next thing we want to do is construct our sequence of frames as i said we're going to pass in some sequence of frames to allow it to get some conception of movement in the system so i have a rather ugly way of doing this as usual but the first thing i want to pass into it is the first the first observation vector from the beginning of the game and i have broken something again what have i broken frames done by some oh of course of course okay so the score for this episode is zero um i want to keep track of the last action so this is something i'm not sure about i must confess to you guys the documentation on the open ai gym is rather lackluster what it says is that each action will be repeated for k frames where k is the set two three or four uh so i guess it gets repeated some random number of times so since i don't know how many times and i want to keep passing in a consistent set of observation vectors of frames i will do something hacky so i'll keep track of the last action and i will only update my action every third action so i want to pass in a sequence of three frames and repeat the action three times i'm kind of forcing the issue again it seems to work i don't think it's the best implementation but this is you know just my quick and dirty implementation so if we have three frames go ahead and choose an action based on those and reset your frame variable to an empty list otherwise go ahead and do what you just did scroll down so then we want to go ahead and take that action keep track of our score [Music] and append our new observation uh i'm just gonna copy that yeah copy that and then um i am going to go ahead and tell it that losing is very bad we don't like losers and this al dot lives thing is the number of lives the agent has ale is just the um emulator in which the opening atar openai jim's atari library is built and next we have to store a transition i'm going to copy that code precisely because i have fat fingers and apparently screw things up so copy that and then [Music] underscore brain.learn batch size keep track of our action and here you can put in a render if you want to see what it's doing um if not then at the end of the episode end of the episode you want to append a score which we're going to plot later and i like to print the score so i can kind of get an idea of how the agent's doing and we need to make a list of the x variable for our plotting function again for the plotting function just go ahead and check out my github for that that's the easiest way and i'm going to set a file name [Music] i'm just gonna call it test for now plus string um num game something like that uh plus dot png so we have a file name then we're going to plot that we want to plot the scores the epsilon history and the file and pass in the file name so that it saves it and that's all she wrote for the for the main loop uh i've gone ahead and run that so i'm going to go ahead and flash in the results here so as you can see the epsilon decreases somewhat linearly over time not somewhat completely linearly and as it does so the agent's performance gradually increases over time and keep in mind here i am plotting the previous uh the average of the previous five games the reason i do that is to account for significant variations in game to game play right so the agent is always going to choose some proportion of random actions and that means it can randomly choose to move left or right into the enemies bullets so there's always some games that's going to get cut short so the the general trend in the performance is up until the very end when it actually takes a bit of a dive and i've seen this over many many different iterations i suspect this has to do with the way that it is navigating through parameter space it'll find pretty good pockets and then kind of shift into a related other local minima which isn't quite as good if you let it run long enough this will eventually go back up but it does have some oscillatory behavior to it but you can see that it increases its score quite dramatically and uh in this particular set of runs i saw scores in excess of 700 points which is actually pretty good for an agent um so let's go ahead and take a look at what it looks like with the target network replacement so here you can see a dramatically different behavior so in this case uh epsilon decreases and the score actually decreases over time and uh you know actually i don't quite know why it does this so the the oscillations down there are almost certainly from the target network replacements uh it could be a fluke but i have run this several times where i see this type of behavior where uh with the target network replacement it totally takes a nosedive i don't think i screwed up my implementation please leave a comment below if you saw something it looks off but as far as i can tell it looks it's implemented correctly you just copy one state dick to another no real big mystery there uh but that's why i choose to leave it off you get a significant variation in performance um more of the stories to go ahead and leave the target network replacement off and uh that's it for this series so we have made an agent to play the atari uh atari game of space invaders uh you by uh gradually decreasing epsilon over time we get really good performance uh several hundred points in fact actually learns how to play the game quite well i'm probably going to go ahead and spin in a video of it playing here so you can see how it looks um if this has been helpful to you please consider subscribing go ahead and leave a comment below if you have one a question suggestion anything uh go ahead i answer and read all my comments um and uh go ahead and smash that like button guys so i hope to see you all in the next video and uh take care in this video i'm going to tell you everything you need to know to start solving reinforcement learning problems with policy gradient methods i'm going to give you the algorithm and the implementation details up front and then we'll go into how it all works and why you would want to do it let's get to it so here's a basic idea behind policy gradient methods a policy is just a probability distribution the agent uses to pick actions so we use a deep neural network to approximate the agent's policy the network takes observations of the environment as input and outputs actions selected according to a softmax activation function next generate an episode and keep track of the states actions and rewards in the agent's memory at the end of each episode go back through these states actions and rewards and compete and compute the discounted future returns at each time step use those returns as weights and the actions the agent took as labels to perform back propagation and update the weights of your deep neural network and just repeat until you have a kick ass agent simple yeah so now we know the what let's unpack how all this works and why it's something worth doing remember with reinforcement learning we're trying to maximize the agent's performance over time let's say the agent's performance is characterized by some function j and it's a function of the weights theta of the deep neural network so our update rule for theta is that the new theta equals the old theta plus some learning rate times the gradient of that performance metric note that we want to increase performance over time so this is technically gradient ascent instead of gradient descent the gradient of this performance metric is going to be proportional to some overstates for the amount of time we spend in any given state and a sum over actions for the value of the state action pairs and the gradient of the policy where of course the policy is just the probability of taking each action given we're in some state this is really an expectation value and after a little manipulation we arrive at the following expression when you plug that into the update rule for theta you get this other expression there are two important features here this g sub t term is the discounted feature returns we referenced in the opening and this gradient of the policy divided by the policy is a vector that tells us the direction and policy space that maximizes the chance that we repeat the action a sub t when you multiply the two you get a vector that increases the probability of taking actions with high expected future returns this is precisely how the agent learns over time and what makes policy gradient methods so powerful this is called the reinforce algorithm by the way if we think about this long enough some problems start to appear for one it doesn't seem very sample efficient at the top of each episode we reset the agent's memory so it effectively discards all its previous experience aside from the new weights that parameterize its policy it's kind of starting from scratch after every time it learns worse yet if the agent has some big probability of selecting any action in any given state how can we control the variation between the episodes for large state spaces aren't there way too many combinations to consider well that's actually a non-trivial problem with policy gradient methods and part of the reason our agent wasn't so great at space invaders obviously no reinforcement learning method is going to be perfect and we'll get to the solution to both of these problems here in a minute but first let's talk about why we would want to use policy gradients at all given these shortcomings the policy gradient method is a pretty different approach to reinforcement learning many reinforcement learning algorithms like deep q learning for instance rely on estimating the value of a state or state action pair in other words the agent wants to know how valuable each state is so that its epsilon greedy policy can let it select the action that leads to the most valuable states the agent repeats this process over and over occasionally choosing random actions to see if it's missing something the intuition behind epsilon greedy action selection is really straightforward figure out what the best action is and take it sometimes do other stuff to make sure you're not wildly wrong okay that makes sense but this assumes that you can accurately learn the action value function to begin with in many cases the value or action value function is incredibly complex and really difficult to learn on realistic time scales in some cases the optimal policy itself may be much simpler and therefore easier to approximate this means the policy gradient agent can learn to beat certain environments much more quickly than if it relied on an algorithm like deep q learning another thing that makes policy gradient methods attractive is what if the optimal policy is actually deterministic in really simple environments with an obvious deterministic policy like a grid world example keeping a finite epsilon means that you keep on exploring even after you've found the best possible solution obviously this is sub-optimal for more complex environments the optimal policy may very well be deterministic but perhaps it's not so obvious and you can't guess at it beforehand in that case one could argue that deep q learning would be great because you can always decrease the exploration factor epsilon over time and allow the agent to settle on a purely greedy strategy this is certainly true but how can we know how quickly to decrease epsilon the beauty of policy gradients is that even though they are stochastic they can approach a deterministic policy over time actions that are optimal will be selected more frequently and this will create a sort of momentum that drives the agent towards that optimal deterministic policy this really isn't feasible in action value algorithms that rely on epsilon greedy or its variations so what about a shortcomings as we said earlier there are really big variations between episodes since each time the agent visits the state it can choose a different action which leads to radically different future returns the agent also doesn't make very good use of its prior experience since it discards them after each time it learns while they seem like show stoppers they have some pretty straightforward solutions to deal with the variance between episodes we want to scale our rewards by some baseline the simplest baseline to use is the average reward from the episode and we can further normalize the g factor by dividing by the standard deviation of those rewards this helps control the variance in the returns so that we don't end up with wildly different step sizes when we when we perform our update to the weights of the deep neural network dealing with the sample and efficiency is even easier while it's possible to update the weights of the neural net after each episode nothing says this has to be the case we can let the agent play a batch of games so it has a chance to visit his state more than once before we update the weights for our network this introduces an additional hyper parameter which is the batch size for our updates but the trade-off is that we end up with a much faster convergence to a good policy now it may seem obvious but increasing the batch size is what allowed me to go from no learning at all in space invaders with policy gradients to something that actually learns how to improve its gameplay so that's policy gradient learning in a nutshell we're using a deep neural network to approximate the agent's policy and then using gradient ascent to choose actions that result in larger returns it may be sample inefficient and have issues with scaling the returns but we can deal with these problems to make policy gradients competitive with other reinforcement learning algorithms like dq learning if you've made it this far check out the video where i implement policy gradients in tensorflow if you like the video make sure to like the video subscribe comment down below and i'll see you in the next video what's up everybody in this tutorial you're going to learn how to land a spaceship on the moon using policy gradient methods you don't need to know anything about reinforcement learning you don't need to know anything about policy gradient methods you just have to follow along let's get started so before we begin let's take a look at the basic idea of what we want to accomplish policy gradient methods work by approximating the policy of the agent the policy is just the probability distribution that the agent uses to select actions so we're going to use a deep neural network to approximate that probability distribution and we're going to be feeding in the input observations from the environment and getting out a probability distribution as an output the agent learns by replaying its memory of the rewards it received during the episode and calculating the discounted future rewards that followed each particular time step those discounted feature rewards act as weights in the update of our deep neural network so that the agent assigns a higher probability to actions whose feature rewards are higher so we'll start with our imports and we're going to want os to handle file operations numpy to handle numpy type operations and of course tensorflow to develop our agent we're going to stick everything in one class whose initialize function takes the learning rate the discount factor gamma the number of actions for the lunar lander environment that's just for the size of the first hidden layer of the neural network we'll default that to 64. the size of the second hidden layer of the deep neural network will also default that to 64. we also need the input dimms and in this case that is 8 so the observation isn't a pixel image it is just a vector that represents the state of the environment we also want a checkpoint directory and this will be useful for saving our model later so this action space will be what we use to select actions later on and we're going to need a number of other administrative type stuff so for instance the state memory is just what the agent will use to keep track of the states it visited likewise for the action memory we want to keep track of the actions the agent took and the rewards it received along the way we also need the layer one size and the layer two size what else we okay so now we can move on to the administrative stuff with tensorflow so tensorflow handles everything in what are called sessions so we have to define one of those we're gonna need a function to build the network and when we return from the network we're going to want to initialize all of the variables so this build network function is only called once it will load up all of the variables and operations under the tensorflow graph and then we have to initialize those variables with some initial values which will be done at random we also need a way of saving the model because your pc may not be fast enough to run this in a you know short enough amount of time so you can do this in chunks by saving and then reloading it as you have time we also need a file to save the checkpoints in so our next order of business is to actually construct this network so we don't need any inputs for that but we do need a set of placeholders and the placeholders serve as placeholders for our inputs it just tells the tensorflow graph that hey we're going to be passing in some variables we don't know what they are yet we may not necessarily even know their shape or size but we know what type they are and we want to give them names so if something goes wrong we can debug later so this input will just be the eight element vector that represents the agent's observation of the environment and if you're not really familiar with tensorflow this idiom of saying shape equals a list whose first element is none tells tensorflow that we do not know the batch size of the data we're going to be loading so the inputs could be 10 states it could be 100 it could be a thousand it could be any number of states and so that none just tells tensorflow hey we don't know what shape it's going to be so you know just take whatever and this label is going to be the actions the agent took during the course of the episode this will be used in calculating our loss function similarly we have something called g and g is just the generic name for the agents discounted future rewards following each time step this is what we will use to bias the agent's loss function towards increasing the probability of actions who generate the most returns over time so now we're going to construct our network so the first layer will just be the input and the number of it'll take of course number of input and input dimms on input and then output the player one size and the activation is just going to be a value function and then we have to worry about initializing this so when we call the tf.global variables initializer it's going to initialize all of the layers and variables with some values we can dictate how it does that and we can think very carefully about it so if you've dealt with deep neural networks in some cases you can get vanishing or exploding gradients that cause the values the network predicts to you know go to you know either really large or really small values it produces junk essentially there is a function that will initialize the values of all the layers such that they are relatively comparable and we have a minimal risk of that happening and that's called a xavier initializer and i'm going to want to copy that because we're going to use that more than once so of course the second layer just takes the first layer's input has l2 size as the number of units with a value activation and of course the same initializer and l3 will be the output of our network however we don't want to activate it just yet so this quantity is related to the probability sorry the policy of the agent but the policy must have the uh property that the sum of the probabilities of taking an action you know the sum of the probabilities for all the actions must equal one and it's the softmax function that has that property and we're going to separate it out so that we can just so that it is a little bit more clean in terms of the the code a little bit more readable for us but the self.actions variable is what will actually calculate the probabilities of selecting some action and that is just the softmax of the l3 and the name of that is probabilities finally we need to well not finally but next we need to calculate the the loss function so we'll stick that in a separate scope and uh what we need is the negative log probability so excuse me the calculation involves the natural log of the policy and you want to take the gradient of the natural log of something so we need a function that matches that property so we'll call it neg log probability and that's the sparse soft max cross entropy with logits try saying that five times fast so log x is just l three and this is important because this is part of the reason we separated out l three in actions because when you're passing in the logits you don't want it to already be activated because the negative the sparse soft max cross entropy will handle the softmax activation function and the labels will just be the label that we pass in from the placeholder and then of course be the actions the agent took and so the loss is then that quantity neglog probability multiplied by the returns g next we need the training operation and that of course is just our gradient descent type algorithm in this case we'll use the atom optimizer the learning rate of whatever we dictate in the constructor and we want to minimize that loss so that is the sum and hole of the deep neural network we need to we need to code the next question we have is how can we select actions for the agent so the agent is attempting to model its own probability distribution for selecting actions so that means what we want to do is take a state as input pass it through the network and get out that probability distribution at the end given by the variable self.actions and then we can use numpy to select a random action according to that probability distribution and we're just going to go ahead and reshape this bill it is so when you run an operation through the tensorflow graph you need to specify a feed dictionary which gives the graph all of the input placeholder variables it's expecting so in this case it wants self.input and that takes state as input and it's going to return a tuple so we're going to take the 0th element as so we can get the correct value that we want and then we can select an action according to numpy random choice from the action space using the probabilities as our distribution and we just returned that action the next problem we have to deal with is storing an action sorry the transitions and of course we'll store the state action and reward and this will be useful when we learn and since we're using lists here we're just going to append the elements to the end of the list next we come to the meat of the problem the learning function and this doesn't require any input so the basic idea here is that we are going to convert these lists into numpy arrays so we can more easily manipulate them and then we're going to iterate through the agent's memory of the rewards it received and calculate the discounted sum of rewards that followed each time step so we're going to need two for loops and a variable to keep track of the sum as well as something to keep track of our discounting so let's deal with the memories first that won't work will it there we go so now we'll instantiate our g factor and get in shape of reward memory we will iterate over the length of that memory which is just length of our episode and so for each time step we want to calculate the sum of the rewards that follow that time step is that correct yes next we take the sum and discount it then of course the discount is just the gamma to the k where k is our time step so then of course the rewards following the teeth the teeth teeth the t time step is just g sum so that's the sum that's the weighted discounted rewards the next thing we have to think about is these rewards can vary a lot between episodes so to promote stability in our algorithm we want to scale these results by some number it turns out that a reasonable number to use is the mean so we're going to subtract off the mean of the rewards the agent received during the episode and then divide by the standard deviation this will give us some nice scaled and normalized numbers such that the algorithm doesn't produce wacky results and since we're dividing by the standard deviation we have to account for the possibility that the standard deviation could be zero hence the conditional statement next we have to run our training operation so the underscore tells us we don't really care about what it returns we have to run the training operation the feed dictionary that'll take an input which is just our state memory it will take the labels and that is just the action memory and it will take the g factor which is just the g we just calculated now at the end of the episode once we finish learning we want to reset the agent's memory so that rewards from one episode don't spill over into another so there are two more functions we need these are administrative we need a way to load the checkpoint and we'll go ahead and print out loading checkpoint just so we know it's doing something and then we have the saver object and we want to restore a session from our checkpoint file next we want to save a checkpoint we're not going to print here i take it back reason is that we're going to be saving a lot and i don't want to print out a bunch of junk statements so and what these are doing is just either taking the the current graph as it is right now and sticking it into a file or conversely taking the graph out of the file loading it into the graph for the current session so that is that next we can move on to the main program to actually test our lander so we'll need jim and i didn't i don't know if i made it clear at the beginning but you'll also need the box 2d dash pi environment so go ahead and do pip install box 2d dash pi if you don't already have that so we'll need to import our policy gradient agent i have this plot learning function i always use you can find it on my github along with this code of course i don't elaborate on it but basically what it does is it takes a sequence of rewards keeps track of it performs a running average of say the last 20 25 whatever amount you want and spits that out to a file we also have a way of saving the renderings of the environment so it runs much faster if you don't actually render to the screen while it's training but you can save those renderings to files in mp4 files so you can go back and watch them later it's how i produce the episodes you saw at the beginning of this video so first thing i'm going to do is instantiate our agent and we'll use a learning rate of zero three zeros and a five and i believe uh oh we'll need a gamma we use something like 0.99 and all and then all the other parameters we'll just leave at the defaults next we need to make our environment and that's lunarlander v2 a way to keep track of the scores the agent received our initial score and number of episodes so i achieved uh pretty good results after 2500 episodes so we can start with that so the first thing we want to do is iterate over our episodes oh let me do this for you so before we do that um i'll comment this out but if you want to save the output you do this env equals wrappers dot monitor pass in the environment wherever you want to save it lunar lander and then you want to use a lambda function to tell it to render on every episode and this force equals true i believe that just tells it to overwrite if there's already data in the directory so at the top of every episode just print out what episode number you're on and the current score you set your done flag and for subsequent episodes you'll want to reset the score reset your environment and play an episode first thing you want to do is select an action and that takes the observation as input so we need to get the new observation reward done flag and info by stepping through the environment once that's done you want to store the transition set the old observation to be the new one so that you select an action based on the new estate and keep track of the reward you received at the end of every episode we want to append the score to the score history and perform our learning operation you also want to save a checkpoint after every operation ever after every learning operation and then when you're done dictate some file name dot png and call my super secret plot learning function that just takes the score history file name and a window that tells it over how many games you want to take the running average so now let's go to our terminal and see how many mistakes i made one second all right so here we are let's go ahead and give it a try so i made some kind of error in the policy gradient agent let's swing back to that file and see where it is one second so here's the model it does not have input dimms that's because i forgot to keep track of it save go back to our terminal and see how it does and i apparently called something i should not have this is line 27 it says self.label placeholder got an unexpected keyword argument named label ah that's because it is called name that's what happens when i try to type and talk at the same time let me make sure i didn't call l1 size l2 size something different no i did not all right i will run that again so now it's unhappy about the choice of oh of course so it's lunar there's no dash in there get rid of that typos galore tonight oh really oh really ah it's store transitions yes so it's actually store transitions so let's call it that and there we go perfect so now it's actually learning i'm not going to sit here and wait for this to do 2500 games because i've already run this once before that's how i got the kodi saw at the beginning so i'm going to go ahead and show you the plot that it produces now so you can see how it actually learns so by the end it gets up to about an average reward of around 200 and above points that's considered solved if you check the documentation on the openai gym so congratulations we have solved the lunar lander environment with the policy gradient algorithm relatively simple just a a deep neural network that calculates the probability of the agent picking an action so i hope this has been helpful go ahead and leave a comment down below feel free to take this code from my github fork it make it better do whatever you want with it i look forward to seeing you all in the next video welcome back everybody to a new reinforcement learning tutorial in today's episode we're going to teach an agent to play space invaders using the policy gradient method let's get to it for imports we start with the usual suspects numpy and tensorflow we start by initializing our class for the policy gradient agent we take the learning rate discount factor number of actions number of layers for the fully connected layer the input shape channels a directory for our checkpoints very important as well as a parameter to dictate which gpu we want tensorflow to use if you only have one gpu or using the cpu you don't need that parameter save the relevant parameters and compute the action space which is just a set of integers we want to subtract out the input heights and width from the input shapes and keep track of the number of channels for use later our agent's memory will be comprised of three lifts that keep track of the state action and rewards we want a configuration which just tells tensorflow which gpu we want to use as well as our session graph that uses that config we call the build network function and then use the tf global variables initializer we need to keep track of the saver and a checkpoint file for saving and loading the model later now if you don't know anything about policy gradient methods don't worry we're going to cover everything you need to know as we go along the first thing we're going to need is a convolutional neural network to handle image pre-processing that'll be connected to a fully connected layer that allows the agent to estimate what action it wants to take in contrast to things like deep q learning policy gradient methods don't actually try to learn the action value or value functions rather policy gradients try to approximate the actual policy of the agent let's take a look at that for our build network function we're going to construct a convolutional neural network with a few parameters an input placeholder that has shape batch size by input height and width as well as the number of channels we will also need an input for the labels which just correspond to the actions the agent takes that is shape batch size and a factor g which is just the discounted future rewards following a given time step that is shape batch size our convolutional neural network is going to be pretty straightforward if you've seen any of my videos you can kind of know what to expect the first layer has 32 filters a kernel size of eight by eight and a stride four and we're going to want to use an initializer for this i found that the xavier initializer works quite well the purpose of it is to keep the to initialize all the parameters in such a way that the uh they the network doesn't have one layer with parameters significantly larger than any other we want to do batch normalization i mistyped the epsilon there should be one by ten to the minus five and you want to of course use a value activation on the first convolutional layer and that commvault that activated output serves as the input to the next layer with 64 filters kernel size of 4x4 and a stride of 2 and again we'll use the xavier initializer of course we also want to do batch normalization on this layer and at this point i think i actually get the correct epsilon for the batch norm and of course we want to use a value activation on that batch normed output as well our third convolutional layer is more of the same 2d convolution with 128 filters it will have a kernel size of 2x2 a stride of 1 and we'll also use the same initialization again batch normalization with an epsilon of 1 by 10 to the minus 5. activate with a value next we have to take into account our fully connected layers so the first thing we need to do is flatten the output of the convolutions because they come out as matrices we need a list go ahead and make the first fully connected layer using fc1 as the number of units value activation and the second dense layer is going to have units equal to the number of actions for the agent which in this case is just six notice that we don't activate that but we have a separate variable for the actions which is the activated output of the network and we're going to use a soft max so that way we get probabilities that add up to one we need to calculate the negative log probability with a sparse softmax cross-entropy function with logits using dense two as our logits and labels as of the actions as our labels the loss is just that quantity multiplied by the expected future rewards and of course we want to reduce that quantity now for the training operation we're going to use the rms prop optimizer with a set of parameters i found these to work quite well this algorithm is pretty finicky so you may have to play around the next thing we have to do is code up the action selection algorithm for the agent in policy gradient methods we're trying to actually approximate the policy which means we're trying to approximate the distribution by which the agent chooses actions given it's in some state s so what we need is a way of computing those probabilities and then sampling them sampling the actions according to those probabilities we choose an action by taking in an observation reshaping it of course this will be a sequence of frames uh for high and you want to calculate the probabilities associated for each action given that observation and then you want to sample that probability distribution using the numpy random choice function next up we have to take care of the agent's memory so we're going to store the observation action and reward in the agent's list using a simple append function so one big problem we're going to have to solve is the fact that policy gradient methods are incredibly simple and efficient these monte carlo methods meaning that at the end of every episode the agent is learning so it throws away all of the experience that required in prior episodes so how do we deal with that well one way to deal with that is to actually queue up a batch of episodes and learn based on that batch of experiences the trouble here is that when we take the rewards that follow any given time step we don't want to account for rewards following the current episode so we don't want rewards from one episode spilling over into another so we have to take care of that here next up we handle the learning for the agent we want to we want to convert the state action and reward memories into arrays so that we can feed them into the numpad the excuse me tensorflow learning function into the sorry the tensorflow graph we have to start by reshaping the state memory into something feasible and then we can calculate the expected feature rewards starting from any given state so what we're going to do is iterate over the entire memory and take into account the rewards the agent receives for all subsequent time steps we also need to make sure that we're not going to take into account rewards from the next episode next up we have the scale the expected feature rewards this is to reduce the variance in the problem so let's make sure we don't have really really large rewards so everything is just kind of scaled next up we call the training operation with an appropriate feed dict of the state memory action memory as labels and the g for our g variable finally since we're done we're going to clear out the agent's memories finally we just have some bookkeeping functions to load and save checkpoints you just call the saver restore function that loads the checkpoint file into the session and the save checkpoint just dumps the current session into the checkpoint file another problem we have to solve is that the agent doesn't get a sense of motion from only a single image right if i show you a single image you don't know if the aliens are moving left or right or really you don't know which direction you're moving so we have to pass in a sequence of frames to get a sense of motion for our agent this is complicated by the fact that the open ai gym atari library in particular returns a set of frames that are repeated so if you actually cycle through the observations over time you'll see that the frames change or sorry don't change uh based on an interval of one two or three so we have to capture enough frames to account for that fact as well as to get a overall sense of movement so that means four is going to be our magic number for so for stacking frames next we move into the main program we import gym numpy our model as well as the plot learning function which is a simple utility you can find on my github as well as the wrappers to record the agent's gameplay if you so choose we need to pre-process the observation by truncating it and taking the average next up we stack the frames so at the beginning of the episode stack frames will be none so you want to initialize an empty array of zeros and iterate over that array and set each of those rows to be the current observation otherwise what you want to do is you want to pop off the bottom observation shift everything down and put the fourth spot or the last spot to be the current observation down in the main function we have a checkpoint flag if you want to load a checkpoint we want to initialize our agent with this set of hyper parameters i found these to work reasonably well you can play around with them but it is incredibly finicky so your mileage may vary we need a file name to save our plots we'll also want to see if we want to load a checkpoint next we initialize our environment space invaders of course keep track of the score history score number of episodes and our stack size of four one iterate over the number of episodes resetting the done flag at the top of each episode we also want to keep track of the running average score from the previous 20 games just so we got an idea if it's actually learning every 20 games we're gonna print out the uh episode score and average score otherwise every other every other episode we're just going to print out the episode number and the score reset the environment and of course you have to pre-process that observation and then go ahead and set your stacked frames to none because we're the top of the episode and then call the stack frames function so that we get four of the initial observation set the score to zero and start iterating over the episode so his first step is to choose an action based on that set of stacked frames go ahead and take that action and get your new state action and reward go ahead and pre-process that observation so that way you can stack it on the stack of frames next up you have to take care of the agent's memory by storing that transition and finally you can increment your score save the score at the end of the episode and every 10 games are going to handle learning and saving a checkpoint and when you're all done go ahead and plot the learning now the agent is done we can take a look at the actual plot it produces over time this is how you know an agent is actually learning what you'll see is that there is some increase in the average reward over time you'll see oscillations up and down and that's perfectly normal but what you want is an overall upward trend now for this particular set of algorithms it is notoriously finicky with respect to learning rates i didn't spend a huge amount of time tuning them or playing with them i just wanted to get something good enough to show you guys how it works and turn it over to your capable hands for fine tuning but what you do see is a definite increase over time as the agent's average reward improves by about 100 points or so that isn't going to win any awards but it is definitely a clear and unequivocal sign of learning so there you have it that was policy gradients in the space invaders environment from the open ai gym i hope you learned something make sure to check out this code on my github you can fork it you can copy it you can do whatever you want with it make sure to subscribe leave a comment down below if you found this helpful i look forward to seeing you all in the next video welcome back everybody to neuralnet.ai i am your host phil tabor previously a subscriber asked me hey phil how do i create my own reinforcement learning environment i said well that's a great question i don't have time to answer it in the comments but i can make a video so here we are what we're going to do in the next two videos is create our own open ai gym compliant reinforcement learning environment the grid world it's going to be text based and if you're not familiar with it the grid world is aptly named a grid of size and by n where the agent starts out in say the top left and that's to navigate its way all the way to the bottom right the twist on this is going to be that there will be two magic squares that cause the agent to teleport across the board the purpose of doing this is to create a shortcut to see if the agent can actually learn the shortcut kind of interesting the agent receives a reward of -1 with each step except for the terminal step or receives a reward of zero therefore the agent will attempt to maximize its reward by minimizing the number of steps it takes to get off the grid world what other things two other concepts we need are the concept of the state space which is the set of all states minus the terminal state and the state space plus which is the set of all states including the terminal state this gives us a bit of a handy way to find out the terminal state as well as to find out if we're attempting to make illegal moves it also follows the nomenclature and terminology from the sutton bardo book reinforcement learning which is an awesome resource you should definitely check out if you have not already so in part one we're going to handle the environment and in part two we're going to get to the main loop and the agent for which we will use q learning now deep q learning because this is a very straightforward environment we don't need a functional approximation we just need the tabular representation of the agent's estimate of the action value function so if you're not familiar with q learning i do have a couple videos on the topic one where the q learning agent solved the card poll game as well as a an explainer type video that talks about what exactly q-learning is so let's go ahead and get started we only have a couple dependencies we're not doing anything on the gpu so just numpy and matplotlib we want to close everything up into a class called grid world and our initializer will take the m and n which is the shape of the grid as well as the magic squares so we represent our grid as an array of zeros and shape m by n we want we want to learn to type uh we want to learn to sorry we want to keep tr we want to keep track of the m and the end for handy use later so let's go ahead and define our state space and that's just going to be a list comprehension for all the states in the range self.m times self.n now the as i said the state space does not include the terminal state and the terminal state is the bottom right so we have to go ahead and remove or pop off that particular state from the list uh next up so now let's go ahead and again learn to type go ahead and define our state space plus also we need to know the the way that the actions map up to their change on the environment so we'll call that the action space a little bit of a misnomer but we can live with it for now so moving up we'll translate the agent up one row which is distance m and moving down will advance the agent's position downward by also m um moving left we'll translate the agent one step we'll decrement the agent's position by one and moving right we'll increase it by one we also want to keep track of the set of possible actions you could use the keys in the action space dictionary but let's go ahead and use a separate structure and we'll use a list up down left and right the reason is that the q learning agent a q learning algorithm sorry can it can choose actions at random so it is handy to have a list from which you can choose randomly uh next we need to add the magic squares because that's a little bit more complicated than it may seem and finally when we initialize the grid we want to set the agent to the top left position let's go ahead and add those magic squares so of course we want to store that in our object now there's a little bit of hokiness that i must explain so the agent is represented by a zero when we print out the grid to the terminal and uh md squares are represented by a one and so excuse me and so that means we need something other than 0 and 1 to represent these magic squares i want to when i render the environment i want to know where the entrance and where the exit is so we use different values for the entrance and exit so that way we can render it correctly so just by royal decree we set i which would be the representation of the of the magic square in the grid world to 2 to start and we're going to go ahead and iterate over the magic squares so now what we need to know is uh what position we are in so you sorry it's the color is off indicating something is wrong i have screwed something up royally which i do not see because i am blind anyway so the the x position is just going to be the floor of the current square and the number of rows and y will be the modulus of the number of columns so then the grid we want to set that x and y position to i and since we want to have a different representation for the entrance and exit go ahead and set the increment i by one recall that the magic squares are is represented as a dictionary so we're iterating over the keys and the values are the destinations so the keys are the source values are destinations so next we want to find out precisely that what the destinations are set that in and then set the grid that square to i and then increment i again and i'm only going to do i'm only going to do two magic squares you can do any number but in this case we're just gonna do two so okay so the next thing we need to know is if we are in the terminal state and as i said earlier the state space and state space plus concepts give us a very easy way of doing that so let's go ahead and take care of that so since the state space plus is all the states and the state space is all the states minus the terminal state we know that the difference between these two sets is the terminal state so state in state space plus and not in the state space how does that look let me scroll down a bit okay so next up let us go ahead and get the agent row and column and we're going to use the same logic as above so next we want to set the state so that will take the new state as input and we're going to go ahead and assume that the new state is allowed so the agent if it is along the left edge and attempts to move left it just receives a reward of minus one and doesn't actually do anything likewise if it's on the top row and attempts to move up it doesn't actually do anything it just gets a reward of minus one for wasting its time so we want to get uh sorry the row and column and set that space to zero because zero denotes an empty square and the agent position then is the new state and again we want to get the new x a new y there is a typo there let's fix that and then set that position to one because that is how we represent the agent by royal decree so the next thing we have to know is if we're attempting to move off the grid that's not allowed the agent can only stay on the grid so let's take care of that so we want to take the new and old states as input and the first thing we want to know is if we're attempting to move off the grid world entirely that's ah so i hate these editors so uh if we are if the new state is not in the new state space plus we are attempting to move off the grid so you return true otherwise if the old state modulus m equals zero and new state modulus um self.m equals self.m minus one then we return true and for brevity i could explain this but the video is running long already so for brevity the reason this is true is left as an exercise to the reader bet you didn't know this was going to be like a college course so now uh basically what we're trying to do here i'll just give you a hint what we're trying to do here is determine if we're trying to move off the grid either to the left or to the right we don't want to wrap around so so if you're for instance if we have a nine by nine grid it goes from zero to eight so then if you add one right you would get nine which would teleport you to the other row uh and the zeroth column you don't want that what you want to do is waste spa ways to move and receive a reward of minus one so that's what we're doing here um old state modulus good grief so if neither of those are true then you can go ahead and return false meaning you're not trying to move off the grid so let's see can you see that you can so next function we need is a way to actually step so let's go ahead and do that let's say the only thing we need is to take in the action so the first thing you want to do is get the x and y again and here's where we're going to check to make sure it's a legal move so the resulting state is then agent position plus the mapping so the agent position is whatever it is and recall that the action space is this dictionary here that maps the actions to the translations in the grid so we're doing down here then is saying the new state is equal to the current state plus whatever the resulting translation is for whatever action we're attempting to make so next thing we need to know is are we on a magic square and if we are um and if we are then the um agent teleports to its new position okay so next up we need to handle the reward so it's minus one if not um is terminal state so it's minus one if we haven't transitioned into the terminal state otherwise it is zero if we're not trying to move off the grid then we can go ahead and set that state self.set state resulting state and then we're ready to go ahead and return so in the openai gym uh whenever you take a step it returns the new state the reward um whether or not the game is over and some debug information so we're gonna do the same thing resulting state reward and the whether or not it is the terminal state and our debug info is just going to be none so if we are attempting to move off the grid what do we want to do nothing so we want to return agent position um and the reward and whether or not it's terminal and the null debug info we're almost there so next thing we need to know is how do we reset the grid because at the end of every episode we have to reset right first thing to do is set the agent position to zero reset the grid to zeros and go ahead and add the magic squares back in and return the agent position which is of course zero oh wow that's real close all right so next up one last function i swear just one more i promise all right i wouldn't lie to you all right next up we want to provide a way of rendering because hey that's helpful for debug i like to print a whole big string of you know dashes because it's party [Music] we want to iterate over the grid for column in row column equals zero in other words if it's an empty square we're just going to print a dash and we're going to end it with a tab if the column is 1 meaning we have an agent there we're going to print an x to denote the agent now if the column is 2 then that is one of the entrances to our magic squares so print the a in with a tab delimiter a tab end if the column equals three you can print a out and equals tab um and if the column equals four then we know we're at the other magic square entrance and finally if it's five then we know we're at the other magic squares exit after each row we want to print a new line and at the end we'll go ahead and print another chunk of pretty dashes oh ah yeah that's it that is it okay so that is it for our agent class that only took how long 20 some minutes wow okay i hope you're still with me basic idea here is to make your own environment you need an initialize a reset a state space state space plus a way to denote possible actions a way to make sure the move is legal and a way to actually affect that environment the step function needs to return the new position the reward whether or not the state is the new state is terminal as well as some debug information you also need a way of resetting and printing out your environment to the terminal so in part two we're actually going to fire this baby up with a q learning algorithm and see how she do that's actually quite exciting it well moderately exciting anyway it actually learns it does quite well and it does find the magic square spoiler alert if you made it this far it finds a magic square and gets out of the minimum number of moves required um it's pretty cool to see so that will come in the next video on vedna's day i hope to see you all then if you like the video make sure to leave a thumbs up subscribe if you have not already for more reinforcement learning content and i will see you all in the next video welcome back everybody to a new tutorial from neuralnet.ai i am your host phil taber if you're new to the channel i'm a physicist former semiconductor process engineer turned machine learning practitioner if you haven't subscribed yet go ahead and hit the the subscribe button so you don't miss any future reinforcement learning tutorials when we left off in our previous video we just finished up the bulk of our open ai gym compliant reinforcement learning environment today we're going to go ahead and code up a q learning agent and the main loop of the program to see how it all performs so let's go ahead and get started so the uh first thing we are going to need is the um is the magic squares right if you recall the magic squares are the teleporters in the grid world that either advance the agent forward or backward so the first one is going to be at position 18 and dump out at position 54 so it'll move it forward and the next one will be at let's say 63 and dump out at position 14. so teleporter a will advance the agent through the grid world and teleporter b will send it back to an earlier square so we need to create our grid world we use a nine by nine grid and pass in the magic squares we just created next up we have to worry about the model hyper parameters so if you are not familiar with that let me give you a quick rundown these are the parameters that control how fast the agent learns and how much it chooses to value the potential future rewards so the first parameter is alpha that is our learning rate 0.1 a gamma of 1.0 tells us that the agent is going to be totally farsighted it will count all future rewards equally an epsilon of 1.0 this is of course the epsilon for epsilon greedy action selection so it will start out behaving pretty much randomly and eventually converge on a purely greedy strategy so q learning is a tabular method where you have a table of state and action pairs and you want to find the value of those state action pairs so to construct that we have to iterate over the set of states and actions state space plus and emv dot possible actions and you have to pick something for an initial value it's really arbitrary but the cool thing about picking zero is that we're using something called optimistic initial values what this means is that since the agent takes or receives a reward of minus one for every step it can never have a reward of zero right because there's some distance between the agent and the exit so by setting the initial estimate at zero you actually encourage exploration of unexplored states because if the agent takes a move it realizes oh i get a reward of -1 that's significantly worse than 0. let me try this other unexplored option so over time it will gradually explore all the available actions for any given state because it's been disappointed by all the stuff it has previously tried just a fun little fact we want to play 50 000 games we need a way of keeping track of our rewards numpy array will do just fine yes so now let's iterate over the total number of games and um thief i like to print out a marker to the terminal so that way i know it's actually working so every five thousand games just print that we're starting the ith game at the top of every episode you want to reset your done flag you want to reset your episode rewards so you don't accumulate rewards from episode episode and of course you want to reset your environment oh let me scroll down here there we go you want to reset your environment just as you would with any open ai gym type problem next up we begin each episode so while not done we want to take a random number for our epsilon greedy action selection so we're going to just make use of this max action before we define it q observation and env.possible actions and what that will do is uh we're going to write it here momentarily but what it's going to do is it is going to find the maximum action for a given state so the random number is less than one minus epsilon we want to do that can you guys see that yep otherwise we want to take a random sample of the action space so we have to write these two functions let's do that quite quickly so the action space sample is pretty straightforward we can just return a random choice from the list of possible actions and that's the reason we chose a list as that data structure just to make it easy next up we have the max action max yeah max action function but that doesn't need to belong to the class that takes the q the state and the set of possible actions we want to take a numpy array of the estimates agent sorry the agent's estimate of the present value of the expected future rewards for the stated stand in all possible actions a in actions and then we want to find the maximum of that and that's just an index so we want oop sorry that's just an index so we want to return the action that that actually corresponds to all right that's all well and good we need more space let's do a little bit more there we go so next we want to actually take the action so we get our new state observation underscore reward done and info envy.step action and next up uh we have to calculate the maximal action for this new state so that we can insert that into our update equation for the q function so let's do that and we're not worried about epsilon greedy here because we're not actually taking that action next up we have to update rq function for the current action and state and that's where our alpha comes in ward plus make sure that is visible to you reward plus some quantity which is gamma our discount factor times q observation underscore action underscore so the new state and action minus q observation action let me tab this over there we go nice and compliant with the pep style guides right mostly okay so this is the update equation for the q function that will update the agent's estimate of the value of the current state and action pair next up we just need to let the agent know that the uh environment has changed states so you set observation to observation underscore and that is it for q learning in a nutshell folks that's really that straightforward so the end of each episode we want to decrease epsilon so that way the agent eventually settles on a purely greedy strategy you can do this a number of ways you can do it you know with a square root function a log function i'm just going to do it linearly it's not that critical for something like this so it's going to decrease it by 2 divided by num games every every game so about halfway through it'll be purely greedy and at the end of every episode you want to make sure you're keeping track of the total rewards which is something i forgot up here yeah so one thing i did forget is to keep track of the total reward for the episode don't forget that very important and at the end of all the episodes you want to plot the total rewards and that is it for the coding portion oh one other thing i take it back so let's scroll up here i do want to show you the environment so let's just do that env dot render and the purpose of doing that is so that you can see how many moves it takes the agent to escape from the grid world that will tell us if it's doing good or not right because there's a minimum minimum number of moves it takes to escape so i'm going to fire up the terminal and go ahead and get that started one second and here we are in the terminal let's go ahead and run that and you can see here that we start at the top left so it takes one two moving to a out is free so 3 4 5 6 7 8 9 10 11. sorry 11 and the 12th move is free because it's the exit to the maze sorry to the grid world so total reward of minus 11 is the best the agent can possibly do it's gone ahead and plotted so let's check that out and here is the plot and you can see that indeed the agent starts out rather poorly exploring finding sub-optimal routes through the grid world but eventually and about halfway through here at um 2500 or so sorry 25 000 you can see that it settles on at least a constant value let's prove that it is the maximum value of minus 11 and you can see that it's 10.97 that is close enough for government work so you see that the agent is able to actually solve the maze sorry the grid world i keep calling it amaze is able to solve the grid world using the q learning algorithm now this isn't surprising you know we would expect this uh what's novel here is that we have created our own reinforcement learning environment that uses a very similar format to the open ai gym so anytime you want to create a new environment you can use you can fire this video up and use the you know set of code here just as a template for your own projects i'm going to put this up on my github i'll link that down below and i'm also going to write up a tutorial for uh in text form and upload it to neuralnet.ai i don't know if all that done tonight i'll update the description with it that's if you are a you know if you consume text more easily than than video then you can go ahead and check that out i hope this has been helpful uh make sure to leave a comment subscribe if you haven't already and i hope to see you all in the next video welcome back data manglers thanks for tuning in for another episode from neuralnet.ai if you're new to the channel i'm phil tabor a physicist and former semiconductor engineer turned machine learning practitioner i'm on a mission to teach the next generation of data engineers so we can stay one step ahead of our robot overlords if you're not subscribed be sure to do that now so you don't miss any future reinforcement learning content we've touched on reinforcement learning many times here on the channel as it represents our best chance at developing something approximating artificial general intelligence we've covered everything from monte carlo methods to deep q q-learning to policy gradient methods using both the pi torch and tensorflow frameworks what we haven't discussed on this channel is the what and the how of reinforcement learning that oversight ends today right now okay maybe a few seconds from now but either way we're going to cover the essentials of reinforcement learning but first let's take a quick step back you're probably familiar with supervised learning which has been successfully applied to fields like computer vision and linear regression here we need mountains of data all classified by hand just to train a neural network while this is proven quite effective it has some pretty significant limitations how do you get the data how do you label it these barriers put many of the most interesting problems in the realm of mega corporations and this does us the individual practitioners no good to top it off it's not really intelligence you and i don't have to see thousands of examples of a thing to understand what that thing is most of us learn actively by doing sure we can shortcut the process by reading books or watching youtube videos but ultimately we have to get our hands dirty to learn if we abstract out the important concepts here we see that the essential stuff is the environment that facilitates our learning the actions that affect that environment and the thing that does the learning the agent no jacket or labels required enter reinforcement learning this is our attempt to take those ingredients and incorporate them into artificial intelligence the environment can be anything from text-based environments like card games to classic atari games to real to the real world at least if you're not afraid of skynet starting an all-out nuclear war that is our ai interacts with this environment through some set of actions which is usually discrete move in some direction or fire at the enemy for instance these actions in turn cause some observable change in the environment meaning the environment transitions from one state to another so for example in the space invaders environment in the open ai gym attempting to move left caused the agent to move left with 100 probability that need not be the case though in the frozen lake environment attempting to move left can result in the agent moving right or up or down even so just keep that in mind that these state transitions are probabilistic and their probabilities don't have to be one hundred percent merely their sum the most important part of the environment is the reward or penalty the agent receives if you take only one thing away from this video it should be that the design of the reward is the most critical component of creating effective reinforcement learning systems this is because all reinforcement learning algorithms seek to maximize the reward of the agent nothing more nothing less in fact this is where the real danger of ai is it's not that it would be malicious but that it would be ruthlessly rational the classic example is the case of an artificial general intelligence whose reward is centered around how many paper clips it churns out sounds innocent right well if you're a paper clip making bot and you figure out that humans consume a bunch of resources that you need to make paper clips then those pesky humans are in the way of an orderly planetary scale office that's problematic for all involved what this means is we must think long and hard about what we want to reward the agent for and even introduce penalties for undertaking actions that endanger human safety at least and systems that will see action in the real world perhaps less dramatic although no less important are the implications for introducing inefficiencies in your agent consider the game of chess you might be tempted to give the agent a penalty for losing pieces but this would potentially prevent the agent from discovering gambits where it sacrifices a piece for a longer term positional advantage the alpha zero engine a chess playing artificial intelligence is notorious for this it will sacrifice multiple pawns and yet still dominate the best traditional chess engines we have to offer [Music] so we have the reward the actions and the environment what are the agent itself the agent is the part of the software that keeps track of these state transitions actions and rewards and looks for patterns to maximize its total reward over time the algorithm that dictates how the agent will act in any given situation or state of the environment is called its policy it is expressed as a probability of choosing some action a given the environment is in some state s please note these probabilities are not the same as the state transition probabilities the mathematical relationship between state transitions rewards and the policy is known as the bellman equation and it tells us the value meaning the expected future reward of a policy for some state of the environment reinforcement learning often though not always means maximizing or solving that bellman equation more on that in future videos this desire to maximize reward leads to a dilemma should the agent maximize his short-term reward by exploiting the best-known action or should it be adventurous and choose actions whose reward appears smaller or maybe even unknown this is known as the explore exploit dilemma and one popular solution is to choose the best known action most of the time and occasionally choose a sub-optimal action to see if there's something better out there this is called an epsilon greedy policy when we think of reinforcement learning we're often thinking about the algorithm the agent uses to solve the bellman equation these generally fall into two categories algorithms that require a full model of their environment and algorithms that don't what does this mean exactly to have a model of the environment as i said earlier actions cause the environment to transition from one state to another with some probability having a full model of the environment means knowing all the state transition probabilities with certainty of course it's quite rare to know this beforehand and so the algorithms that require a full model are of somewhat limited utility this class of algorithms is known as dynamic programming if we don't have a model or a model of the environment is incomplete we can't use dynamic programming instead we have to rely on the family of model-free algorithms one popular such algorithm is q learning or deep q learning which you studied on this channel these rely on keeping track of the state transitions actions and rewards to learn the model of the environment over time in the case of q-learning these parameters are saved in a table and in the case of deep q learning the relationships between them are expressed as an approximate functional relationship which is learned by a deep neural network that's really all there is at least at a high level so to recap reinforcement learning is a class of machine learning algorithms that help an autonomous agent navigate a complex environment the agent must be given a sequence of rewards or penalties to learn what is required of it the agent attempts to maximize this reward over time or mathematical terms to solve the bellman equation the algorithms that help the agent estimate future rewards fall into two classes those that require we know the state transition probabilities for the environment beforehand and those that don't since knowing these probabilities is a rare luxury we often rely on model-free algorithms like deep queue learning if you'd like to know more please check out some of the other videos on this channel i hope this has been helpful please leave a comment a like and subscribe if you haven't already look forward to seeing you all in the next video welcome back to the free reinforcement learning course from neuralnet.ai i'm your host phil tabor if you're not subscribed be sure to do that now and hit the bell icon so you get notified for each new module in the course in module 1 we covered some essential concepts in reinforcement learning so if you haven't seen it go ahead and check it out now so this module makes more sense if you have seen it you may remember that reinforcement learning basically boils down to an agent interacting with some environment and receiving some rewards in the process these rewards tell the agent what's good and bad and the agent uses some algorithm to try to maximize rewards over time in practice what we get is a sequence of decisions by the agent and each decision doesn't just influence its immediate reward rather each decision influences all future rewards in mathematical terms we have a sequence of states actions and rewards that one could call a decision process if each state in this process is purely a function of the previous state and action of the agent then this process is called a markov decision process or mdp for short these are an idealized mathematical abstraction that we use to construct the theory of reinforcement learning for many problems this assumption can be broken to various degrees how much that really matters is often a complicated question and one we're just going to dodge for now regardless in most cases the assumption that a process obeys the markov property is good enough and we can use all the resulting mathematics for reinforcement learning problems by now i've said that a reinforcement learning agent seeks to maximize rewards over time so how does this fit into a markov decision process from the agent's perspective it receives some sequence of rewards over time and that sequence of rewards can be used to construct the expected return for the agent then the return at some time step t is just the sum of the rewards that follow all the way up to some final time capital t this final time step naturally introduces the concept of episodes which are discrete periods of gameplay that are characterized by state transitions actions and rewards upon taking this final time step the agent enters some terminal state which is unique this means that no matter how we end the episode the terminal state is always the same no future rewards follow after we reach the terminal state so the agent's expected reward for that terminal state is precisely zero with a bit of creativity we call tasks that can be broken into episodes episodic tasks of course not all tasks are episodic many are in fact continuous this is a bit of a problem since if the final time step is at infinity the total reward could also be infinite this makes the concept of maximizing rewards meaningless so we have to introduce an additional concept the fix and we use this for both episodic and continuing tasks is the idea of discounting this basically means the agent values future rewards less and less this discounting follows a power law where each time step results in more and more discounting this hyperparameter gamma is called the discount rate and you've no doubt seen this before in our videos on reinforcement learning if you use this form for the expected return and do some simple factoring you derive a really useful fact there is a recursive relationship between rewards at subsequent time steps this is something we'll exploit constantly in reinforcement learning so we have an agent that is engaged in some discrete processes receiving rewards and trying to maximize its expected feature returns if you remember from the first lecture the algorithm that determines how the agent is going to act is called its policy since the agent has a set of defined rules for how it's going to act in any given state it can use a sequence of states actions and rewards to figure out the value of any given state the value of a state is the expected return when starting in that state and following the policy it's given formally by the following equation in some problems like say q learning we're more concerned with maximizing the action value function which tells the agent the value of taking some action while in some given state and following the policy thereafter [Music] remember how i said we can exploit the recursive relationship between subsequent returns well if we plug that into the expression for the value function we actually discover that the value function itself is defined recursively this is called the bellman equation from the first module and this is the quantity many algorithms seek to maximize the bellman equation is really an expectation value as it's a weighted average of how likely each particular sequence of states actions and rewards is given the state transition probabilities and the probability of the agent selecting that action much of the following material will involve coming up with various schemes to solve the bellman equation and evolve the policy in such a way that the value function increases over time in the next module we'll take a look at the explore exploit dilemma which is the expression of the trade-off between long and short-term rewards i hope this has been helpful questions comments suggestions leave them below i read and answer all my comments if you made it this far consider subscribing so you get notified when the rest of the course drops i look forward to seeing you in the next video welcome to module 3 of the free reinforcement learning course from neural net dot ai i'm your host phil taper if you're not subscribed make sure to do that now so you don't miss the rest of the course in the previous video we learned about a special type of process called the markov decision process there each state depends only on the previous state and the action taken by the agent this leads to the recursive relationship between the agent's estimate of returns at successive time steps this relationship extends to the agent's estimate of the value function which is given by the bellman equation as we covered in module 1 reinforcement learning for the most part boils down to maximizing this value function however it's not always so simple surprise surprise just like you and i have trade-offs in real life reinforcement learning agents are faced with similar considerations should the agent take the action that it knows will immediately provide the most reward or should it explore other actions to see if it can do better this conundrum is known as the explorer exploit dilemma and every reinforcement learning algorithm has to deal with this fortunately there are many solutions and we'll cover some of them here one such solution is the idea of optimistic initial values when the agent starts playing the game it has to use some initial estimate for the value or action value function this estimate is totally arbitrary but if you know something about the reward structure beforehand we can actually initialize it in such a way as to encourage exploration suppose we have an environment like our grid world and the video on creating our own reinforcement learning environment in that environment the agent receives a reward of minus one for each step and so the expected returns are always negative or zero no matter the state of the environment or the action the agent takes so what would happen if we tell the agent that the value of all the state action pairs are positive or even zero on the first move the agent picks some action randomly because all the actions look identical it receives a reward of -1 and updates his estimates accordingly so it's a bit disappointed it was expecting chocolate cake and got a mud pie the next time it encounters that state it will take a different action because the other actions have an estimate of zero reward for that state which is better than the negative reward it actually received this means that the agent ends up exploring all the state action pairs many times as each update makes the agent's estimate more and more accurate we never had to explicitly tell the agent to take exploratory actions because it's greed drobit to take exploratory actions after it became disappointed with whatever action it just took again this is called optimistic initial values another feasible solution is to spend some portion of the time choosing random actions and the majority of the time choosing greedy actions this is called an epsilon greedy strategy and it's the one we employ the most it's quite robust as we can change the random parameter over time so the agent converges onto a nearly pure greedy strategy the proportion of the time the agent spends exploring is a hyper parameter of the problem and we typically call it epsilon one potential strategy is to start out completely randomly and then use some decay function to gradually increase the proportion of greedy actions the agent takes the form of this function isn't critically important it can be linear a power law or really any other function whether or not the agent converges to a purely greedy strategy is going to depend on the problem for simple environments like the grid world where we know the optimal solution beforehand it makes quite a bit of sense converged to a purely greedy strategy however with a game like space invaders a popular environment from the open ai gym there are so many variables that it's hard to be sure the agent has settled on the truly optimal strategy the solution there is to leave epsilon at some small but finite value so the agent is occasionally taking exploratory actions to test its understanding of the environment all this discussion has made a very important assumption we've assumed the agent only uses a single policy the agent uses both the same policy to update his estimate of the value function as well as to generate actions there's no rule this has to be the case in fact an agent can leverage two policies it can use one policy to generate actions and then use the data that generates to update the value function for some other policy this is called off policy learning and this is precisely what we use in q-learning the agent uses some epsilon greedy strategy to generate steps in the markov chain which is the sequence of state action rewards and resulting states and then uses that data to update the estimate of the action value function for the purely greedy action in effect we're using an epsilon greedy strategy to update our estimate of the purely greedy strategy needless to say this works quite well and it's something we'll come back to in later modules when we get to monte carlo methods and temporal difference learning that's it for now reinforcement learning agents seek to maximize their total reward but face a dilemma of whether to maximize current reward or take exploratory steps with suboptimal actions in the hope of optimizing long-term rewards one solution is to bias the agent's initial estimates in such a way that it encourages exploration before settling on a purely greedy strategy another is to spend some proportion of the time exploring and the majority of the time exploiting the best known action and finally the agent can leverage two policies one to generate data and the other to update the estimate of the action value or value function in the next module we're going to get to dynamic programming class of model based reinforcement learning algorithms make sure to subscribe so you don't miss the remainder of this course and i look forward to seeing you in the next video welcome back everybody to machine learning with phil i am your host dr phil when we last touched on the open ai gym we did q-learning to teach the cartpole robot how to dance basically how to balance the pole in this video we're going to take a look at a related algorithm called sarsa so they're related in the sense that they're both types of temporal difference learning algorithms the difference being that sarsa is an on policy method and q learning is an off policy method hey appearance by the cat um if you if you don't know what that means i highly encourage you to check out my course reinforcement learning in motion on manning publications i go in depth on all this stuff in that course uh enough plugging let's get back to it so the other cool thing is that it that sarsa as well as q learning are model free meaning that you do not need a complete model of your environment to actually get some learning done and that's important because there's many cases in which you don't know the full model of the environment what does that mean it means you don't know the state transition probabilities so if you're in some state s and take some action a what is the probability you will end up in state s prime and get reward r those probabilities are not completely known for all problems and so algorithms that that handle that uncertainty are critical for real-world applications another neat thing is uh that this is a bootstrapped method meaning that it uses estimates to generate other estimates right so you don't need to know too much about the system to get started you just make some wild ass guesses and you get moving let's take a look at the algorithm so uh your first step is to initialize your learning rate alpha uh and of course that's going to control the rate of learning how quickly you make adjustments to the q function uh then you initialize the q function the q function is just the agent's estimate of its discounted future rewards starting from a given state s and taking an action a and it may have some assumptions built in onto whether or not you follow some particular policy or not but that's a general gist so you need to initialize your state and choose some initial action based on that state using an epsilon greedy strategy from that function q then you loop over the episode taking the action getting your reward and your new state s prime choose an action a prime as a function of that state s prime using epsilon greedy from your q function and then go ahead and update the q function according to the update rule you see on the screen and then go ahead and store your state prime into s and your a prime into a and loop until the episode is done again in the course i go into many more details this is just quick and dirty a bit of a teaser video to get you guys interested in the course and to give you some useful information at the same time so with that being said let's go ahead and jump into the code i'm not going to be doing typing on screen but i will be showing you the relevant code as we go along and boom we are back in the code editor so here i am using visual studio code um even on linux this is a great editor if you're not using it i highly recommend it adam was a little bit buggy for me and of course sublime is now is nag ware so go ahead and give it a look if you haven't already so we need to define a function to take the max action and that takes as inputs the q function as well as the state and you're just converting the um the q function into an array and to a numpy array uh for each action in that in that list and finding the arg max of that now recall that in numpy the arg max takes the returns the first element of a max so if you have two actions that are tied it'll give you the first one so of course in the cart poll example our action space is just moving left and right right if you don't remember it's just a cart that slides along the x-axis trying to keep a pole vertical of course this is a continuous space and the q function is a discrete uh a discrete mathematical construct right so the states are discrete numbers and so you have to do a little trick here to discretize your space and so if you look in the documentation for the cartpole example you'll find the limits on these variables and you can use that to create a linear space based out of it based on those limits and divide it up into 10 different buckets right so that way you get you go from a continuous representation to a discrete representation of your state space and then i define a small helper function here to get the state based on the observation it just digitizes these it digitizes those linear spaces using the observation that you pass in from the open ai gym and it returns a four vector that is a the buckets that correspond to the value of the element of the observation the main program we want to use small learning rate alpha 0.1 for a gamma something like 0.9 of course the gamma is the discount factor it's debatable whether or not you need it here so discounting in general is used when you don't know the we you don't know for certain you're going to get some reward in the future so it doesn't make sense to give it a 100 percent weight you could just as easily here use a 1.0 because the state transition functions in the cardboard example are deterministic as far as i'm aware some if i'm wrong please someone correct me and of course the epsilon for the epsilon greedy we're going to start out at 1.0 you'll see why here in a second and so you need to construct the set of states which of course just corresponds to the integer representations of our continuous space so you just have um ranges from zero to zero to nine and you construct a four vector out of out of that right so you have zero zero zero one one one et cetera et cetera et cetera and initialize your q function here i'm going to initialize everything as a zero right recall that we had to we could initialize it arbitrarily but for the terminal states you want that to be zero because again the value of the terminal state is zero and a is two in a range of two because we only have two actions move left move right whoops also i'm gonna run fifty thousand games if you have a slower computer you might wanna run fewer it takes quite a bit of time to run and i'm going to track the total rewards as we go along so just a little helper line here to print out the the number of games you're playing it's always good to know where you are right you if it stops chugging along you want to know if it's broken or actually doing something useful so you get your initial observation by resetting the environment get your state and calculate a random number and so you take a maximum action if the random number is less than one minus epsilon so epsilon is starting out at one so if random is less than zero otherwise randomly sample your action space done flag defaults and your rewards for the episode to zero then you loop over the episode until you're done and you go ahead and take the action a getting your reward and the new observation the state prime then is going to be the get state of the observation right these observation is a four vector of continuous numbers that we have to transform into a set of discrete integers a four vector of discrete integers then we go ahead and calculate another random number and choose another action based upon that then calculate sum up the total rewards and update the q function based on the update rule i gave you in the slides and of course set the state in action to the new the s prime and a prime and after each episode you're going to decrease epsilon because you want this you don't want the epsilon to be permanently one right you want to encourage some amount of exploration and some amount of exploitation so epsilon has to be a function of time and just save your total rewards when it's all done it's going to go ahead and plot it out and you should see something similar to the following i'm going to go ahead and run that now and that is going to take a minute to run and so here you have the output of the source algorithm after running 50 000 iterations so what you see is first of all a messy plot that's to be expected with 50 000 games when you're plotting every single point but what you notice immediately is that there is a general trend upward and when epsilon reaches its minimum epsilon goes to zero and it does a fully exploitative strategy the algorithm actually does a really good job of hitting 200 moves most of the time recall that 200 moves is the um 200 moves is the maximum number of steps for the cart pull problem uh because good algorithms can get it to to balance uh pretty much indefinitely so it would never terminate so the open ai gym just terminates at 200 steps so anything close to that is pretty good now one thing that's interesting is that it does have a fair amount of variability it doesn't actually balance it 200 moves the entire time and there are a number of reasons for this perhaps you can speculate below i invite you to speculate my thought process is that the the way we have discretized this space isn't sufficient to characterize the problem in such a way that the algorithm can learn something completely and totally useful so it just doesn't have enough information based on the ten thousand ten of the four yeah ten thousand uh states we've we've discretized it into uh and there could be other things that matter you know uh you could have other features for instance combinations of velocities and positions that matter so we could have under engineered the problem slightly but for just a quick little chunk of 170 lines of code or so it's actually quite good so uh any questions be sure to leave them below and hey if you've made it this far and you haven't subscribed please consider i'm going to be releasing more and more content like this i'm doing this full time now um and i look forward to seeing you all in the next video oh and by the way in the next video we're going to be taking a look at double q learning uh which is yet another variation of these uh model free bootstrap methods see you then oh and one other thing if you want the code for this i'll leave the code i'll leave the link to my github this is code for my course reinforcement learning and motion i'm just showcasing it here to show what you're going to learn in the course so go ahead and click the link in the description and it'll take you to my github where you can find that code as well as all the code from the course hope you like it see you guys in the next video welcome back everybody to machine learning with phil i am your host dr phil in yesterday's video we took a look at sarsa in the open ai gym getting the cart pole to balance itself as promised today we are looking at the algorithm of double queue learning also in the cartpole openaigm environment so we touched on q-learning many many months ago and the basic idea is that q-learning is a model-free bootstrapped off-policy learning algorithm what that means is model-free it does not need to know it does not need the complete state transition dynamics of the environment to function it learns the game by playing it bootstrapped in that it doesn't need very many very much help getting started it generates estimates using its initial estimates which are totally arbitrary except for the terminal states off policy meaning that it is using a separate policy other than it is using a behavioral policy and a target policy to to both learn about the environment and generate behavior respectively now when you deal with problems that uh when you deal with algorithms that take a maximizing approach to choosing actions you always get something called maximization bias so say you have some set of states with many different actions such that the action value function for that state and all actions is zero then the agent's estimate the q capital q of s a can actually be will actually have some uncertainty to it and that uncertainty is actually a spread in the values right and that spread causes it to have some amount of positive bias and the max of the true values is zero but the max of the capital q the agent's estimate is positive hence you have a positive bias and that can often be a problem in in reinforcement learning algorithms so this happens because you're using the same set of samples to max to determine the maximizing action as well as the value of that action and one way to solve this problem is to use two separate q functions to determine the max action and the value and you set up a relationship between them and then you alternate between them as you play the game so you're using one of them to determine the max action one of them to determine its value and you alternate between them so that you eliminate the bias over time that's double q learning in a nutshell the algorithm is the following so you initialize your alpha and your epsilon where alpha is your learning rate epsilon is what you use for epsilon greedy you want to initialize the q1 and q2 functions for all states and actions in your state in action space of course that's arbitrary except for the terminal states which must have a value of zero and you loop over your set of episodes and you initialize your state and for each episode write each step within the episode choose an action from uh using your state using epsilon greedy strategy in the sum of q1 and q2 so you have the two separate q functions so if you're using single queue learning you would take the max action over just one queue but since you're dealing with two you have to account for that somehow right you could do a max you could do a sum you could do an average in this case we're going to take the sum of the two q functions take that action get your reward observe the new state and then with the 0.5 probability either update q1 or q2 according to this update rule here and of course at the end of the step go ahead and set your estate to the new state and keep looping until the game is done so clear as mud i hope so by the way if you want more reinforcement learning content make sure to subscribe hit the bell icon so you get notified let's get to it so next up we have our code and here we are inside of our code editor again i'm using visual studio code to take a look at our double queue learning script i'm not going to be typing into the terminal i think that's probably a little bit annoying i'm just going to review the code as we go along if you have seen my video on the source algorithm there's going to be a fair amount of overlap because we're solving the same set of problems over again the only real difference is in that video we source it to calculate the action value function and in this case we're using double q learning again we have a max action function what this does is tells us the max action for a given state to construct that you make a numpy array out of a list that is for a given state both actions and as we said in the video we're going to take the sum of the q1 and q2 for a given state for both actions you want to take the arg max of that and recall in numpy the arg max function if there is a tie returns the first element so if the left and right actions both have identical action value functions then it will return the left action consistently that may or may not be a problem it's just something to be aware of and once again we have to discretize the spaces recall that the cart pull problem which is just the cart sliding along a track with a pole that is that must be maintained vertically right in the cart pole example we have a continuous space the x and the theta can be any number within a given range and likewise for the velocities to deal with that we have a couple options we could simply use neural networks to approximate those functions but in this case we're going to use a little trick to discretize the space so we're going to divide it up into 10 equal chunks and any number that falls within a particular chunk will be assigned an integer so you'll go from a continuous to a discrete representation of your four vector the observation along with that comes a get state observat state along with that comes a get state function that you pass in the observation and it just uses those uh digitized spaces excuse me just use those linear spaces to use the numpy digitized function to get the integer representation of the respective elements of your observation i've also added a function to plot the running average here i do this because in the sarsa video we end up with a little bit of a mess with 50 000 data points this will plot a running average over the prior 100 games next up we have to initialize our hyper parameters our learning rate of 0.1 this just controls the step size in the update equation the gamma is of course the discount factor the agent uses in its estimates of the future rewards so i don't believe this should actually be 0.9 i i left it here because it's not super critical as far as i'm concerned it should really be 1.0 and the reason is that the purpose of discounting is to account for uncertainties and future rewards if you have some sequence of rewards with a probability of receiving them then it makes no sense to give each of those rewards equal weight because you don't know if you're going to get them in the cart poll example the rewards are certain as far as i'm aware the state transition probabilities are one you know that if you move right you're going to actually end up moving right you know deterministically where the pole and the cart are going to move so it shouldn't be discounted as far as i'm concerned epsilon is just the epsilon factor for our for our epsilon greedy algorithm and that's pretty much it for hyperparameters of the model next up we have to construct our state space so what this means oh baby's unhappy the state space is of course the um the representation of the digitized space so we're going to have for the cart position you're going to have 10 buckets the velocity is 10 buckets and likewise for the thetas theta position and theta velocity so you're going to have 10 to the four possible states so 10 000 states and those are going to be numbered all the way from 0 0 0 to 99.99 that's all we're doing here is we're constructing the set of states next up we have to initialize our q functions recall that the initialization is arbitrary except for the terminal state which must have a value of zero the reason for this is that the terminal state by definition has a future value of zero because you stopped playing the game right makes sense you could initialize this randomly you could initialize it with minus one plus one doesn't really matter so long as the terminal state is zero for simplicity i'm initializing everything at zero i'm going to play a hundred thousand games the reason is that this algorithm eliminates bias but at the expense of convergence speed so you have to let it run a little bit longer uh an array for keeping track of the total rewards and we're gonna loop over a hundred thousand games printing out every five thousand games to let us know it's still running always want to reset your done flag your rewards and reset the episode at the top and you're going to loop over the episode getting your state calculating a random number for your epsilon greedy strategy you're gonna set the action to be the max action of q1 and q2 if the random number is less than one minus epsilon otherwise you're going to randomly sample your action space in any event you take that action get your new state reward and done flag and go ahead and tally up your reward and convert that observation to a state s prime then go ahead and calculate a separate random number the purpose of this random number is to determine which q function we're going to update you know we're going to be using one to calculate we're alternating between them because we have to eliminate the maximization bias right one is for finding the max action one is for finding the value of that action we alternate between episodes by way of this random number in both cases you want to collect the you want to calculate the max action either q1 or q2 and use the update rule i showed you in the slides to update the estimates for q1 and q2 as you go at the end of the episode sorry at the end of the step excuse me you want to reset the old observation to the new one so that way you can get the state up here and at the end of the episode you want to go ahead and decrease epsilon if you're not familiar with this epsilon greedy is just a strategy for dealing with the explore exploit dilemma so an agent always has some estimate of the future rewards based on its model of the environment or its experience playing the game if it's model free or a model uh problem right it can either explore or exploit its best known actions so one way of dealing with the dilemma of how much time should you spend exploring versus how much time should you spend exploiting is to use something called epsilon greedy meaning that some percentage of the time you explore some percentage of the time you exploit and the way that you get it to settle on a greedy strategy is to gradually decrease that exploration parameter epsilon over time and that's what we're doing here and of course you want to keep track of the total rewards for that episode and recall in the current poll example the agent gets a reward of positive one every time the poll stays vertical so every move that it doesn't flop over it gets one point and at the end you're going to go ahead and plot your running averages so i'm going to go ahead and run that and that'll take a minute uh while it's running i want to ask you guys a question so what type of material do you want to see from what i'm seeing in the data the the reinforcement learning stuff is immensely popular my other content not so much so i'm going to keep focusing on this type of stuff but are you happy seeing the sutton bardo type introductory material or do you want to see more deep learning type material right there's a whole host of dozens of deep reinforcement learning algorithms we can cover but i'm actually quite content to cover this stuff because i believe that if you can't master the basics then the deep learning stuff isn't going to make sense anyway right because you have the complexity of deep learning on top of the complexity of the reinforcement learning material on top of it so if there's anything in particular you guys want to see make sure to leave a comment below and hey if you haven't subscribed and you happen to like reinforcement learning and machine learning material please consider doing so if you like the video make sure to leave a thumbs up hey if you thought it sucked go ahead and leave a thumbs down and tell me why i'm happy to answer the comments answer your objections and if you guys have suggestions for improvement i'm all ears and here we are it is finally finished with all hundred thousand episodes and you can see here the running average over the course of those games as you would expect the agent begins to learn fairly quickly balancing the cart pull more and more and more by about 60 000 games it starts to hit the consistently hit the 200 move threshold where it is able to balance the cart pull all 200 moves of the game now recall this was with a gamma of 1.0 i'm going to go ahead and rerun this with a gamma of 0.9 and see how it does so burn this image into your brain and i'm going to go ahead and check it out with a gamma of 0.9 and see if we can do any better and we are back with the second run using a gamma of 0.9 and you can see something quite interesting here so it actually only kind of ever reaches the 200 mark uh just for a handful of games and then kind of stutters along actually decreasing in performance as it goes along so something funny is going on here and to be frank i off the top of my head i'm not entirely certain why so i invite you all to speculate however the what's also interesting is that i this is the second time i'm recording this i recorded it earlier and didn't scroll down the code so you ended up staring at the same chunk of stuff had to redo it and in that case i had a gamma of 0.9 as well and it seemed to work just fine so i suspect there's some significant variation here to do with the random number generator um it could just all be due to that right this is a complex space and it wanders around different portions this could happen potentially because it doesn't visit all areas of the parameter space enough times to get a reasonable estimate of the samples and there may be some type of bias on where it visits later on in the course of the episodes although that sounds kind of unlikely to me but either way that is double q learning you can see how the hyper parameters actually affect the model it seems to have a fairly large effect as you might expect and the next video we're going to be taking a look at double sarsa so if you are not subscribed i ask you to please consider doing so hit the notification icon so you can see when i release that video i look forward to seeing you all in the next video well i hope that was helpful everyone so what did we learn we learned about q-learning policy gradient methods sarsa double q learning and even how to create our own reinforcement learning environments this is a very solid foundation in the topic of reinforcement learning and you're pretty well prepared to go out and explore more advanced topics so what are those more advanced topics so right now the forefront are things like deep deterministic policy gradients which is as you might guess from the name a more advanced version of policy gradient methods they're also actor critic methods uh behavioral cloning there's all sorts of more advanced topics out there that you're now pretty well equipped to go explore these are particularly useful in environments where you have continuous action spaces so all the environments we studied in this set of tutorials have a discrete action space meaning the agent only moves or takes some discrete set of actions other environments such as the bipedal walker car racing things of that nature have continuous state spaces so excuse me continuous action spaces which require different mechanisms to solve q learning really can't handle it so you're now free to go ahead and check that stuff out if you've made it this far please consider subscribing to my channel machine learning with phil and i hope this is helpful for all of you leave a comment down below and make sure to share this and i'll see you all in the next video
Keep this transcript
Save it to LunaNotes and it becomes a real note in your library — editable, searchable, and ready to turn into flashcards or a diagram. Free to start.
Save to LunaNotesOr download subtitles for another video.
These subtitles were extracted using the Free YouTube subtitle downloader by LunaNotes.
Related videos
Download Subtitles for All Machine Learning Concepts Video
Enhance your understanding by downloading accurate subtitles for the 'All Machine Learning Concepts Explained in 22 Minutes' video. Access clear captions to follow complex topics with ease and improve your learning experience.
Download Recurrent Neural Networks (RNNs) Subtitles & Captions for Clear Understanding
Get accurate, easy-to-follow subtitles for 'Recurrent Neural Networks (RNNs), Clearly Explained!!!' to enhance your machine learning study. Download SRT captions to unlock every detail of this intuitive RNN tutorial for better comprehension and note-taking.
Download Subtitles for Complete RAG Crash Course with Langchain
Enhance your learning experience by downloading subtitles for the Complete RAG Crash Course with Langchain video. Subtitles help you follow along easily, support better comprehension, and make revisiting key concepts effortless. Access accurate captions to maximize your understanding of Langchain in just 2 hours.
Download Subtitles for Introduction to DaVinci Resolve Full Course
Enhance your learning experience by downloading accurate subtitles for the Introduction to DaVinci Resolve full course. Captions help you follow along effortlessly, improve comprehension, and make the tutorial accessible anytime, anywhere.
Download Subtitles for CLAUDE CODE Full Course 2026
Enhance your learning experience with downloadable subtitles for the CLAUDE CODE FULL COURSE 4 HOURS: Build & Sell (2026). These captions help you follow along easily, improve comprehension, and revisit key concepts anytime. Perfect for learners who want clear, accessible content at their own pace.
Most viewed
Untertitel für 'Nicos Weg' Deutsch lernen A1 Film herunterladen
Laden Sie die Untertitel für den gesamten Film 'Nicos Weg' herunter, um Ihr Deutschlernen auf A1 Niveau zu unterstützen. Untertitel helfen Ihnen, Wortschatz und Aussprache besser zu verstehen und verbessern das Hörverständnis effektiv.
ดาวน์โหลดซับไตเติ้ล DMD LAND 3 The Final Land Day 1
ดาวน์โหลดซับไตเติ้ลสำหรับวิดีโอ DMD LAND 3 The Final Land Day 1 เพื่อช่วยให้เข้าใจเนื้อหาได้ง่ายขึ้น และเพิ่มความสะดวกในการติดตามทุกช่วงเวลา เหมาะสำหรับผู้ชมที่ต้องการความชัดเจนและเข้าถึงข้อมูลอย่างครบถ้วน
Subtítulos para TIPOS DE APEGO | 6 DE COPAS Episodio 56
Descarga los subtítulos para el episodio 56 de la tercera temporada de 6 DE COPAS, centrado en los tipos de apego. Mejora tu comprensión y disfruta del contenido en detalle con nuestros subtítulos precisos y accesibles.
Download Subtitles for Harvard CS50 2026 Computer Science Course
Enhance your learning experience with downloadable subtitles for the Harvard CS50 2026 full computer science course. Easily follow along with lectures, improve comprehension, and access the content offline anytime. Perfect for students and enthusiasts aiming to master computer science concepts.
Descarga Subtítulos para NARCISISMO | 6 DE COPAS - Episodio 63
Accede fácilmente a los subtítulos del episodio 63 de '6 DE COPAS', centrado en el narcisismo. Descargar estos subtítulos te ayudará a entender mejor el contenido y mejorar la experiencia de visualización.
Found this transcript useful?
Take it with you. One click puts it in your own LunaNotes library.
Save to LunaNotes