Deep Learning Tutorials Lisa Lab download
Deep Learning Tutorials Lisa Lab download
https://ebookbell.com/product/deep-learning-tutorials-lisa-
lab-32853472
https://ebookbell.com/product/artificial-intelligence-engines-a-
tutorial-introduction-to-the-mathematics-of-deep-learning-1st-edition-
james-stone-23407368
Python Machine Learning Machine Learning And Deep Learning With Python
Scikitlearn And Tensorflow Stepbystep Tutorial For Beginners Samuel
Burns Chenjin5com
https://ebookbell.com/product/python-machine-learning-machine-
learning-and-deep-learning-with-python-scikitlearn-and-tensorflow-
stepbystep-tutorial-for-beginners-samuel-burns-chenjin5com-36752488
https://ebookbell.com/product/deep-learning-ian-goodfellow-yoshua-
bengio-aaron-courville-44886094
https://ebookbell.com/product/deep-learning-in-biology-and-medicine-
davide-bacciu-paulo-j-g-lisboa-44899934
Deep Learning For Sustainable Agriculture Ramesh Poonia Vijander Singh
https://ebookbell.com/product/deep-learning-for-sustainable-
agriculture-ramesh-poonia-vijander-singh-46110062
https://ebookbell.com/product/deep-learning-based-speech-quality-
prediction-gabriel-mittag-46124808
https://ebookbell.com/product/deep-learning-for-computational-
problems-in-hardware-security-pranesh-santikellur-46163396
https://ebookbell.com/product/deep-learning-for-social-media-data-
analytics-tzungpei-hong-46196138
https://ebookbell.com/product/deep-learning-for-targeted-treatments-
transformation-in-healthcare-rishabha-malviya-46226054
Deep Learning Tutorial
Release 0.1
1 LICENSE 1
3 Getting Started 5
3.1 Download . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
3.2 Datasets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
3.3 Notation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
3.4 A Primer on Supervised Optimization for Deep Learning . . . . . . . . . . . . . . . . . . . 8
3.5 Theano/Python Tips . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
5 Multilayer Perceptron 35
5.1 The Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
5.2 Going from logistic regression to MLP . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
5.3 Putting it All Together . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
5.4 Tips and Tricks for training MLPs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
i
6.10 Tips and Tricks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
ii
13.4 Code - Citations - Contact . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
13.5 References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
14 Modeling and generating sequences of polyphonic music with the RNN-RBM 149
14.1 The RNN-RBM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
14.2 Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
14.3 Results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
14.4 How to improve this code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
15 Miscellaneous 159
15.1 Plotting Samples and Filters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
16 References 163
Bibliography 165
Index 167
iii
iv
CHAPTER
ONE
LICENSE
1
Deep Learning Tutorial, Release 0.1
2 Chapter 1. LICENSE
CHAPTER
TWO
Deep Learning is a new area of Machine Learning research, which has been introduced with the objective of
moving Machine Learning closer to one of its original goals: Artificial Intelligence. See these course notes
for a brief introduction to Machine Learning for AI and an introduction to Deep Learning algorithms.
Deep Learning is about learning multiple levels of representation and abstraction that help to make sense of
data such as images, sound, and text. For more about deep learning algorithms, see for example:
• The monograph or review paper Learning Deep Architectures for AI (Foundations & Trends in Ma-
chine Learning, 2009).
• The ICML 2009 Workshop on Learning Feature Hierarchies webpage has a list of references.
• The LISA public wiki has a reading list and a bibliography.
• Geoff Hinton has readings from 2009’s NIPS tutorial.
The tutorials presented here will introduce you to some of the most important deep learning algorithms and
will also show you how to run them using Theano. Theano is a python library that makes writing deep
learning models easy, and gives the option of training them on a GPU.
The algorithm tutorials have some prerequisites. You should know some python, and be familiar with
numpy. Since this tutorial is about using Theano, you should read over the Theano basic tutorial first. Once
you’ve done that, read through our Getting Started chapter – it introduces the notation, and [downloadable]
datasets used in the algorithm tutorials, and the way we do optimization by stochastic gradient descent.
The purely supervised learning algorithms are meant to be read in order:
1. Logistic Regression - using Theano for something simple
2. Multilayer perceptron - introduction to layers
3. Deep Convolutional Network - a simplified version of LeNet5
The unsupervised and semi-supervised learning algorithms can be read in any order (the auto-encoders can
be read independently of the RBM/DBN thread):
• Auto Encoders, Denoising Autoencoders - description of autoencoders
• Stacked Denoising Auto-Encoders - easy steps into unsupervised pre-training for deep nets
• Restricted Boltzmann Machines - single layer generative RBM model
• Deep Belief Networks - unsupervised generative pre-training of stacked RBMs followed by supervised
fine-tuning
3
Deep Learning Tutorial, Release 0.1
Building towards including the mcRBM model, we have a new tutorial on sampling from energy models:
• HMC Sampling - hybrid (aka Hamiltonian) Monte-Carlo sampling with scan()
Building towards including the Contractive auto-encoders tutorial, we have the code for now:
• Contractive auto-encoders code - There is some basic doc in the code.
Recurrent neural networks with word embeddings and context window:
• Semantic Parsing of Speech using Recurrent Net
LSTM network for sentiment analysis:
• LSTM network
Energy-based recurrent neural network (RNN-RBM):
• Modeling and generating sequences of polyphonic music
THREE
GETTING STARTED
These tutorials do not attempt to make up for a graduate or undergraduate course in machine learning, but
we do make a rapid overview of some important concepts (and notation) to make sure that we’re on the same
page. You’ll also need to download the datasets mentioned in this chapter in order to run the example code
of the up-coming tutorials.
3.1 Download
On each learning algorithm page, you will be able to download the corresponding files. If you want to
download all of them at the same time, you can clone the git repository of the tutorial:
git clone https://github.com/lisa-lab/DeepLearningTutorials.git
3.2 Datasets
(mnist.pkl.gz)
The MNIST dataset consists of handwritten digit images and it is divided in 60,000 examples
for the training set and 10,000 examples for testing. In many papers as well as in this tutorial,
the official training set of 60,000 is divided into an actual training set of 50,000 examples and
10,000 validation examples (for selecting hyper-parameters like learning rate and size of the
model). All digit images have been size-normalized and centered in a fixed size image of 28 x
28 pixels. In the original dataset each pixel of the image is represented by a value between 0
and 255, where 0 is black, 255 is white and anything in between is a different shade of grey.
Here are some examples of MNIST digits:
For convenience we pickled the dataset to make it easier to use in python. It is available for
download here. The pickled file represents a tuple of 3 lists : the training set, the validation
set and the testing set. Each of the three lists is a pair formed from a list of images and a list
of class labels for each of the images. An image is represented as numpy 1-dimensional array
5
Deep Learning Tutorial, Release 0.1
of 784 (28 x 28) float values between 0 and 1 (0 stands for black, 1 for white). The labels are
numbers between 0 and 9 indicating which digit the image represents. The code block below
shows how to load the dataset.
import cPickle, gzip, numpy
When using the dataset, we usually divide it in minibatches (see Stochastic Gradient Descent).
We encourage you to store the dataset into shared variables and access it based on the minibatch
index, given a fixed and known batch size. The reason behind shared variables is related to using
the GPU. There is a large overhead when copying data into the GPU memory. If you would
copy data on request ( each minibatch individually when needed) as the code will do if you do
not use shared variables, due to this overhead, the GPU code will not be much faster then the
CPU code (maybe even slower). If you have your data in Theano shared variables though, you
give Theano the possibility to copy the entire data on the GPU in a single call when the shared
variables are constructed. Afterwards the GPU can access any minibatch by taking a slice
from this shared variables, without needing to copy any information from the CPU memory
and therefore bypassing the overhead. Because the datapoints and their labels are usually of
different nature (labels are usually integers while datapoints are real numbers) we suggest to
use different variables for label and data. Also we recommend using different variables for
the training set, validation set and testing set to make the code more readable (resulting in 6
different shared variables).
Since now the data is in one variable, and a minibatch is defined as a slice of that variable, it
comes more natural to define a minibatch by indicating its index and its size. In our setup the
batch size stays constant throughout the execution of the code, therefore a function will actually
require only the index to identify on which datapoints to work. The code below shows how to
store your data and how to access a minibatch:
def shared_dataset(data_xy):
""" Function that loads the dataset into shared variables
The data has to be stored as floats on the GPU ( the right dtype for storing on the GPU is given by
theano.config.floatX). To get around this shortcomming for the labels, we store them as float, and
then cast it to int.
Note: If you are running your code on the GPU and the dataset you are using is too large to fit in memory
the code will crash. In such a case you should store the data in a shared variable. You can however store a
sufficiently small chunk of your data (several minibatches) in a shared variable and use that during training.
Once you got through the chunk, update the values it stores. This way you minimize the number of data
transfers between CPU memory and GPU memory.
3.3 Notation
We label data sets as D. When the distinction is important, we indicate train, validation, and test sets as:
Dtrain , Dvalid and Dtest . The validation set is used to perform model selection and hyper-parameter selec-
tion, whereas the test set is used to evaluate the final generalization error and compare different algorithms
in an unbiased way.
The tutorials mostly deal with classification problems, where each data set D is an indexed set of pairs
(x(i) , y (i) ). We use superscripts to distinguish training set examples: x(i) ∈ RD is thus the i-th training
example of dimensionality D. Similarly, y (i) ∈ {0, ..., L} is the i-th label assigned to input x(i) . It is
straightforward to extend these examples to ones where y (i) has other types (e.g. Gaussian for regression,
or groups of multinomials for predicting multiple symbols).
3.3. Notation 7
Deep Learning Tutorial, Release 0.1
What’s exciting about Deep Learning is largely the use of unsupervised learning of deep networks. But
supervised learning also plays an important role. The utility of unsupervised pre-training is often evaluated
on the basis of what performance can be achieved after supervised fine-tuning. This chapter reviews the
basics of supervised learning for classification models, and covers the minibatch stochastic gradient descent
algorithm that is used to fine-tune many of the models in the Deep Learning Tutorials. Have a look at these
introductory course notes on gradient-based learning for more basics on the notion of optimizing a training
criterion using the gradient.
Zero-One Loss
The models presented in these deep learning tutorials are mostly used for classification. The objective in
training a classifier is to minimize the number of errors (zero-one loss) on unseen examples. If f : RD →
{0, ..., L} is the prediction function, then this loss can be written as:
|D|
X
`0,1 = If (x(i) )6=y(i)
i=0
where either D is the training set (during training) or D ∩ Dtrain = ∅ (to avoid biasing the evaluation of
validation or test error). I is the indicator function defined as:
1 if x is True
Ix =
0 otherwise
Since the zero-one loss is not differentiable, optimizing it for large models (thousands or millions of param-
eters) is prohibitively expensive (computationally). We thus maximize the log-likelihood of our classifier
given all the labels in a training set.
|D|
X
L(θ, D) = log P (Y = y (i) |x(i) , θ)
i=0
The likelihood of the correct class is not the same as the number of right predictions, but from the point of
view of a randomly initialized classifier they are pretty similar. Remember that likelihood and zero-one loss
are different objectives; you should see that they are corralated on the validation set but sometimes one will
rise while the other falls, or vice-versa.
Since we usually speak in terms of minimizing a loss function, learning will thus attempt to minimize the
negative log-likelihood (NLL), defined as:
|D|
X
N LL(θ, D) = − log P (Y = y (i) |x(i) , θ)
i=0
The NLL of our classifier is a differentiable surrogate for the zero-one loss, and we use the gradient of this
function over our training data as a supervised learning signal for deep learning of a classifier.
This can be computed using the following line of code :
# NLL is a symbolic variable ; to get the actual value of NLL, this symbolic
# expression has to be compiled into a Theano function (see the Theano
# tutorial for more details)
NLL = -T.sum(T.log(p_y_given_x)[T.arange(y.shape[0]), y])
# note on syntax: T.arange(y.shape[0]) is a vector of integers [0,1,2,...,len(y)].
# Indexing a matrix M by the two vectors [0,1,...,K], [a,b,...,k] returns the
# elements M[0,a], M[1,b], ..., M[K,k] as a vector. Here, we use this
# syntax to retrieve the log-probability of the correct labels, y.
What is ordinary gradient descent? it is a simple algorithm in which we repeatedly make small steps down-
ward on an error surface defined by a loss function of some parameters. For the purpose of ordinary gradient
descent we consider that the training data is rolled into the loss function. Then the pseudocode of this algo-
rithm can be described as :
# GRADIENT DESCENT
while True:
loss = f(params)
d_loss_wrt_params = ... # compute gradient
params -= learning_rate * d_loss_wrt_params
if <stopping condition is met>:
return params
Stochastic gradient descent (SGD) works according to the same principles as ordinary gradient descent, but
proceeds more quickly by estimating the gradient from just a few examples at a time instead of the entire
training set. In its purest form, we estimate the gradient from just a single example at a time.
# STOCHASTIC GRADIENT DESCENT
for (x_i,y_i) in training_set:
# imagine an infinite generator
# that may repeat examples (if there is only a finite training
loss = f(params, x_i, y_i)
d_loss_wrt_params = ... # compute gradient
params -= learning_rate * d_loss_wrt_params
if <stopping condition is met>:
return params
The variant that we recommend for deep learning is a further twist on stochastic gradient descent using so-
called “minibatches”. Minibatch SGD works identically to SGD, except that we use more than one training
example to make each estimate of the gradient. This technique reduces variance in the estimate of the
gradient, and often makes better use of the hierarchical memory organization in modern computers.
for (x_batch,y_batch) in train_batches:
# imagine an infinite generator
# that may repeat examples
loss = f(params, x_batch, y_batch)
d_loss_wrt_params = ... # compute gradient using theano
params -= learning_rate * d_loss_wrt_params
There is a tradeoff in the choice of the minibatch size B. The reduction of variance and use of SIMD
instructions helps most when increasing B from 1 to 2, but the marginal improvement fades rapidly to
nothing. With large B, time is wasted in reducing the variance of the gradient estimator, that time would be
better spent on additional gradient steps. An optimal B is model-, dataset-, and hardware-dependent, and
can be anywhere from 1 to maybe several hundreds. In the tutorial we set it to 20, but this choice is almost
arbitrary (though harmless).
Note: If you are training for a fixed number of epochs, the minibatch size becomes important because it
controls the number of updates done to your parameters. Training the same model for 10 epochs using a
batch size of 1 yields completely different results compared to training for the same 10 epochs but with a
batchsize of 20. Keep this in mind when switching between batch sizes and be prepared to tweak all the
other parameters acording to the batch size used.
All code-blocks above show pseudocode of how the algorithm looks like. Implementing such algorithm in
Theano can be done as follows :
# Minibatch Stochastic Gradient Descent
3.4.3 Regularization
There is more to machine learning than optimization. When we train our model from data we are trying
to prepare it to do well on new examples, not the ones it has already seen. The training loop above for
MSGD does not take this into account, and may overfit the training examples. A way to combat overfitting
is through regularization. There are several techniques for regularization; the ones we will explain here are
L1/L2 regularization and early-stopping.
L1 and L2 regularization
L1 and L2 regularization involve adding an extra term to the loss function, which penalizes certain parameter
configurations. Formally, if our loss function is:
|D|
X
N LL(θ, D) = − log P (Y = y (i) |x(i) , θ)
i=0
where
1
|θ| p
X
p
||θ||p = |θj |
j=0
which is the Lp norm of θ. λ is a hyper-parameter which controls the relative importance of the regularization
parameter. Commonly used values for p are 1 and 2, hence the L1/L2 nomenclature. If p=2, then the
regularizer is also called “weight decay”.
In principle, adding a regularization term to the loss will encourage smooth network mappings in a neural
network (by penalizing large values of the parameters, which decreases the amount of nonlinearity that
the network models). More intuitively, the two terms (NLL and R(θ)) correspond to modelling the data
well (NLL) and having “simple” or “smooth” solutions (R(θ)). Thus, minimizing the sum of both will, in
theory, correspond to finding the right trade-off between the fit to the training data and the “generality” of
the solution that is found. To follow Occam’s razor principle, this minimization should find us the simplest
solution (as measured by our simplicity criterion) that fits the training data.
Note that the fact that a solution is “simple” does not mean that it will generalize well. Empirically, it
was found that performing such regularization in the context of neural networks helps with generalization,
especially on small datasets. The code block below shows how to compute the loss in python when it
contains both a L1 regularization term weighted by λ1 and L2 regularization term weighted by λ2
# symbolic Theano variable that represents the L1 regularization term
L1 = T.sum(abs(param))
# the loss
loss = NLL + lambda_1 * L1 + lambda_2 * L2
Early-Stopping
Early-stopping combats overfitting by monitoring the model’s performance on a validation set. A validation
set is a set of examples that we never use for gradient descent, but which is also not a part of the test set. The
I
AM unable to tell you what followed. Even Roland had no clear
recollection. When he recovered his senses, he rose and cast his
eyes round him, to find himself in the midst of a vast sandy
plain, stretching on all sides to the horizon. The sun poured its
hostile rays upon him so fiercely, that in a few minutes his armour
became insupportably hot. The atmosphere was so charged with
electricity, that the plume of his helmet crackled, and gave out
sparks. In vain he searched the horizon for a place of shelter—there
was nothing to be seen but level plain and blue sky. Gigantic red
ants came and went busily—they were the only occupants of this
desert. All of a sudden he beheld before him in the distance white
mosques, knots of palms, and a sea-port with some vessels at
anchor, and others sailing out of the harbour. He saw, too, long
caravans, which journeyed to the city gates.
Roland felt his courage revive, and set out in the direction of the
city. But he did not appear to come any the closer to it; he took to
running until he fell down with fatigue on the burning sand. Then
the city seemed to turn of a yellow hue, the blue of the sea grew
paler, and was lost in that of the sky; the trees vanished, and the
Count of Mans found himself once more alone in the desert.
“Why come to a halt?” said he to himself. “Better move forward in
any direction at hap-hazard. I can only gain by the change.”
He rose, determined to struggle on as long as his limbs would
sustain him. What was his surprise to see, in an opposite direction to
that he had just been pursuing, a mountain covered with verdure,
on the summit of which stood a castle! Three walls of
circumvallation surrounded it. At the foot of each flowed a river
covered with vessels of war. Three hanging ladders of marvellous
workmanship united the three platforms of the fortress, and four
bastions guarded the approach to each ladder.
“Charlemagne, who knows how punctual you are, seeing you were
ten minutes behind your time to take on your guard, has sent to
look for you in every direction. You are pale, my dear Count; what
has happened to you?”
“I will tell you all about it,” said Roland, as he hastened to his post
near the Emperor.
C
HARLEMAGNE had an excellent memory. He never omitted to
ponder over the dangers to which Mitaine was exposed at
every turn. He had the scene of the late ambush carefully
searched by his spies in the first place, and afterwards by his
soldiers. All, on their return, made the same report. They said the
forest was inhabited, and there was a good deal of talk about a
castle called “The Fortress of Fear,” which was to be found
somewhere in the neighbourhood, although nobody they met with
had seen it. None, however, doubted its existence. If a child
disappeared, or any cattle were carried off, the trembling peasants
said, “The Lord of Fear-fortress had taken them.” If a fire broke out
anywhere, it was the Lord of Fear-fortress who must have lit it. The
origin of all accidents, mishaps, catastrophes, or disasters was
traced to the mysterious owner of this invisible castle.
“I should like to have the mystery cleared up,” said Charlemagne
to himself. “I can hardly resign myself to the belief that it is Ganelon,
my old brother-in-arms.”
He called his knights together.
“My faithful champions, I need four of you for a perilous
adventure, I know not where I am sending you—I know not whether
you will return. Who will risk death for my good favour?”
All the knights at once flung themselves at his feet, each
entreating the Emperor to honour him with his choice.
“You place me in a difficult position,” said the Emperor, greatly
moved; “I see that chance must point out the four champions. I can
without fear trust to it, for you are all equally brave.”
The names of all the knights present were put into a helmet, and
Mitaine played the part of Destiny to the best of her power, little
thinking she was choosing her own champions and avengers. The
first name she called out was that of Allegrignac of Cognac, Count of
Salençon and Saintonge.
“The lot suits me admirably,” said the Emperor, giving a friendly
wave of his hand to the knight. “You know the language of the
country, and will be a safe guide for your companions.”
Mitaine next named the Baron of Mont-Rognon, Lord of
Bourglastic, Tortebesse, and elsewhere.
“This is indeed a capital choice! There is no stouter arm in the
Arvennes than yours; and if there be a postern to be burst open by
a powerful shoulder, you will be there, Mont-Rognon.”
“Porc-en-Truie, Lord of Machavoine,” cried Mitaine.
“I am in luck to-day, by St. James! You are known to be
experienced, Porc-en-Truie, and you will conduct the adventure, I
entrust to you, to a prosperous end, I feel sure. But I am curious to
know who is my fourth champion.”
“Maragougnia, Count of Rioin,” said Mitaine.
“Now we have wisdom, strength, and cunning. Maragougnia can
give the serpent points at wisdom, and beat him. If I do not succeed
with such knights I shall despair altogether.”
Charlemagne withdrew with his four champions, told them of the
perils to which his god-child had been exposed, the investigation he
had instituted, the suspicions he had entertained; and finally, he
spoke of the Fortress of Fear, winding up in these terms:—
“I am anxious to square accounts with this Croquemitaine. You will
pass through the forest till you arrive at Alagon, a little hamlet on
the banks of the Ebro. There you will inquire for the Fonda del
Caïman, or, if you prefer it, the sign of the Crocodile. You will there
rest yourselves for a short time, and then set out on your quests.
You, Allegrignac, striking off from the river, will pursue your course
towards Pampeluna. You, Mont-Rognon, will proceed in the direction
of Catalyud; and look out for the Saracens, my friend, who on that
side are disgusted enough with the trouble we have given them.
You, Porc-en-Truie, will make for Fuentes. If you are guided by me,
you will travel by night only, and conceal yourself carefully by day.
You will appreciate my counsel when once you are on the road. You,
finally, my gallant Maragougnia, will have to direct your steps
towards Lerida, but you will not go beyond the river Alcander. I have
reserved this expedition for you because it is the most hazardous—
there, you need not thank me. I understand you! Quarter the
country in every direction, and find out for me this Fortress of Fear.
He who brings me the head of its dreaded lord shall be created a
baron and peer of my realm.”
The Emperor replenished the purses of his champions, and took
leave of them with an embrace. When they’ found themselves alone
they interchanged looks of bewilderment.
“What do you think of that?” said Porc-en-Truie, with a grimace.
“That I shall be a duke,” said Allegrignac, cutting a caper. “This
adventure won’t take me a minute!”
“To think that we must set out to-night!” said Mont-Rognon, in
tones of regret; “and to think that I have ordered a splendid supper
for to-night, which my fellows will get the benefit of!”
“To think that we shall none of us ever come back again!” said
Maragougnia, in a melancholy voice, as he wiped away a tear with
the sleeve of his chain-mail.
“Pshaw! who knows?” broke in Porc-en-Truie, with a smile. “Let us
set out, and then we can see!”
They appointed to meet on the borders of the forest, and within
an hour afterwards they’ were all on the spot, equipped for war or
for travel.
Porc-en-Truie, Lord of Machavoine, was a great fellow of thirty
years of age, more skilled in avoiding blows than in dealing them. He
invariably shirked all his military duties, not because he was a
coward, but because he was incorrigibly idle. He had been known to
tramp three hours afoot to save himself the trouble of saddling his
horse, and he had killed his dearest friend in a tournament, in order
to terminate a long and fatiguing tilting match. He arrived at the
rendezvous on horseback, with no weapon but his sword.
“How imprudent!” cried Allegrignac, the moment he saw him
coming. “Are we going to a wedding only, or are you desirous of
emulating Miton’s great feat at the Tourney of Fronsac?”
“I hate a load of weapons, and I don’t mean to kill myself for this
Mitaine—for whom, between you and me, I don’t care a grain of
mustard-seed!”
* Vide “Malbrouck:”—
T
HE innkeeper was a man of middle size, half Spaniard and half
Moor, with a big body and thin leys, a brown skin and grey
eyes. He had acquired considerable reputation in the district
for his mode of dressing calves’ feet with saffron, and his
handiness in stabbing people in the right place. He made everything
a matter of trade, and used to regret that he had inherited no
religious opinions which he could have abjured at a fixed price to be
got either from the Saracens or the Christians. For the rest, he was a
most obliging host, provided your purse was well supplied; and I
believe I shall put the finishing stroke to the likeness when I say he
was the biggest robber in all Spain, from Pontevedra to Girone.
Ali Pépé opened the door. One is always forgetting something, and
I forgot to tell you his name was Ali Pépé.
“Where’s the landlady?” asked Allegrignac, twisting his moustache.
“I want a bed,” yawned Porc-en-Truie.
“Some supper!” growled Mont-Rognon.
Maragougnia said nothing. He was absorbed in studying the inn,
and the estimate he formed seemed far from satisfactory.
Ali Pépé stood on the defensive, blocking the entrance of the inn.
“Your lordships appear of too exalted a station for me to omit to
inform you that you will find the accommodation here very unsuited
to you.”
“Here’s frankness and disinterestedness! But where can we find
better accommodation?”
Original Size -- Medium-Size
ebookbell.com