Deep Learning 2: Introduction to TensorFlow

so hi i'm matteo the plant for today as
she mention is to introduce you to the
fundamental ideas behind tense flow as
well as give you some examples and some
tips that will help you while you are
doing your assignments and also give you
a demo of Kolob which is the environment
you will be coding your assignments in
and we will have some time at the end so
that you can try out Kolob and come to
us and ask us questions if you have some
issues with it and you have problems for
instance connecting to the backend that
actually runs the computation so what
then what is the fundamental idea
intense flow so test flow is the
framework there's composed of two main
parts so the first part is the library
it's a library that is used to define
computational graphs and the second part
is a runtime that allows you to execute
these graphs across a variety of
different hardware computational graphs
if you're not familiar with the concept
they are an abstract way of describing
computation as directed graphs and in
these graphs the edges correspond to
data to multi-dimensional arrays that
flow through the different operations
and the nodes represent these operations
we try to create these these data these
arrays and this these tensors or they
manipulate them according to specific
rules and so what's the advantage of the
of computational graphs and how do they
compare to a standard program so it's
not a program is mainly constituted by
two things is a collection of primitive
operations together with an order in
which we want these operations to be
executed and of course there are many
other things you might think you know
their functions or classes well all
these things are basically abstractions
and they are the most fundamental levels
this is really what the program is about
instead computational graphs are again a
set of collection a collection of
primitive operations but instead of
specifying the order of execution they
specify exclusively the dependencies
across these operations so how the
outputs of these operations flow from
one operation to another and this is
quite an advantage of representations
for reason I will be explaining shortly
so on the left for instance
can see a very simple program where we
instance a the variable we assign its
variable a value of 10 then we assign
and it we create another variable we
multiply them we take their sum we take
the result of these two of operation we
divide one by the other and we printed a
result it's a very very simple program
and the same the same set of operation
scales will be encoded in a more
abstract form in the site on the right
where we see as we have these ops these
operations which in this case create two
numbers and then the other combine them
in different ways and finally arisen in
operation that actually takes care of
printing and what's the advantage of the
second representation the one on the
right the main advantage is that we can
do dependency driven scheduling so this
means that operations that do not depend
on each other in any way can happen in
parallel can be scheduled in parallel
and this means that by using the
topology of the graph to drive the
scheduling of operations we can get much
better performance by exploiting at best
the capability of the our hardware so
for instance in nowadays each of you on
your laptop probably has 8 to 16 cores
and by representing your program and the
operations that you want to be executed
in this form you can easily assign the
the back end of 10 0 can easily assign
the different operations which do not
depend on each other on different cores
and just execute them in parallel so you
get really high performance with very
minimal input from the person who
actually writes the program so let's see
how you can define such a computational
graph saying again this extremely simple
example on the left you can now see the
test flow equivalent of the same program
so in this case we are defining a tensor
that is a constant of 10 and another
tensor which is a constant of 20 these
are two operations that generate these
pieces of data and then we define an
operation for each of the ones that we
had previously so the addition of these
two numbers their multiplication and the
division of the results
and the key issue here is that when you
execute the program on the left this
tensorflow program you know computation
is actually happening when you get to
the end of this sequence of programs you
don't have actually computed the result
of these about these operations you have
only defined and declared which
operations you would like to have
executed and then it's a separate step
the one of actually executing your
populational graph come performing all
these sequence of operations and getting
out results and this is different this
is the same difference between
declarative programming and imperative
programming and it's it's a difference
that can takes a little bit of time at
the beginning to get used to but that is
very powerful because it enables to do
very interesting things so in the pencil
terminology the operations these nodes
in this graph are called ops and the the
data that flows between these ops are
referred to as tensors and in general
these transfers will be basically
multi-dimensional arrays or tuples and
nested tuples of multi-dimensional
arrays so the one important thing is
that control doesn't just allow you to
implement simple computation graphs like
the one I showed you it actually
supports very general forms of
computation so it includes a stateful
conditional iterative and a synchronous
computation from first principles and
all these forms of computations are
directly enabled by specific inbuilt ops
which you can use and you can to define
these this type of conviction in your
graph so we'll have variable ops
these are ops that create allocate some
space in memory and then you allow you
to read and write values to these states
to this space in memory and these values
will persist across different executions
of this graph then we have conditional
ops which allowed to may allow you to
make the some part of the computation
conditional on the result of some other
parts of the computation so you could
depending on the result of certain part
of the graph either execute it some
portion of the graph or a different
portion of the graph
you have Lou pops these allows you to
efficiently specify computational graphs
which have cycles so you can for
instance have loops and iterate the same
alliteration until some condition is
satisfied all without leaving the
computational graph control ops allow
you to enforce or some additional
handcrafted order in the execution of
pairs of ops so in some specific cases
the data-driven dependencies are not
enough you might want to explicitly say
that before sum up executed some other
op must have completed its execution and
our specific ops that allow you to
specify these additional constraints and
finally our queue ops which allow you to
describe a synchronous computations in a
very clean and effective way so until
now all the exam the simple examples I
showed you only focused on declaring and
describing this computational graph but
every single dense flow program actually
is constitutive to parts so there is the
Declaration of the graph and then there
is the execution of the computational
graph or of some subset of the
computational graph and both these these
parts happen within Python so you have a
Python interference to tensor flow that
you can use to define computational
graphs as the TF graph objects and then
you have other Python utilities that you
can use in order to trigger and schedule
execution of these portions of the graph
through what we call a TF session so
let's start with the TF graph so the TF
graph combines and describes they hold
all the computations they have defined
through the through these abstractions
of ops and tensors where tensors are
just a description of these
multi-dimensional arrays that flow
between operations and you may have
shape and a data type but they don't
have actual values this is really the
most important thing that you need to
remember when you're writing test flow
when you define a tensor that doesn't
allocate anything in order there is no
actual computation going on and this is
very intuitive if you think of this
simple example so let's define it in a
mattress of
tricks of betray lien by a trillion
intense flow and in noon pi so if you do
intend tensor flow that is a perfectly
defined thing to do you can define a
matrix of zeros of a trillion by
trillion but until you try to execute
this op and therefore the back end
actually tries to instantiate to this
trillion by trillion zeroes everything
is perfectly fine well when you in a
standard scientific computing library
where you when you define a matrix of a
trillion a trillion that means that
you're actually instantiating that's
that amount of memory and it's just an
out of memory error so this this core
distinction between a declaring and
execute is really what you need to keep
in mind because these two parts live
within the same program because you're
using the same language both to define
and then later to actually execute one
interesting feature of the F graph is
that beside the accumulating all these
tens flops and tensors it also does what
we call shape inference so if you define
some tensors and then you define some
operations on them
the temporal graph will try as much as
possible to propagate shape information
across different tops so if I take for
instance the matrix of a 10 by 10 matrix
of zeros and I concatenate I can
catenate it with himself for her fall
along the first axis I get another
tensor back in this tensor even without
executing I can already asked the what
shape it has because tenth row will just
in fee infer the shape from the input or
from the input tensor and specifical so
this is the on the other part of test
flow so there's the sessions is our
interface to explore run time so the
part of tencel of the tensor library
that takes care of scheduling and
executing ops across your a different
hardware and you the a fashion carries
out is what carries out to the actual
computation and on the left you can see
a simple example of you visiting a
session to compute some to perform some
operations so we define a simple graph
again this is just defining three
tensors which are just constants and
then another couple of ops which add
the first two and then divide the first
two by deferred at that point when you
arrive to the fourth line no computation
has actually yet happened and then is
the the after the the comments there is
where we actually perform some
computation this is where we define it
you have session object and and then we
can ask this object to execute specific
portions of the graph in this case we
are saying session run the the tensor D
and the tensor D is the division between
the first two and the third and and
there is where the computation actually
happens and you can both request
execution of a single op so as in this
case or as you can see on the right you
can also request execution of multiple
ops at once
multiply request the evaluation of
multiple tensors at once and then it
will just trigger all the execution in a
single pass the when you when you speak
about sessions the most important thing
you need to remember is that tensorflow
identifies and executes the smallest set
of nodes which needs to be evaluated in
order to compute the tensors you are
requesting so in this case everything
need to be executed because in order to
know what the years you need to divide
the addition of a B plus C in order to
have a C you need to execute that
constant in order to a to get to the
addition of a and B you need to execute
both a and B so just by the natural
dependencies in the computational graph
by requesting an evaluation for a tensor
D you tends flow knows that needs to
execute the entire graph but in other
situations we have much more complicated
graphs this might not be the case so
when you request the execution of a
specific portion of the graph not
everything will necessarily be executed
so you will have maybe just a portion of
the graph to that gets executed which is
the minimal portion needed to evaluate
the tensor this rule comes with binding
for multiple programming language so
python is the main supported language
and the one we'll use in this course but
it's good to know for future reference
that there are you can actually
interface tense flow across a variety of
different languages so there is
C C++ interface and C++ is actually what
implements most of the back end of
tension and then there are go and Java
support although in experimental state
from the tense flow team as well as
support for other languages such as
Haskell and rust but which are supported
exclusively by the open-source community
and the choice of the language in which
you interface sense really is not as
crucial because so python is convenient
and we chose us for this course because
has a lot of open source support there
are a lot of other libraries for data
science and machine learning which are
implemented in Python but the the
language you choose to interface with
pipe do it tensile is actually just a
declared what you use to declare the
graph and to request executions from the
graph but most of the computation and
all the heavy lifting actually happens
in the highly optimized C++ back-end so
there the choice of the language used to
interface sense but it's not as crucial
for performance in many situations so
until this point we have seen different
constants and we have defined different
operations to be in different ways but
each execution of the graph would always
give you the same result because if you
take two times constant answers a and B
and you sum them every time you execute
that operation you'll get a give that
same result back variables are instead
the what enables learning by preserving
State across different executions of the
graph so all the part they're trainable
parameters of machine learning models
for instance will typically be TF
variables and variable is defined by a
name type shape and initialization
procedure so for instance you can
declare a variable as an example which
shows how to declare a variable called
width which is a matrix of floats with
two two by two and which is initialized
using just a random random normal
distribution with a specific standard
deviation and a mean of zero and once
you have defined these variables then
you can use them within your
computational graph and you can define
ops which update and modify these
variables within the
we're the computational graph so for
reading the variables and using them
within the compositional graph that is
very easy because you can just use them
as you would use any other tensors so
the variable V which we define in the
previous in the previous slide we can
just you for instance take the matrix
misil tration of that variable with
another constant matrix as in the first
example here in the slide so there you
can basically reuse them interchangeably
with tensors however you can also assign
values to these variables and then this
value will be maintained until the net
another update happens and the
assignments are also ops which are also
exposed by the object itself so you can
you basically have two different
syntaxes for doing assignment in the
first case you call a sign on the object
on the reference to the variable itself
and then you assign what another tensor
to it or in the second case you can
actually define call the library assign
up and just pass both the variable you
want to assign and the tensor you want
to place inside it so the finding a
variable adds the top to the
computational graph but again just like
with tensors a variable instance
actually exists and allocates memory and
hold values only in the context of a
specific session so if you have for
instance like multiple sessions and
let's use the same computational graph
the same variable might have different
values in the different sessions because
the variable definition in the
computational graph is just a
declaration that you have a variable of
a specific shape pipe and initialization
but it doesn't actually hold values
until you try to execute it in a session
one thing you need to remember is that
before using a variable in a session you
need to explicitly initialize it so you
need and you can do it manually but
there is also a shortcut to just
initialize all the variables in your in
your chrome additional graph and this is
an example suppose you have some
function create graph that defines your
big computational graph and this
includes the creation of some variables
then you can create an op with the TF
global variable initial
lasers that when executed initializes
all the variables inside your graph at
once and then once you have done that
there is where you can actually go on
and use these variables in order to
perform your computation there is also
an alternative so instead of
initializing the variables manually at
the beginning of the session you can
also rely on on the only money for the
session to do this for you so the money
for the session is basically a wrapper
around the standard tense flow session
that takes care of a bit of the
boilerplate code that otherwise you will
need to use in your graph one of the
things that does but it's not the only
one is initializing the variables so
because when you have declared all the
variables you have to have specified in
meta way of initializing then the the
monitored session can just go through
all the variables in their graph call
the appropriate initializer and do this
without you having to to do the
operation manually one thing you need to
take you to remember though is that the
monitor session doesn't only do the
initialization of the variables does has
others side-effects that you can see in
the documentation but the one of which
you must be definitely aware of is that
it finalizes the graph finalizing the
graph means that any attempt to create
additional ops and add the additional
ops to a TF graph after you have called
monitor session will actually raise an
error so if you if you need to first
create the all the computational graph
and then instantiate your monitor
session and use it to carry out the
computation any questions up to here
anything unclear
so variables are nice because now we
have enabled our graph to to express
much more general forms of computation
which the result of an execution of the
graph as tight as has an effect that
persists in future execution of the
graph which is important if you want to
do machine learning because you need to
for instance update the variables of
your model in order to improve the
performance of whatever task you are
trying to address but there is another
important thing in order to to to be
more general the important the second
important thing is that we need a way to
feed the data into the graph so if the
data set is very very small in principle
we can just embed it in the graph
definition itself so we could load the
entire dataset inside the new PI array
it's just a big matrix and then we could
define a TF constant which is enough but
if every time is executed we'll load the
entire array into and provide a few as
as a result however this is really not a
recommended way of doing this and this
is because for multiple reason but the
most trivial is that if the dataset is
of even moderate size you'll probably
run out of memory and also the whole
data set will be serialized every time
the graph is serialized
so if you store your graph somewhere
then also all the entire dates that will
be also be solved those saved within the
graph definition which is a very
inefficient way of going forward so
there is a different and better approach
to this so if you need to feed input and
data into your graph and you need this
data to change across different
execution of the graphs as it's very
standard machine learning where you want
to feed different inputs after every
update then you need to use placeholders
and feed dictionary these are two test
flow components that allow you to inject
data inside the graph and do this at
execution time so you use you define the
placeholder at graph declaration time
and you can use them within the graph
graph declaration just as if they were
other standard tensors but at each
execution of the graph they will take
a different value they will take the
value that you specify in the feed
dictionary that you pass the session
that run so this is a very simple
example again I define a placeholder
which is just a scalar it's a float and
if the scholar and that's all you need
to know for the graph definition then I
define another constant B which is just
a zero and I define an op which takes
these new numbers some sets and gives me
back yet another tensor and if now I
instance a the session and I run see if
I just run C without providing any value
for a this will give an error an error
will give you a runtime error because we
will tell you that it needs a value for
the placeholder in order to know what a
plus B is but if you instead if you
provide a feedback ssin area which is a
dictionary that map's placeholders to
numbers or new PI arrays then it will
actually perform the computation and
give you back the result you you wanted
so for instance if you feed a value of 3
for a you will get back 4 and if you
feed a value of 4 you'll get back 5 as
it seems the most reasonable so what are
the pros and of placeholders so using
placeholders puts the onus of managing
the data fully on you so tense flow
really doesn't care so it just expects
the dictionary of placeholders to numpy
arrays for each calls of session the
trend and all the rest is up to you if
you want to load the data somewhere from
file you want to pre-process it you want
to batch it in specific ways you want to
queue it all of this if you use
placeholder you'll need to do yourself
which is not a big issue because
typically this reduces to some math
matrix
gymnastics but it is is it is an
additional honours and additional
beaufort code that you need to to care
to take care of the advantages that
despite being a bit labor-intensive it
is very flexible you can literally
pre-process your data in any way you
want in noon pie in python land and then
just feed the data to tens flow for to
perform the computation of n for
instance the update of your model if you
don't eat however you don't always need
all these flexibility very often
the type of pre-processing and item
managing that you have to do is fairly
standard in that case tens flow up so
offers additional built-in
functionalities for working with data so
you have if you look up the F data this
gives you all sorts of utilities for
loading data loading data from different
types of sources files CSV files all of
this comes for free intense flow and if
you if your use case is not too unusual
then typically the loading of the data
will be take care appropriately by some
of the built-in utilities of tensorflow
ok so let's now all always seen up to
now was very very trivial example so
let's try to make it a slightly more
interesting and consider a simple linear
regression problem and keep things easy
we'll consider a univariate regression
which is the problem of learning some
function f from real numbers to other
real numbers and yeah please so the
definitely question but the answer is no
because when you serialize the graph you
serialize just the definition of the
graph so you serialize that there is a
placeholder which is a float and has a
emanates a scalar but this the value
that the feed dictionary assumes that's
not part of the graph definition that's
something you provide a front I'm and
might be different at each execution as
in this case so when you serialize the
graph the the placeholders are extremely
extremely lightweight because they don't
actually contain any data no no
so at graph definition yes you only
refer to it as the reference to some
specific as an I reference to some
tensor which is generated by this
placeholder and at execution time that's
where actually this placeholder needs to
have some memory allocation because it's
it actually is fed in some day some data
from the feedback
sorry but there is no additional like at
graph definition time there's no
allocation of memory in terms of for the
values of this placeholder so when you
need to just sterilize that you really
don't need about you don't need that no
so the answer is no again and the reason
is that the only things that persist
across the execution of the elf graph
are variables and though it's a bit less
common cues so everything else like
tensors do not have a value outside of
an execution of a session Letran so the
when you request execution of some
tensor then all variables are evaluated
all feed dictionary and placeholders are
evaluated and then the pests flow sweeps
through the graph computing all the
tents where it needs to give you back
that number and then it returns you at
number which you now have as a new PI
array in Python land and then the and
and nothing is persisted across the
state full components of the graph then
that will be fine so you could instead
of printing it you could say D equals
the result of session not run and then
you could say session of run see if e
Dictionary a D and that would actually
reuse the variable as he suggested any
other questions this
so the reason to use variables and we'll
see it very shortly but just to give you
a brief introduction you these variables
maintain values within the computational
graph itself so and they are available
for instance you know if you want to
compute gradients and derivatives of
some tense with respect to some
variables within the computational graph
then you cannot do it if if you if you
define it as placeholder because the
placeholders you cannot define gradients
with respect to placeholders so the you
really if you want to use all the power
of tense flows to computes gradients
perform optimization and all of that you
really want to store the stateful
components of your model within the
graph rather than in Python outside of
it sorry could you repeat is that so
what I was thinking of was something
like sorry some hey this where you
define the entire dataset as a huge
matrix so this will give you probably
run out of memory as you try to evaluate
this OP the advantage of doing it in
Python is that typically you won't just
define a huge moon pie array in Python
but you'll probably have some some way
of reading through the data and you
would probably read the portion of the
data set put into a matrix feed it into
tens flow then read another batch of the
of data from the data set put it into
metrics and feed intense flow possibly
using utility code that you can find the
open source for doing this in a
synchronous manner and this is allows
you to prevent the problem of running
out of memory anything else okay
so let's consider the simple problem as
I'm saying univariate regression aims a
learning function from real numbers to
other real numbers and to learn this
from data the key aspect of univariate
linear regression is that we assume that
that function is linear so there and we
in univariate case we assumed above the
input and the output are just a single
scalar what does it mean that it's
linear it means that there is this that
the data satisfies this relationship
where the output can be computed just by
multiplying the input by some scalar
value and then summing some offset
typically in the data itself this
relation will actually not hold so it's
it's rare that the data itself is
exactly linearly but for any big set of
pairs of inputs and outputs of where
both are scalars you can find values for
W and B in the linear relay in the
linear equation that minimizes the error
the mean squared error on your data set
so you can find a specific pair of
coefficients such that if you use those
coefficients to predict the output from
the input the average squared error on
the death set is minimized and if as
well and this is usually as often many
circumstances is enough because may be
that the discrepancies and the error
that you see comes just from random
noise in the data set and you don't
really want to fit all of that
necessarily so the linear function finds
the best possible trend that best
possible linear trend that explains the
data so in the in the univariate linear
case then you can actually find these
coefficient in just closed form so there
is an equation that gives you the best
values for both W and B for a given data
set the what the two values that
minimizes the prediction error under
this set and these are the equation you
can see in the second line if you if you
consider that X bar and y bar or just
the mean of the input and outputs
respectively this amounts to just
summing over the it set the product of
the difference between inputs and the
mean input and the output and the mean
output and dividing it by the variance
of the input
and there is a similar even simpler
equation for finding the coefficient B
this is very convenient because the
means that you can in one shot just get
out there is the best linear fit to your
data just by applying that equation
however it was also not a particularly
general approach so it works for linear
functions and linear linear models but
it doesn't generalize to big complicated
models so a more general way of solving
the linear regression problem which we
will generalize to the kind of models
we'll see and we will use in this course
is to use gradient descent to
iteratively improve our estimates of W
and B so many of you I assume will be
familiar with Wayne descent but just to
recap what you do at gradient ascent is
you update each parameter by subtracting
some fraction of the derivative of the
loss function in this case the mean
squared error with respect to that
parameter itself and this leads you to a
simple update rule for both wmb that you
can apply iteratively until convergence
until you you converge on some values
which are an optimal fit for the datum
and this kind of solution is great in
the sense solutions that it's variance
generalizes to problems where this is
the closed form solution doesn't exist
or it's too computationally expensive to
solve which is also a quite common use
case so in order to address this problem
with ten's flow first of all we need a
data set so let's consider a simple data
set where we generate data according to
the following rule here we basically
compute you take as a few inputs just
the equally spaced and then we we
basically multiply them by a coefficient
add some offset so this would give us a
perfect linear relation between inputs
and outputs but then we add some random
noise just some gaps in noise with zero
mean and unit variance just to introduce
a bit of of discrepancies in the data
and then the problem we will try to
solve in the next couple of examples is
how to minimize find the best linear
model to fit this data
so in order to do so first of all we
need to create simple linear regression
model so just to for to rap to a
separate the definition of the model
from the training of the model I have
here define the class it's a linear
object a linear class that when you
instance it that defines two variables a
variable for the coefficient and a
variable for the offset and these
variables can be updated within the
Tanner graph and will persist values
across the executions at the beginning
they will be initialized at zero and
until we update those values those
variables will maintain a value of zero
if we are during a session that run we
update these values to some other
variable to some other value then we'll
get some different linear model and the
linear model itself it's defined in the
call so once we instance it is object we
will call the object in order to
actually build the linear model and this
will be just multiplying that variable
by the input tensor and multiplied and
adding up the offset variable it's a
very simple model what we will do first
is now trying to solve this model in
closed form which will be a bit clunky
and then we will see how we can also
solve that with gradient descent in a
much more neat and efficient way which
generalizes to much more complicated
models so let's define the solver as
part of the graph itself just to make it
a bit more interesting what we need
first is two placeholders we need a
placeholders for the inputs and
placeholders for the outputs then we do
a instance in our model and we connect
our model to the inputs tensor to the
import placeholder when we call the
model on the input placeholder xdf this
call function has executed so we create
a tensor which is equal to the product
of the placeholder times W plus B we
then get back from the model a model
outputs tensor which will give us
predictions for each of the inputs in
the placeholder we can then define the
what the optimal values for WM be using
transposing the equation that we had
here just intense for a language so what
we need is just to sum and computes to
compute sums and computes means and this
is what we do with the simple code here
so this is the numerator to estimate 8w
and this is the denominator in the first
case we we take reduce mean in order to
compute the mean of the outputs or this
mean of xdf in order to compute the mean
of the inputs and then we multiply them
and reduce some to actually get them so
we can do the same or with the with the
denominator and gets out the tensors for
W hat and B hat which will be our
estimates of wmb respectively
this will be the WMV which minimizes
error in our input data which is not yet
defined in the tense flow graph so this
is function of what we feed in as tense
as the placeholders we can feed any data
and this intense row will give us back
the best W and best B and then what you
can do is always remaining in a fence
row graph also define ops that update
our model itself so we can define an OP
that takes the variable W and assigns
our best estimate for it and we can
define AB if I sign up that takes the
variable B and assign the best estimate
for it and this will give us and if we
execute in a session that runs all W and
solve B we'll get the solution to our
linear regression problem for every
given set of inputs and outputs pairs
and this is what we do in this example
so right here we are defining one if
your session so this is initializing all
the variable for free without having to
take care of it it's finalizing the
graph so we cannot anymore modify the
OPP's itself we can still modify the
values of the variables with during the
execution of the session that runs but
we cannot add the new components to the
graph and then we call session that run
on solve W and solve B feeding in the
input and outputs that we have created
an oompa using this simple code here
when we do this what we get is that the
the tense flow back end executes the
entire graph which we saw here because
in order to execute sold V in order to
assign it needs to know the value of W
hat and goes all the way backwards
Pearsall de Graaff computes the optimal
WMV and assigns it to the variable from
then on in all future execution de
Graaff until we actually call again
solve the W and solve B until we
actually change in some way the
variables of that model that model will
persist we'll keep those as values for W
and V so we have a trained linear model
that we can use to make predictions and
this is what we do in a second in the
second session that run where we
computed the model outputs for those
inputs to get to get a visualization of
what our model is actually representing
and this is the line you can see on the
right and as you can see it's a sensible
fit for the data we have of course it
cannot fit all of the inputs outputs
pairs because the data itself has this
Gaussian noise and it's not perfectly
linear but it does get person very
closely what the trend underlying trend
is any question up to here on this
example
yes exactly so basically what what tends
flow does is goes to model output which
is here and executes everything that is
required to compute model output and
solve W and solve B so they're
reassigning us variables is not required
in order to compute model out but
because model output is just this call
here it's W which is a variable which
persists this values across execution B
which is also a variable and X which is
just the current placeholder so all the
rest of the graph because it's not
required it's not required by any
dependency to be executed will not be
executed saving computation and giving
you the results you would expect yeah
that's a very good point
the ytf actually is not needed so
because you don't need ytf in order to
compute them out loud but it's not used
if you don't feed a value to the feed
dictionary the transfer will perfectly
will not explain or to request you to do
so so the only values that you will need
to provide in a fig dictionary is the
values for all placeholders which are
used to in order to compute the tensor
you are questioning in that specific
session not run you could define a
linear a linear model which has an
update method which thing basically
includes all of that code that's
perfectly fine okay so this is this the
example of how you would solve linear
regression with close for but really
this is not how you will ever train
models within this course so but it is a
good example or to start getting to
understand the how you can code then and
describe computation in Tesla so now
let's focus on gradient sense since this
is what we will be using mostly before
we going into there I want to point out
another huge advantage of using
computational graphs the SAPS of
representation and is and this is that
it allows you to very easily compute
gradients so if we know the gradient of
the output of an ox with respect to the
input of that hopper for every primitive
op which comes for free intense flow
then the chain rule provides us a way to
compute gradients for any tensor with
respect to any variable in the graph as
long as there is the dependencies
between those and the reason is that
computing some tensor from some variable
eventually amounts to some form of
compositions of functions so by just
using the chain rule you can end knowing
the gradients of the individual ops you
can compute the full gradient with
respect to the tensor to some other
variables whose possibilities used very
very far away inside the graph and you
can do this fully automatically so you
don't need to
your gradients while in this example we
didn't have gradients but we wrote the
solution to the problem manually within
the graph this is really not necessary
in most cases when you do gradient
ascent based algorithms because
tensorflow can infer and compute the
gradients directly from the structure of
the graph itself and the produce process
is known as reverse mode out to
differentiation and it not only allows
you to compute the gradient with respect
to a tensor and any variable in the
graph but it does so in a very efficient
way because you can do this basically in
a single sweep with a background forward
for the graph and and despite being
automatic and not requiring you to
actually describe it write down the
gradient manually it is not like
numerical methods because numerical
methods are a way of computing gradients
in an approximate way without writing on
the equation just by computing the
finished differences between evaluations
of some function while auto-da-fé is
actually giving you the exact gradients
the real true gradients just for free in
an automatic fashion so how does out to
different automatic differentiation work
as I said it's just an implementation of
the chain rule but it also has very neat
graphical representation you can map the
chain rule to basically very simple and
clean operation onto the graph so
basically if you want to compute that
the gradient of some tensor with respect
to some variable in the output let's say
a and B are the two variables if you
want to compute the greatness of this
with respect to a you only need to
compute the two accumulative lie
gradients along the path from from the
outputs until their variable you want to
compute the gradient for if however in
your graph there is a cycle sorry not
there is a cycle but there is there are
multiple paths that lead to the output
tensor you want to compute a gradient
for then you need to multiply along the
paths and saw some where paths join and
this is basically just the chain rule
but it's it's graphical representation
and you can do so as you can and then
you can immediately see that computing
and the gradient fooders for this tensor
respect to any of the variables just one
for in a backward pass for the graph
any questions on this please it depends
on the values you fit into it so it will
multiply the gradient with respect of
this with respect to this for the same
put times the gradients of this with
respect to its input for that Val
specific value that gives you all
gradients in a single path pass through
the data you just do it forward then you
do a backward and you have all gradients
and you reuse all the computation like
the evaluation of this node is needed
both if you want to improve the
gradients with respect to this then the
gradient with respect to this and if you
go backwards you can just reuse all
there is if you're computing and do it
in a single nice sweep well foreign mode
is a bit more convoluted so this is a
typical form of people use it's it's
basically also what back propagation is
all about
of course it's perfectly valid to also
just write down manually the derivatives
and just there and compute all the
equation and write down that as as as
part of the graph itself and then apply
the gradients that's that's not wrong in
any way they give you exact same results
the advantage of this is that if your
model is huge and very complicated doing
all that of manually might not be
particularly complicated by it's very a
lot of computation very boring and you
probably might get the wrong at some
point and then all your results will be
off well if you do this you can you can
rely on the on the well tested
asthmaticus translation tool to just
infer from the structure of the graph
itself what the right gradient is which
is convenient for big complicated models
so how does this actually happen intense
flow so what happens is that pencil OTF
gradient function constructs that sub
graph that implements
in a specific way the the absurd
differentiation and the next thing is
does this in a fully transparent way so
what the only thing you need to do is
called TF gradients and specify the
tensor and the variables you want to
tent the to compute the gradients with
respect to so this could be a the list
of all the variables of your model this
could be the loss function and then TF
gradients would give you back the
derivative of the last function with
respect to each of the variables and so
if so grads will be a list of tensor
which has the same length of variable
lists because you'll have a gradient for
each of those variables and one thing
you need if the tensor does not depend
on one of those variables then that
entry will still be present in rats but
will be none so it will just figure out
that there is no dependency between the
two so there is no gradient defined for
heard that tensor we respect that
variable and just return you a none for
that specific entry and finally if my
tensor is a multi-dimensional tensor
what happens is that gradient is summed
along those dimensions so you don't get
the Jacobian you get the summed version
of it so we can also define the gradient
descent solver as part of the graph and
in this case what we need to do is to
execute an update op repeatedly until
convergence and the graph we saw before
was much more complicated while here
because we are really exploiting the the
core functionalities of tens flow we can
get this very clean and very simple
update rule with a fine loss function as
the difference between a model output
and the outputs in the placeholder then
we define the gradient of the loss with
respect to the variables and then we can
just assign the hard-coded expression of
the gradient sense so the current value
of the variable minus some fraction of
the gradient where def number 0.001 is
what we typically call learning rate we
can also group these so we can create an
OP that when execute excuse both parts
and then calling this and actually
training your model is just repeatedly
calling that update op so every time you
need to feed the placeholders and call
date and you can do this I don't know
500 times and if you log and if you
print the various predictions along the
way for a few different a few different
steps you can see that the the
prediction start just with a random
slope and random offset and then slowly
start to move up and align correctly
with the underlying trend in the data so
there is also an alternative so then
this is already pretty clean I think you
you will agree is definitely much much
cleaner than it was defining close form
solution but you're still doing a quite
a bit of boilerplate code which is
fairly standard like just a plot taking
that gradient and assigning it to the
variable one by one so what you can do
and you should do is use test flow
optimizers so instead of manually
computing the rains and applying the
updates you use these high level
components which in aryl are subclasses
of this trainer EF Train optimizer which
implement all sorts of different
optimization processes so you have TF
Train gradient descent optimizer where
you just specify the learning rate and
or you can define other gradient descent
optimizers that are more that are much
more effective in practice such as
rmsprop or atom optimizer these
additional these different optimizers do
things like momentum or some forms of a
slightly second-order optimization and
you the Tesla really gives you a lot of
different built in optimizers to play
with and that makes a massive difference
when you have to actually train in
practice big neural network models so
before I go to the next topic any
questions up to here sounds good so oh
yeah
TF group is just an open circuit it
x'q like if you request evaluation of
update in a session that run then test
flow will actually is like requesting
execution of those
it's just a way of instead of doing
session the front update W update B you
can just say session that run update
okay so control logic so up to now we
have seen stateful computation we have
seen how we can define these
computational rafts and have them
persist values across different
executions but there is more to
computational growth to transfer the
computational graphs so what we can do
is also support conditional and
iterative computation as well as
specifying additional control
dependencies so up to now all the
dependencies were purely the one that
were driven by the data itself like one
op was using a specific tensor in order
to compute his output and therefore had
to wait for that tensor to be available
in order to be executed and everything
that didn't depend on each other would
execute in parallel potentially and
would be scheduled by the temporal
backend in order to maximize performance
but without any specific prescribed
order with control dependencies what we
can do is add the additional dependency
so we can say first do this and then do
this other thing you don't need to
specify a full ordering of all the ops
but you can add the specific
synchronization points by using these
control dependencies if you have
constant the FK is allowed to specify
conditional execution so if the
computation of this part of the graph
gives you some specific value then
execute this otherwise execute something
else and while loop allows you to write
cycles within the dense flow graph
itself so let's take a simple example we
define a variable with zero
initialization we define in a sign up
which add which assigns 10 to that
variable we define in a tensor that sums
one to the variable X and then we
execute Z within the monitored session
what do you think will be the output
any idea
any brave person there is an obvious
answer the obvious answer is with the 11
and the actual answer is one so the
reason is is that you need to think
about dependencies we have asked to
execute that that is equal to X plus 1 X
is a variable which is initialized to 0
0 plus 1 is 1 there is no reason by
which assign X should be executed in
this computational graph we have not
requested it it's not is output is not
used anywhere so Tesla will find the
minimal subset of nodes and needs in
order to compute that and just return
you that what you can do
maybe it's do this what if I do a sine X
and said what will be the output of this
code 10 and 11 the answer will be either
10 + 1 or 10 or and 11 why is that
the arena's in is that when you call a
session that run with a list of tensors
the order in which you pass this tensor
doesn't matter 10 Cyril is not first
assigning calling assign X and then
assigning Zed it's taking all tensors
that you pass the session at run and is
doing one pass through the graph and
trying to come and scheduling everything
as fast as it can
so depending on on just a race condition
it might first execute a sine X and then
someone or first execute someone and
then assigned first do 0 plus 1 and then
assign 10 because there is no dependency
these two things now we are asking for
both but they're still note nothing
that's prescribes in which order they
should happen so they might happen in
any possible order what you can do if
you want to specify an order is do this
you can say will control the pendency of
an assign X to X plus 1 this means that
if you ask even only for Zed tensor will
know when it tries to compute said that
before doing whatever is in this block
it must evaluate assign X will execute
assign X
assign a value of 10 to the variable and
then someone and now you actually get a
deterministic
output of eleven so anything any
questions I guess there will be sorry
[Music]
yes that would be a valid way of doing
it so if they assign variables actually
perform an assigning of the variable and
also return you the new value so if
instead of if here instead of saying is
that equal X plus one you would say Z
equal a sign X plus one then it would
first compute a sign x returned your
value of ten and then someone and will
also give you the terminus take output
conditional evaluation so this is what
you need in order to make your
computational graph conditional on other
parts of the computational graph so you
have the PF Condor and this enables the
makes the execution of whatever you
define in these two function conditional
on the on the output of the of the
switch in this case so what does it mean
it basically DF con takes a condition a
boolean tensor and two functions where
the two functions define the graph that
you want to execute if the boolean
tensor is true and the graph you want to
execute the bull and tensor is false so
if you do this you define two variables
you define a placeholder for a switch so
we can feed the true or false when we
call session that run at leisure then we
define it you have cond which returns
you the output of assigning V 1 1 to V 1
or the output assigning 2 to be 2
depending on the value of the switch if
then we call session that run and cond
and then we print the resulting values
for W for V 1 and V 2 what we'll get is
as you would expect to the Sun that's V
2 has a value of 2 because because we
have said that switches false it didn't
execute this part of the graph it only
executed the second part of the graph
defined by that lambda lambda and so you
get the value you would most likely
expect however there is a more fun to
this because you might think okay
do an innocent refactoring and I'll just
create these assign functions here and
then I have a lambda just returns that a
sign up if you do this what do you think
will be the output sorry
so that would will be that they both are
true the execution of both R is
triggered so what happens is that all
the code that you want to be executed
conditionally should be created by the
function you pass through the TF cond in
this case the function we pass so if you
have cond is not creating anything the
OP has already been created outside and
this means that this two ops are a
dependency of the f-con and this means
that if there are a dependency of the
Afghan before executing before even
checking that condition transfer will
execute both of them because they're
both dependencies that must be executed
so both v1 and v2 will be assigned the
value and then it will check the switch
and will return you v2 in this case
because the switch is false so it will
return you only the second but will also
execute the first and in this case
because the the graph we're creating is
actually an assign up this will have
side effect that will persist in other
cases if you don't have variable
assignment within the TF cond having
dependencies that are not created within
the function but outside will only be a
waste of computation but if you have a
sign ops it will actually change the
result of future executions no they are
run if they are dependency of something
else so they are run if they are used
within something else so typically in
most tops that it means that they are
used their value is directly used by in
the case of TF cond this means that
their value is potentially used and and
that's enough to trigger execution
unless you created within that function
and then it knows that it actually
has to executed only in one or specific
case you can also have cycles in the
graph so have iterative computation
within your computational graph and so
if you let's see how this works so this
can also be a bit tricky but it's very
useful in a variety of situations
so let's go through this code in a bit
more detail so we define a constant of
two and we define a matrix this is just
a matrix of ones and we define a
condition so this condition is the graph
that will be executed to evaluate if you
need to do another iteration while the
body will be the graph that is executed
at each iteration and both the condition
and the body will be passed to the same
tensors it just happens that they
conditionally you looks at one of them
so I put an underscore there and then
you define a while loop by specifying a
by passing condition body and initial
values for the loop parts the loop VARs
are the variables that will be passed
both to body and and the condition at
each cycle and that's at the beginning
they will have a value of 0 and just a
diagonal of 1 so what what happens if
you execute this code what you get is
that for K times because a at each
iteration this while loop will multiply
the diagonal by the matrix m so we'll be
basically raising to the to a power by
multiplying multiple times with itself
and then finally when the when the loop
var I gets to about this K then it exits
so the while loop will return you the
final value for I and the final and the
multiplication of the map that matrix by
itself for K times this might seem a bit
too concrete example why and how on
earth you would do what you do test
so the Reno zone is that this is very
very common and useful thing to do in a
variety of situation where you have
sequential data data you want to not
process a single sample like in standard
supervised learning or
you have you know iid samples and just
go go through them once and each of each
update each evaluation or the sample is
independent by each other you have
situations where you have time series or
you have language you have that you have
the the way you don't want to process
one input depends on how you process the
previous input in this case you want
maybe to keep around the outputs of the
previous computation and you want to
reuse it and you want to iterate maybe
for a variable length so maybe you want
to process one word at the time until
the end of the sentence and you don't
know in advance how long the tell how
long the sentence will be in this case
you need a way to just perform this
computation for multiple times until
some conditions satisfied and this is
where things like a wire loop come come
handy however the while loop is fairly
low-level so you don't always need to go
all the way down to that tense flow
typically exposes both very low-level
API is very low levels utilities that
are extremely flexible and allow you to
do basically anything you want as well
as providing a lot of the built-in
function and built-in code that takes
care of all the most common use case and
the most standard situations and this is
also the case for here for these cyclic
and iterative computations so what is
the the standard setup when you do this
kind of iterative computation in deep
learning and in machine learning the the
standard situation is that you have some
transformation which we typically speak
about as a core and which you apply your
course of lis to some state which is
which is what persists and is
accumulated along the way so the core is
a transformation it's a piece of graph
that applies some transformation in this
case is multiplying the input by some
matrix the state is what is accumulated
along the way so then the previous
example is the cave power of the matrix
and and the third thing that we
typically have in in in deep learning or
enforcement is we also output things
along the way so after each each time we
take the previous state we apply the
transformation
we get the new state and we get some
output maybe the best guess at that step
of the of the processing and this like
this is the situation the same pattern
applies across the deep learning in when
you do time series prediction sequence
to sequence models but applies to
reinforcement learning where you have to
take decisions in partially observable
domains so if you have a you know a
personal learning you have these agents
which must learn to perform some tasks
and act in some environment and in some
cases the environment is fully known to
the agent agent just sees everything
there is to know and to see at each step
in this case it doesn't really need to
memorize anything it doesn't need to at
each step can decide based only on his
current information but in most
interesting domains this is not the case
you have maybe you have a first-person
view so when you look in some direction
you don't see what is happening in the
other direction anything you need in
order to know what to do while you're
looking in this direction need to
remember what the world looks like when
you are looking in the other direction
so you need to have this acutely this
persistent state which you accumulate
along the way in order to take decisions
in a partially observable domain however
also in their enforcement learning case
the same pattern works perfectly fine
you define a transformation which takes
a previous state and outputs a new
output and a new state and this is why
test will give us the specific utility
for this this use case because it's
really what they're the most common that
you will encounter it so in order to
give you an example of this let's take
something that most of you will know
pretty well which is the Fibonacci
sequence
so the fibonacci sequence is a very
simple sequence of integers where each
element is the sum of the previous two
so the first two elements are 0 and 1 so
the third element is is sorry
so the first island each element is sum
of the previous two so free is the sum
of 2 plus 1 5 is the sum of 3 plus 2 8
is the sum of 5 plus 3 and so on so
forth and you can just generate all
these sequence by just applying the same
rule to this persistent state that
you're moving forward because if you
keep a memory of what are the last two
you can just go on and on and on yeah
yeah there is a what started is there
and so what the what does the
transformation you're applying look like
this is you as we said is defined
typically in in the intense flow terms
by a core so a core is something that
takes an old state and gives you an
output and a new state so and what does
this core what does this transformation
actually do so you you define that you
the old state has the previous two
elements the outputs is just the sum of
those two elements and the next state is
the new output and the second element
from the previous state this is a very
simple transformation you take the last
two you drop one you sum them and you're
cumulate in front and how would you
implement this intense both there's
actually fairly easy what you need to do
is define a Fibonacci core if you want
actually core is something that has now
to precise at one of one at each step it
always gives you the next number in the
sequence and has a state size which is
actually has two dimensions because you
have the pre you need to remember the
previous two elements in order to
continue and what we do is then we can
define the core the same equation we had
defined in pseudo certain settings to
the code before just like this so we
return the sum of the two elements of
the state this is the outfit at each
state and the new state which is just
the second element of the state and the
new one then we can define the zero
state and the initial state this is what
we need in order to for the tensile
utilities to work appropriately and then
what you can do is just this you you use
the dynamic here and then you specify a
Fibonacci core you specify some inputs
which we don't really care about and
pipe floats
time major this just specifies whether
you want the bachelor mansion or time
demand
this is some technicalities which you
can look into more details later but the
the core thing I want to show you is
that just by defining the core then you
can get the unrolling for free and this
happens dynamically and in a very
efficient way just out of the box and if
you just run the TF dynamic RNN with a
specific core then you get the sequence
you would expect yeah yeah and as you
see here the input is not actually used
but the the dynamic hernán expects you
that you take input because when all
practical situations you won't just be
updating the state without looking at
the world you'll typically be feeding as
input I don't know the last observation
in Reverse my learning the last word
that you read in natural language
processing or the last time step in
sometimes years prediction right that
would be what yeah that would be one way
of doing it for instance yeah okay so
these are really the core
functionalities and slow ones we went up
to now
however test flow is really really
powerful and huge library so there are
that supports a lot of things because
once you embrace this paradigm of
declaring and then executing through a
through a runtime you actually can do
much more like much more things that for
just for free so what happens is for
instance that multi-threaded execution
this we partially already discussed
happens for free everything that is not
has not a dependency on each other hence
role will just try to execute it as fast
as possible if your computer has eight
cores and there are two things that can
happen at the same time it will just
schedule it on two different cores and
get there for good multi-threading
taking a totally transparent way you
don't need to say okay create this
thread manage this thread test row gives
you multi-threading out of the box just
by the fact that is using this
computational graph abstraction but emit
less obvious because we didn't mention
it yet is that test will actually
enables you also transparent execution
across different types of hardware so it
doesn't only support multi-threading it
also supports the Terrigen is computing
so you might execute some part of on the
CPU some part on a GPU some part on the
FPGA some parts on some other crazy
device because the the abstraction
itself is agnostic to this like you
define a computational graph it's a very
very abstract view of the computation
you need to do and then pencil what what
does this give you it gives you simple
ways of annotating this graph and just
saying this op should be on this device
this op should be on the Sutter device
and then the TF the TENS flow backend
takes care of actually doing all the
scheduling across the different devices
another final really interesting
advantage of tens flow it transparent to
this distributed execution so you the
same computational graph just by
annotating you differently
you can execute across multiple machines
and then the test world they can will
also take care again fully transparently
of communication across the machines you
all don't have to have do do RPC calls
yourselves
you'll just specify where on what
machines the different ops live and then
stencil will it will make will send the
data back and forth and just take care
of that computation and this is
extremely powerful if you want to deploy
some huge model maybe in production and
you want across multiple machines and
and this is especially powerful because
one of the things that you can do for
instance in a distributed way is the
training of the model so you could have
multiple machines each of which is
sampling a batch of computing gradients
and then these gradients can be applied
in a distributed way to a shared set of
variables either in a synchronous or in
a synchronous way times flow supports
both in basically out of the box
so just to give you an idea of what we
what I mean by annotating your graph
annotating your graph means basically
just putting these blocks where you say
with pf' device create these ops all ops
created within a TF device block will be
placed on that specific device in this
example I'm just telling that I want
those constants to live in the CPU like
the creation of those constants to
happen on the CPU and the matrix
multiplication I wanted to happen on GP
and that's all you need if you are a
computer if your test flow is built with
the with GPU support and you have a GPU
in your in your machine that's all you
need you will execute this code and it
will pick the appropriate device based
on the annotation you made this config
has to the TF session this is just what
you need to do if you want to log what
you are actually where the different
tops are actually being executed the at
Estoril will send the data from the CPU
to the GPU and then perform the
operation I'm not claiming that this is
you know a good split of the two things
it's just to give you an example of how
you can separate out things yeah in that
case the GPU will probably you will
probably not be able to execute that
operation on the GPU there are however
ways in which you could do it for
instance you could have that your data
is so big because it's it's a big batch
of data in that case you might execute
half of the batch on one GPU and half of
the batch in another GB and then just
join the outputs of the two things so
there are ways you can then split this
up the computation between but if it's a
single like monolithic matrix
multiplication then it's and that's much
rubric creation is so big that cannot
fit on a GPU you are a bit in trouble
that that's kind of not really tensor
flow transfer issue it's more although
there are specific ways in which you can
still do partitioning but are much more
complicated
than just splitting the batch so what
will happen if I just do this so what
happens is that you don't need to
annotate your your graph so tens flow by
default who has an automatic placement
procedure that will try to do his best
according some heuristic and what it can
cannot do to assign the different tops
to different devices so in this case it
will definitely put on the CPU those two
but then if your GP if your computer has
a GPU and you have built tens flow with
GPUs then this operation will actually
be scheduled by default on the GPU even
if you dont annotate it my pen slow
tries to schedule as much as possible in
the GPUs if instead you don't have a GPU
then it will just schedule it on the CPU
and that's that's it so there is also an
automatic placement system and that's
where this config configuration comes
handy because we can just inspect where
tens decided to boot ops because
sometimes they might decide to put on
the GPU some operation which are fairly
small and don't scale well and are
actually better executed on the CPU so
it's good to if you don't specify
everything yourself is good to keep an
eye on we're we're thankful is actually
placing the different operations so
already in core tensorflow there are two
levels so there are both low-level
utility functions and there are higher
level functions like the dynamic RNN
utilities to enroll cores
there is actually quite a few core tools
and libraries built inside tens flow but
there are also a host of different
neural network I bred for instance built
on top of tensorflow at a much higher
level of abstraction which you can use
in order to exploit all the power of
tens flow while maybe making it a bit
less boiler practicode and much simpler
to reason about so just two examples for
future reference one is SONET and one is
Karis sonnet is the the neural network
library we use in deep mine and it's now
open source caris is a neural net to a
library which supports multiple backends
you can use ten back-end you can
use tor chose back-end you can use Tiano
I think as back-end
and however in this course we will ask
you to actually build your necklace with
the row tents for not using and not to
use these higher level libraries because
even if you do eventually use these
higher level libraries and we do all
every day indeed mine understand the
core functionality of tensorflow and the
lower level is important in order to use
them in the appropriate and correct way
so I'll just give you a couple of data
points about SONET specifically so SONET
is the tenth floor library with two main
aims the first is give you a reference
implementation and well-tested
implementations of a variety of deep
learning modules and architectures and
the second is provide you out-of-the-box
easy sharing of weights across modules
so there are lot of situations where you
want to reuse the same weights in
multiple places and this can be a bit
tricky if you if you don't if you don't
have a library that does this for you
because you need to construct the same
graph in two places but we're using the
same variables and it can be a bit
boiler plating so sonic gives you this
out of the box by embracing this
configure then connect paradigm which is
also what I was I had used in this
simple example so in the linear in the
linear model I have this configure and
connect exam pursed I created the
variables and then I called the object
in order to actually create the graph
that performs the computation and so on
it gives you this follows this exactly
the exact pattern and the only thing you
would need to do in order to change that
into a sonnet module is inherit from
abstract module and then you can
actually free free you don't really need
to enunciate things there separately in
an init you can just use this inside the
definition of the graph itself and then
sonnet because you are in everything
from abstract model will take care
behind-the-scenes of actually making
sure that it doesn't create different
variables every time but every time you
call this object it
creates a new graph but that shares
variables with all the previous one
that's convenient when you need to share
variables effectively and finally before
switching to coal I just wanted to point
out that nowadays there are many deep
learning frameworks available there is
torch and PI torch so these are two
different interface to a common back-end
in Lua and Python respectively
there is chain er which is also in
Python cafe which is C++ and PI 2 in the
interface and piano which is similar in
some ways to tense flow but the laughter
is not supported anymore but it was
maybe in some way the most a precursor
of tensor because it follows a similar
declarative approach in which you define
the graph and then this graph gets
compiled into execution and all of these
have pros and cons and share quite a lot
of features and have some differences
and in terms of raw performance depends
a lot on the models on some models will
run faster on some specific back-end
some will run faster with others but if
you're speaking about single machine
it's probably comparable many of these
what tends flow gives really an edge one
is if you want to really not just play
play with the model and prototype it but
once you have the model just scale it up
you want to put it in production you
want to scare top across thousand
machines like it basically gives the old
death for free so all the distributed
and the the multi-threading the
parallelism of the different devices all
that is extremely transparent to the
users so really enables you to go from
just simple prototyping to actual
production code really easily so now
that's it for the first part and now
Alex will be talking about Kolob and how
you can use it in order to do the
assignments of this course is there any
final question you'd like to ask on this
part
so the next 20 minutes are going to run
you through collab which is what we're
going to be doing all the assignments in
for this course and what you're gonna be
using largely to develop when you're
running a tensorflow
so can I get a quick show of hands is
anyone used ipython notebook before or
Jupiter notebook okay great well we're
coming from a pretty good running start
then we're still going to go through
everything just slowly to make sure that
everyone has it
so what collab is is essentially what we
use internally to develop tensorflow and
also to do a lot of research at Google
which is our own hosted version of
ipython notebook so you can use if
you've got your laptop's here you can
use it to run along as I do these or you
can just watch it and we'll have some
time at the end for you to go through
and do it yourself you can access this
by going to collab dot research
google.com I just mentioned you're
actually very fortunate because this has
only been released by Google essentially
at the end of the beginning of this year
and it's a really really excellent tool
having this hosted to start off with you
can sign in using you should be able to
sign in using your personal accounts and
you'll be able to connect to a back-end
but for some of the later assignments
where you're going to need more
computing resources you'll be explicitly
whitelisted to give you more resources
so that you can actually train some of
these more sophisticated models we're
going to be looking at so you can be
hosted with Python 2 or Python 3 I would
recommend generally in PI 2 because even
with transfer this is still better
supported that you have the opportunity
for both and this is a kind of thing you
can be presented with when you log in so
we've got this signal here says that
you're correctly connected to the back
end which is going to happen
automatically for you but if it is
disconnected for any reason you can just
real quick on this item
it'll reallocate you a server on Google
cloud and will reconnect you to your
tense flow backend I'll probably skip
through this a little faster since most
people are familiar with ipython
notebook but to give you a general idea
everything here is either a code cell or
a text cell for the code cells you can
run anything that's Python you can run a
few extra functions that we'll see and
you can also run direct shell commands
which is going to allow you to install
other libraries on the computer if you
actually need to do that so in order to
run a cell your options are shift enter
or control enter or using this play
button on the side and then the output
from the cell okay so you can see here
that I'm actually not connected to the
runtime in this echo lab notebook so I
can just click on next and now I have my
back-end this should be able to run and
very obviously we get 10 text cells also
work very similarly to an eye Python
notebook these are very very useful I
would get in the habit of using these to
comment as you're going along this is
also helpful if you're working with
other people I mentioned that one of the
things that makes it particularly good
and the reason it's used at Google over
I PI third notebook is that you can
collaboratively work on this this is
where the name collab comes from so if
this link was shared with somebody else
then we can both work on the notebook at
the same time leaving some text cells
around is going to make your life a
little bit easier and you can also put
in latex which is again more important
when we're starting to be implementing
formulas intensive flow again pretty
basic but if a cell is running long you
can cancel it halfway you can also
restart the runtime so sometimes $0.10
tensorflow is running at a lower level
than Python it can hang in a way that
you won't be able to stop it through
this
if that happens go to runtime and
restart the runtime and that will give
you everything from scratch you lose all
the save state because that actually
resets the Python runtime you also have
access to system commands which you
won't need to use too much but in case
you want to import other libraries other
Python libraries which aren't built-in
by default this is going to
important and we'll show you how to use
that in a second yeah hi that's a great
question so data lab is a version of
hosted ipython notebook on Google Cloud
and colab which is also very similar to
what kool-aid is here in the public
facing version the best answer to this
is that collab was our internal version
and dataflow was made by cloud
specifically to be externalized and so
they are very similar but the feature
set is not exactly overlapping I haven't
used data lab as much so I'm actually
not familiar but I believe the
collaborative nature is not there but I
may be incorrect on that the other thing
you have which again you have an I -
notebook is that you have the ability to
use HTML which we will also be using to
help understand what's going on some of
our Python graphs or you can put things
like this you may or may not get bonus
points and assignments if you put little
scrolling text
it depends who's marking it I will give
you more points I'm not actually marking
any later assignments though so take
that with a grain of salt but obviously
you can also do this programmatically
which is going to be very helpful when
you're writing a tense flow model
because visualization for all machine
learning models is always a key to
understanding what is going on and
debugging what's going wrong and then
you also have these nice things like tab
complete and you can have interactive
outputs this is not clear to me how this
is meant to be interactive but there are
also interactive outputs that you can
use as well all this is to say you don't
need to use any of this functionality
necessarily for the assignments but a
lot of it will make your life a little
bit easier and a little bit more fun you
can also this is also integrated with
Google Drive
so it's a good place to save save many
copies save frequently
and you will minimize some of the risks
there okay so here is the interesting
thing where it comes to shell commands
so as you saw before exclamation points
allow you to run shell commands on the
machine this is running on so if for
example you want to upgrade attentively
to the nightly build which is something
you might be interested in doing you of
course first connect to the runtime and
you'll see this will go through and
actually install the newer version of
tensorflow for you on this point most of
the assignments will be they've been
made
assuming that you were using the current
version of tensorflow that is running on
these machines however if you want to
use some of the newer features of
tensorflow which can be very helpful one
which you might want to look into is
called tensorflow
eager mode and it can make a debugging a
lot easier for complex models you would
need to run the nightly build and so you
would have to run this kind of thing and
in similar ways these two introductory
code labs are linked directly off the
landing page so you can go back to these
they're very easy to access and it just
shows you how you can install these
different libraries if you have favorite
Python libraries you want to use the
standard binary only comes effectively
with tensorflow
and install so if you want any other
libraries you will need to install them
okay any questions on collab so far
before we have a look at some of the
formulas matteo brought up earlier in
the talk yeah yes so if you want to be
using the nightly version you would have
to run that every time you restart your
runtime any other questions yes Oh like
virtual ends
no but effectively you will get since
you get a new runtime a fresh one every
time you open a new collab you could
simulate this by essentially having
different documents for therefore
different things so it's probably
possible but I haven't tried it I don't
know anyone who has any other questions
yeah so this is a really good point if
people are not very familiar with
ipython notebook one of the things that
can make debugging harder and bugs that
come up quite often is that you set a
variable in a previous cell you maybe
delete that you forget about it but it's
still globally set in the Python runtime
and you have these very odd issues to
debug there is where is it mm-hmm
okay so in collab the closest thing that
can help in this is you have a history
in an executed code history so that you
can see what has been run in order from
the cells and so it's one thing that you
can do to flick back and see if there's
anything that stands out aside from that
it is a problem and just generally good
code health and if something goes wrong
resetting as I showed before if you
reset the runtime that obviously clears
the Python global state so if you have
any odd transient errors that can help
clean that up
any other questions
okay oh one other thing that you might
also find helpful is if you have a cell
you'll sometimes run into an issue
especially in the later assignments
where you have a lot of somewhat dense
code and the car labs can go quite large
colab gives you nope
maybe it doesn't in this okay I take
that back
not all of the internal yeah not all of
the internal features are external yet
but hopefully that will be soon okay so
this is code that you might find useful
while you're developing which is going
to allow us to visualize the graph in a
nice Explorer you're making something so
we'll have a look at a very simple
tensor flow graph in code and then
actually see it rendered
okay so this is a very very simple tense
photograph don't forget to connect to
your runtime okay so that's executed
correctly
and now you can see here we have two
multiplication operations and four
constants so it's obvious to everyone
why there is two multiplication
operations there in four constants does
anyone want to suggest a reason why that
might be
no it's not legible from the back thank
you very much that is still very useful
snow let me see if I can zoom in for you
is that a little bit more legible there
we are so this shows everything that's
been written into the Python graph so
far the reason that happened is because
I ran the cell once without sho TF graph
there and then I ran the same cell again
after I'd written sho TF graph so the
first time it creates two constants and
a multiplication operation and then the
second time I ran that it creates
another two constants and another
multiplication operation and what we've
now got in the graph X refers to the
second one that was created and we've
now orphaned part of our tensor flow
graph we have something in the tense of
a graph but we have no Python variable
that refers to that multiplication node
anymore so if this happens it's not
actually a big deal because that node
will just sit there and won't get
executed if we don't have a Python
reference to it that's the reason that
there is too and you'll see throughout
here there's a TF dot reset default
graph so if you don't explicitly tell
tensorflow what graph to put things into
it has a default graph that it'll put it
into by default pre run reset default
graph and then run this again there
should only be one multiplication and
two constants which is what we see there
so we'll go down and see this tends to
only be useful it's a kind of last
resort debugging mechanism to be honest
because you'll see that as we start to
get more complicated functions the graph
becomes very complicated very quickly
the most useful advice I can give you to
successfully completing the assignments
that you'll be given is that it's much
better to not make mistakes in the first
place
and so if you have a chance to like pair
code work with a friend and try and make
sure that everything is right all the
way along are you'd be much better off
than trying to debug at the end because
it is notoriously hard okay
so this is just what we were looking
through in the slides in the first half
with Matteo and this is generating some
random data that is linear with some
noise added and then these structures
that we saw before so here we've got two
placeholders where we're going to be
putting in the X's and the Y's that
we're going to be training on and so we
have a pretty simple graph here we have
X's and Y's
because I saw we've constructed so far
however now we're going to create a
linear model so I'm sorry I realize that
text is actually quite small can people
see the text up the back not really
mmm don't know that I can actually help
you out here you can do the yeah that's
it
say any better I think it's just gonna
be hard to read this much code from far
away so you'll just have to trust me
that I'm telling you the right thing I'm
not gonna lie to you okay I deliberately
left this in to show you how difficult
it can be to debug tensorflow code and
so I'm gonna follow my own advice and
I'm just going to restart the runtime
and go from the beginning because I'm
fairly sure that should have worked if
not
and there you go
reset default run time okay so this is
what the graph looks like full closed
form linear regression so you can see
now that there's quite a lot of
fundamental operations that go into even
something here which is relatively
simple and you can see that variables in
the graph the W and the B here are
highlighted in blue and these larger
boxes that you can see here actually are
groups and if you double click on them
you can go and see the operations that
are within that entity within the tensor
flow graph and then you can see as
Matteo claims if you run this you do get
the closed form linear regression
solution to that particular set of data
so we're getting to the end now I'll
skip the the rest of the lecture code is
in here and this all runs straight up
I'm going to share this collab after the
lecture in the Moodle but for the moment
is there any questions before we finish
up yes do you have anything like that
instead of matplotlib no I really wish
we did but we don't could you say that
again
yes so for 410 to flow variables tensor
board has some visualization
capabilities although it's not clear to
me whether you will be using tensor
board in these exercises I'm not sure at
the moment yes it is this is this is
used with intense aboard this is this is
a particular widgets that there's an
internal version which does this
properly this is a kind of like external
hack that you're essentially pulling
from a tensor board instance just to get
a nice graph down it would be in a
theory possible to get the other stuff
too but I won't be able to supply you
with that code I don't believe so not
for the external version now you will
have to have an internet connection yes
I you'd be responsible for making sure
that your component like your runtime
your Python runtime has the same version
components so just be careful of that
drift but otherwise you should be able
to run them in a normal ipython notebook
yep same one any other questions yeah if
you open in playground here that that
allows you to open a ipython notebook
and be able to play around with it but
it doesn't save a copy in Google Drive
so normally when you start a new one
it'll save a copy in Google Drive but if
you just want to play around with one
that you've been sent you can open in
playground to actually execute it
without saving it
your variables the best way is generally
with a named scope as much as you can do
that it also does help debugging a lot
it's a very good practice to use so yeah
I put named name scopes on everything
and just while we're on the subject of
good things to do often commenting
tenses with their expected shape in the
Python code can be very helpful to make
sure that you are calculating the
quantities that you think you're
calculating any final questions as long
as you have your collab open it should
just sit there indefinitely in the back
and time out if you have very we'll see
as the course progresses if you have
very long running jobs we'll need to
make sure that nothing fails but also
once you've been whitelisted you'll
actually have specific machines which
are for you guys that shouldn't go down
if your internet connection dies and you
lose connection with the back end my
guess is that you would be able to
reconnect to a fresh kernel which means
you'll lose any state that's going on so
yeah don't do this anywhere you have a
really sketchy internet connection but
it's I was gonna say I hope UCL has a
pretty good one last one yeah what sorry
what free resources you have access to
on here I think it's it's probably not
the smallest instance on Google cloud
but maybe the second smallest instance
which gets spun up in this free version
when we get you your whitelisted access
I think it's either going to be a GPU
instance or an eight CPU instance all
right thanks very much for your
attention this morning and good luck
with the rest of the course


