<p>Looking at <a href="https://arxiv.org/pdf/1409.1556.pdf" rel="nofollow noreferrer">the VGG16 paper</a> and interpreting a bit, I believe the difference is basically in how many times your base network is going to see the input images, and how it will treat them as a result.</p>

<p>According the paper, random scaling is performed on input images during training (scale jitter). If you place your new dense layers on top of the frozen base network and then run the whole stack through a training procedure (second approach), I suppose the assumption is that you would not be disabling the scale jitter mechanism in the base network; thus you would see (different) randomly-scaled versions of each input image each time through your training set (each epoch).</p>

<p>If you run the input images through your base network a single time (first approach), the base is essentially running in an evaluation mode, so it does not scale the input image at all, or do any other sort of image augmentation type of transformation. You <em>could</em> do so yourself to basically add the augmented input images to your newly-transformed dataset. I suppose the book is assuming that you <em>won't</em> do this.</p>

<p>Either way, you would likely end up training on multiple epochs (multiple times through the dataset) so the second approach would carry the added load of executing the whole base network for every training sample for every epoch, whereas the first approach would only require executing the base network once for each sample offline, and then just training on the pre-transformed samples.</p>
Understanding feature extraction using a pretrained convolutional neural network
<p>In the book <a href="https://rads.stackoverflow.com/amzn/click/com/1617294438" rel="nofollow noreferrer" rel="nofollow noreferrer">Deep Learning with Python</a> by François Chollet (creator of Keras), section 5.3 (see the <a href="https://github.com/fchollet/deep-learning-with-python-notebooks/blob/master/5.3-using-a-pretrained-convnet.ipynb" rel="nofollow noreferrer">companion Jupyter notebook</a>), the following is unclear to me:</p>
<blockquote>
<p>Let's put this in practice by using the convolutional base of the VGG16 network, trained on ImageNet, to extract interesting features from our cat and dog images, and then training a cat vs. dog classifier on top of these features.</p>
<p>[...]</p>
<p>There are two ways we could proceed:</p>
<ul>
<li>Running the convolutional base over our dataset, recording its output
to a Numpy array on disk, then using this data as input to a
standalone densely-connected classifier similar to those you have seen
in the first chapters of this book. This solution is very fast and
cheap to run, because it only requires running the convolutional base
once for every input image, and the convolutional base is by far the
most expensive part of the pipeline. <strong>However, for the exact same
reason, this technique would not allow us to leverage data
augmentation at all</strong>.</li>
<li>Extending the model we have (conv_base) by adding
Dense layers on top, and running the whole thing end-to-end on the
input data. This allows us to use data augmentation, because every
input image is going through the convolutional base every time it is
seen by the model. However, for this same reason, this technique is
far more expensive than the first one.</li>
</ul>
</blockquote>
<p>Why can't we augment our data (generate more images from the existing data), run the convolutional base over the augmented dataset (one time), record its output and then use this data as input to a standalone fully-connected classifier?</p>
<p>Wouldn't it give similar results to the second alternative but be faster?</p>
<p>What am I missing?</p>