Deep Learning (Adaptive Computation and Machine Learning series), Ian Goodfellow
We all heard of this buz word “LLM” (Large Language Model). But let’s put that aside for just a second and look at a
much simpler one called “character-level language model” where, for example, we input a prefix of a word such as “hell”
and the model outputs a complete word “hello”. That is, this language model predicts the next character of a character
sequence. This is like a Math function where we have:
f(“hell")=“hello"
where we call inputs like “hell” a sequence.
How do we obtain a function like this? One approach is to have 4 black boxes, each of which takes a single character as
input and calculates an output:
But one might have noticed that if the 3rd function (box) produces f(′l′)=′l′, then why would the 4th function
(box), given the same input, gives a different output of ‘o’? This suggest that we should take the history into
account. Instead of having f depend on 1 parameter, we now have it take 2 parameters.
a character;
a variable that summarizes the previous calculations:
Now it makes much more sense with:
f(‘l’,h2)=‘l’f(‘l’,h3)=‘o’
But what if we want to predict a longer or shorter word? For example, how about predicting “cat” by “ca”? That’s simple,
we will have 2 black boxes to do the work.
What if the function f is not smart enough to produce the correct output everytime? We will simply collect a lot of
examples such as “cat” and “hello”, and feed them into the boxes to train them until they can output correct vocabulary
like “cat” and “hello”.
This is the idea behind RNN. It’s recurrent because the boxed function gets invoked repeatedly for each element of the
sequence. In the case of our character-level language model, element is a character such as “e” and sequence is a string
like “hell”
Each function f is a network unit containing 2 perceptrons. One perceptron computes the “history” like h1, h2,
h3. Its formula is very similar to that of perceptron:
h(t)=g1(Whhh(t−1)+Wxhx(t)+bh)
where t is the index of the “black boxes” shown above. In our example of “hell”, t∈{1,2,3,4}. The other
perceptron computes the output like ‘e’, ‘l’, ‘l’, ‘o’. We call those value y which is given by
o(t)=g2(Wyhh(t)+bo)
TIP
What are g1 and g2?
They are activation functions which are used to change the linear function in a perceptron to a non-linear function.
Please refer to Machine Learning by Mitchell, Tom M. (1997), Paperback (page 96) for why we bump it to non-linear
We now develop the forward propagation equations for the RNN. We assume the hyperbolic tangent activation function,
i.e. tanh(x)=ex+e−xex−e−x and that the output is discrete, as if the RNN is used to predict
words or characters. A natural way to represent discrete variables is to regard the output o as giving
the unnormalized log probabilities of each possible value of the discrete variable. We can then apply the softmax
(discussed shortly) operation as a post-processing step to obtain a vector y^(t) of normalized
probabilities over the output. Forward propagation begins with a specification of the initial state
h(0). Then, for each time step from t=1 to t=τ, we apply the following update equations:
According to the discussion of Machine Learning by Mitchell, Tom M. (1997), the key for training RNN or any neural
network is through “specifying a measure for the training error”. We call this measure a loss function.
In RNN, the total loss for a given sequence of input x paired with a sequence of expected
y is the sum of the losses over all the time steps, i.e.
L({x(1),...,x(τ)},{y(1),...,y(τ)})=t∑τL(t)
Knowing the exact form of L(t) requires our intuitive understanding of cross-entropy
In information theory, the cross-entropy between two probability
distributions p and q over the same underlying set of events measures the average number of bits needed to identify
an event drawn from the set if a coding scheme used for the set is optimized for an estimated probability distribution
q, rather than the true distribution p
Confused? Let’s put it in the context of Machine Learning. Machine Learning sees the world based on probability. The
“probability distribution” identifies the various tasks to learn. For example, a daily language such as English or
Chinese, can be seen as a probability distribution. The probability of “name” followed by “is” is far greater than “are”
as in “My name is Jack”. We call such language distribution p. The task of RNN (or Machine Learning in general) is to
learn an approximated distribution of p; we call this approximation q
“The average number of bits needed” is can be seen as the distance between p and q given an event. In analogy of
language, this can be the quantitative measure of the deviation between a real language phrase “My name is Jack” and
“My name are Jack”.
At this point, it is easy to imagine that, in the Machine Learning world, the cross entropy indicates the distance
between what the model believes the output distribution should be and what the original distribution really is.
Now we have an intuitive understanding of cross entropy, let’s formally define it. The cross-entropy of the discrete
probability distribution q relative to a distribution p over a given set is defined as
H(p,q)=−x∑p(x)logq(x)
Since we assume the softmax probability distribution earlier, the probability distribution of q(x) is:
What is the Mathematical form of p(i) in RNN? Why would it become 1?
By definition, p(i) is the true distribution whose exact functional form is unknown. In the language of
Approximation Theory, p(i) is the function that RNN is trying to learn or approximate mathematically.
Although the p(i) makes the exact form of L unknown, computationally p(i) is perfectly defined in each
training example. Taking our “hello” example:
The 4 probability distributions of q(x) is “reflected” in the output layer of this example. They are “reflecting” the
probability distribution of q(x) because they are only o values and have not been transformed to the σ
distribution yet. But in this case, we are 100% sure that the true probability distribution p(i) for the 4 outputs are
0100,0010,0010,0001
respectively. That is all we need for calculating the L
The softmax function takes as input a vector z of K real numbers,
and normalizes it into a probability distribution consisting of K probabilities proportional to the exponentials of
the input numbers. That is, prior to applying softmax, some vector components could be negative, or greater than one;
and might not sum to 1; but after applying softmax, each component will be in the interval (0,1) and the components
will add up to 1, so that they can be interpreted as probabilities. Furthermore, the larger input components will
correspond to larger probabilities.
For a vector z of K real numbers, the the standard (unit) softmax function σ:RK↦(0,1)K,
where K≥1 is defined by
σ(z)i=∑j=1Kezjezi
where i=1,2,...,K and x=(x1,x2,...,xK)∈RK
In the context of RNN,
σ(o)i=−∑j=1neojeoi
where
n is the length of a sequence feed into the RNN
oi is the output by perceptron unit i
i=1,2,...,n,
o=(o1,o2,...,on)∈Rn
The softmax function takes an N-dimensional vector of arbitrary real values and produces another N-dimensional vector
with real values in the range (0, 1) that add up to 1.0. It maps RN→RN
σ(o):o1o2…on→σ1σ2…σn
This property of softmax function that it outputs a probability distribution makes it suitable for probabilistic
interpretation in classification tasks. Neural networks, however, are commonly trained under a log loss (or
cross-entropy) regime
We are going to compute the derivative of the softmax function because we will be using it for training our RNN model
shortly. But before diving in, it is important to keep in mind that Softmax is fundamentally a vector function. It takes
a vector as input and produces a vector as output; in other words, it has multiple inputs and multiple outputs.
Therefore, we cannot just ask for “the derivative of softmax”; We should instead specify:
Which component (output element) of softmax we’re seeking to find the derivative of.
Since softmax has multiple inputs, with respect to which input element the partial derivative is computed.
What we’re looking for is the partial derivatives of
∂ok∂σi=∂ok∂∑j=1neojeoi
where ∂ok∂σi is the partial derivative of the i-th output with respect with the k-th
input.
We’ll be using the quotient rule of derivatives. For h(x)=g(x)f(x) where both f and g are
differentiable and g(x)=0, The quotient rule states that the
derivative of h(x) is
Training a RNN model of is the same thing as searching for the optimal values for the following parameters of the
Forward Progagation Equations:
Wxh
Whh
Wyh
bh
bo
By the Gradient Descent discussed in Machine Learning by Mitchell, Tom M. (1997), we should derive the weight updat
rule by taking partial derivatives with respect to all of the variables above. Let’s start with Wyh
Machine Learning by Mitchell, Tom M. (1997) has mentioned gradients and partial derivatives as being important for an
optimization algorithm to update, say, the model weights of a neural network to reach an optimal set of weights. The use
of partial derivatives permits each weight to be updated independently of the others, by calculating the gradient of the
error curve with respect to each weight in turn.
Many of the functions that we usually work with in machine learning are multivariate, vector-valued functions, which
means that they map multiple real inputs n to multiple real outputs m:
f:Rn→Rm
In training a neural network, the backpropagation algorithm is responsible for sharing back the error calculated at the
output layer among the neurons comprising the different hidden layers of the neural network, until it reaches the input.
If our RNN contains only 1 perceptron unit, the error is propagated back by, using the
Chain Rule of dxdz=dydzdxdy:
∂W∂L=∂o∂L∂W∂o
Note that in the RNN mode, L is not a direct function of W. Thus its first order derivative cannot be
computed unless we connect the L to o first and then to W, because both the first order derivatives of
∂o∂L and ∂W∂o are defined by the model presented earlier
above
It is more often the case that we’d have many connected perceptrons populating the network, each attributed a different
weight. Since this is the case for RNN, we can generalise multiple inputs and multiple outputs using the
Generalized Chain Rule:
Consider the case where x∈Rm and u∈Rn; an inner function, f, maps m inputs to n
outputs, while an outer function, g, receives n inputs to produce an output, h∈Rk. For
i=1,…,m the generalized chain rule states:
The equation above leaves us with a term ∇h(t)L, which we calculate next. Note that
the back propagation on h(t) has source from both o(t) and
h(t+1). It’s gradient, therefore, is given by
Note that the 2nd term
Wxh⊺∇h(t+1)L(diag[1−(h(t+1))2])
is zero at first iteration propagating back because for the last-layer (unrolled) of RNN , there’s no gradient update
flow from the next hidden state.
So far we have derived backpropagating rule for Whh