Bad AI Predictions: Bard Upgrade, 2 Years to AI Auto-Money, OpenAI Investigation and more

people are starting to get used to the
Breakneck pace of AI so I wanted to show
that developments in just the last few
days fly in the face of what was
predicted only a couple of years ago
starting with the upgrades The Bard then
a snapshot of Claude 2. the
all-encompassing open AI investigation
and inflection ai's predictions of a
self-guided million dollar making AI
coming in just two years but I'm going
to start with this page from a book
released in 2021 called a brief history
of AI look at the tasks it says are
nowhere near solved and at the bottom it
says at present we have no idea about
how to get computers to do the tasks at
the bottom of the list I'm not arguing
that these are solved but this year we
are getting pretty close check out the
second one down human level automated
translation I asked the new bar to write
a poem about machine translation and
here it is I'm not going to judge the
poem but then I asked now translate it
into Spanish of course that's nothing
new but listen to the quality of the
text-to-speech model used to read out
this poem here's a snippet
is
I don't know about you but that is
starting to sound awfully human-like now
yes it could do this before for English
but now it can do it for even Swahili
and I know some people will say don't we
already have Google translate but Palm 2
which is the model behind Bard
outperforms Google translate I covered
this in the original palm 2 video but
the conclusion was we observe that Palm
2 improves quality both over the
original palm and Google translate okay
that is pretty insane but what about the
next one interpreting what is going on
in a photograph are we nowhere near
solving that well I gave Bart the meme
that you can see and I said interpret
what's going on and it said this the
image shows a pizza that has been shaped
to look like the death star already that
is so Savvy to me that it knows it's a
pizza despite it being so strangely
formed and it can interpret that the
toppings make it look like the Death
Star of course as a bonus it can read
the text and therefore understand the
meme it says it's humorous because the
Death Star is a symbol of death and
destruction compared to a pizza which is
about food and enjoyment a quick bonus
tip by the way is that you can scroll to
the end of the response and click this
modify response button and then you can
adjust the output for example I'm going
to make it do something shorter and you
are going to see a shorter version of
this interpretation and here it is
apparently reduced by about 25 now the
Google lens is incorporated into Bard I
use it daily on my walks to answer
questions about things around me like
maybe I see a butterfly and I ask what
type of butterfly is or a plant and one
thing to caution you on is that if it
sees a human face it will block that out
and not answer the question and one more
crazy thing that I found that I'm
curious if anyone else found this is
that I took a photo in my local park in
air actually recognized the location of
the park and it was not a nationally let
alone internationally recognized park at
all now that didn't work every time but
it is something you might want to try on
your next walk or run and you might have
noticed that that's quite similar to the
one second from last which is
interpreting a work of art now again I'm
not saying that solved and there may be
some reverse image search going on here
I asked write a haiku about where the
stairs are going in this work of art
famously this sketch is about the stairs
going nowhere by Esha and it wrote an
almost perfect haiku about the fact that
the stairs are going nowhere let's now
take a break from that book and look at
what professional forecasters predicted
that AI would be capable of for the math
data sets for this particular Benchmark
in 2021 they put did a score of 21 in
2023 and 52 in 2025 and the predicted
Trend would hit 80 only in 2028 five
years from now seven years from then
well regular viewers of my channel might
know that gpd4 can already get 78 of
problems from that data set correct
already today and you can see here that
there is still quite a lot of room for
further Improvement and honestly this is
without code interpreter or Wolfram
Alpha so I actually ran hundreds of
experiments of my own using g64 with
code interpreter on the math data set
and it was getting more like 86 correct
but back to predictions from 2021 notice
two of the other categories that are
apparently nowhere near solved
understanding a story and answering
questions about it and writing an
interesting story here is a 112 page
novel written fully by gpt4 now I think
it meets the definition of being
interesting if not human level but
honestly when a model can be fine-tuned
on an author's work I think it will get
very very close my own prediction is
that we are less than a year away from a
human level novel not as good as the
best of course but fooling many readers
but here is where I can explore a bit
with Claude 2 which can take in a
hundred thousand tokens I was lucky to
get early access to Claude 2 and around
hundreds of my own experiments which I
will talk about more in future videos
but for this video remember the books
predictions about answering questions
about such a novel or story well I
inputted that entire gpt4 generated
novel and I said find 10 sentences whose
vocabulary could be made less generic
and if you look at these suggestions
from Claude 2 it does indeed make the
vocabulary more exciting definitely not
perfect still quite generic but we have
words like crystalline ethereal and
inaugurable I I love that word myself
one of my favorites again I think we're
less than a year from a high quality
full-length novel being produced using
one prompt and if you wanted a more
technical test of reading comprehension
don't forget that gpd4 got 99th
percentile in the verbal section of the
GRE which includes reading comprehension
I managed to get 170 on this test and to
be honest when I saw Gypsy 4 get 99th
percentile that was a huge wake-up call
for me a true story actually is that
when I saw that result I decided to make
covering AI my full-time job and I think
each person will go through their own
such moment when gbt4 or GT5 or Gemini
crosses some Benchmark to do with their
profession it's like I didn't wake up
much when it could create basic art
because I'm not an artist but when these
models come onto territory that you
yourself know about that's when you
realize how powerful they are and I
think a lot of people have gone through
that Journey this is metaculous if
that's how you pronounce it and their
predictions about AGI and look what the
predictions were two years ago around
the time of that book they were late
2030s even early 2040s and this was as
late as October or November of 2021. you
can see that they thought AGI would be
20 or more years away what do they think
now well
2026. that is quite a change in two
years and I can understand why Mustafa
Suleiman the founder of inflection AI
goes further they are building towards
their own AGI and they plan to ask it to
go make one million dollars of course it
would need a strategy it would need to
research and design products etc etc
maybe with a little bit of human
approval but the work would all be done
by an AI and he says something like this
could be as little as two years away and
those of you who watched my previous
video on super intelligence will find
that quite a contrast to the idea that
super intelligence is 10 to 20 years
away I don't know about you guys but I
think if an AI can make money in this
way the entire world economy will be
transformed rapidly there is a curious
possibility though that such an AI
wouldn't be released to the general
public of course I was following the FTC
investigation into openai as you might
expect I read all 20 pages of the
investigation multiple times in fact Sam
Altman openly grumbled that the FDC
request started with this leak enabling
me to read about it it is actually a
crazy document and it feels to me a bit
like some sort of strip search like they
want all internal Communications about
the propensity of chatgpt to produce
inaccurate statements or reveal personal
information and they say at the top do
not delete any emails relating to this
in other videos I've covered how any
model can be jailbroken and I've also
covered how Sam Altman said that it
might be two years before models stop
hallucinating so if the FTC ends up
finding open AI or the other companies
billions of dollars as they find other
companies before I can see one result
being much more reticence from these
companies over publicly deploying their
models of course let me know in the
comments whether you think that's a good
thing or a bad thing speaking of money
though I can't leave out that this week
was the start of xai Elon Musk was able
to promise up to 200 million dollars as
a signing bonus for some of the AI
researchers that joined him if companies
are willing to promise that much to
researchers willing to defect from
deepmind or open AI I do find it hard to
see the march to Super intelligence
slowing down much so let's end with that
famous scene from iRobot although
perhaps this time with a different
ending an imitation of life
can a robot write a symphony
can a robot turn a canvas into a
beautiful masterpiece
thank you so much for watching and have
a wonderful day