Lesson 2 discussion

Hello guys,
here’s my opinion about main assignment of lesson2:
1: use vgg16 model to train the training set, use the “7 lines code”;
2: use model.pop() method to delete the final layer;
3: use model.add() method to add a new dense layer, in order to output 2 classes

but here’s my confusion:
in lesson2.ipynb, I did’t see any training vgg model process like lesson1, such as using model.fit(), shouldn’t we train the model first and then modify the last layer?

thanks for answering.

@justinho,we already load the weights from vgg while creating the model itself, hence no need to train it before removing the last layer. You can checkout that code in vgg16.py

Once the last layer is popped out, we add a new layer with 2 outputs, then we can train the model again to our dataset.

1 Like

Thanks @Manoj ,
Do you mean these lines of code?

if so, in lesson1.ipynb, why we have to use finetune() and fit() at the first begining (in 11th line), and then use that again (in 20th and 21th line)? Would get a better result after do the finetune twice?Therefore in my mind, the first fit() is used to train the model, and the second time is uesd to finetune, I don’t know if my idea is right or not, it confuses me.

如何进行预测??
我自己也训练了一个猫和狗识别的模型,但是训练完以后我不知道怎么去预测?? 有方法可以分享下吗?

@justinho, In finetune() method, we just pop up the last layer and add a new layer depending upon our data and compile the model. In finetune(), we don’t train the model. In fit we train the model with the given data. We only need to call finetune() once, that is enough.

But we can call fit() number of times or pass on no_of epochs parameter to train the model multiple times, this is where model tries to find the optimal weights. We keep on training the model(may need to change the learning rates) until we get a good accuracy on predictions.

I have started reading https://cs231n.github.io/optimization-1/

Can I skipnotes 1, 2 which deal with SVM and other approaches?. I want to focus on the current course and not go on a very long tangent and get lost in forest of things …

Check the dogs_cats_redux.ipynb

Folder Structure should be **test/unknown/**to_be_predicted.jpg

Call

test_path = data_path + 'test/'
batches, preds = vgg.test(test_path, batch_size = batch_size*2)

So I was watching the lesson video, great as usual, but expected somebody to ask one question I had in mind on the last part of the video.

Jeremy ran a 3-epoch experiment, and the accuracy after the second epoch was lower than after the first one. The third epoch got the best result, though. Could anyone explain to me why the accuracy decreased after the second epoch?

Let me take a stab at this, in very basic terms (I’m only on lesson 2)…

Each epoch runs through the entire dataset that you’re “fitting” the model for. During this process you’re trying to get the best weights/parameters. This is the optimization part (e.g. stochastic gradient descent), as an example in lesson 2, where Jeremy showed the animated linear model, the line (model) getting closer and closer to the dotted line (actuals).

The accuracy changes because as the model is being fit through each epoch, adjustments are made in order to try to “improve” the model. Sometimes it gets better and sometimes it gets worse, but another iteration happens, it learns, readjusts and tries to improve - something to do with partial derivatives :slight_smile:

If you went through 30 instead of 3 epochs you’ll see similar results but should be improving overall. Check out the wiki below for a much better answer on SGD.

Hope that helps a little.

http://wiki.fast.ai/index.php/Lesson_2_Notes#Gradient_Descent

1 Like

Thanks Jason, very useful. So adding more epochs does not necessarily mean obtaining better resullts at each iteration, but in the overall accuracy after all the iterations instead.

I keep getting a memory error message on the following line:

trn_data = get_data(path+‘train’)

The same line corresponding to validation files works fine. This is the error I get:


MemoryError Traceback (most recent call last)
in ()
----> 1 trn_data = get_data(path+‘train’)

/home/username/courses/deeplearning1/nbs/utils.pyc in get_data(path, target_size)
135 def get_data(path, target_size=(224,224)):
136 batches = get_batches(path, shuffle=False, batch_size=1, class_mode=None, target_size=target_size)
–> 137 return np.concatenate([batches.next() for i in range(batches.nb_sample)])
138
139

MemoryError:

It looks like numpy is running out of memory when concatenating the batches. I’m working on a computer with 16 GB of RAM and a GTX 970 graphic card. Any ideas?

@Estiui, 16GB Ram won’t be sufficient when calling get_data. Even 60GB RAM p2 instance was not sufficient for me. You can add large amount of swap and try.

Thanks for your answer, Manoj, but I don’t understand what you mean with adding swap, could you please elaborate?

@Estiui, Swap is used as a overflow area when system runs out of ram. It is situated on the hard disk. You can look online on how to create the swap partition. It is generally recommended that swap should not be created on SSD.

Ah ok, you were making reference to the swap partition, my bad. Anyway, I do not have enough space to cover those more than 60 GB with swap, sadly. Is there any other workaround? Could I make it work from a different approach, if my computer can’t handle that particular function?

Sorry, I don’t have any other ideas. You just need to load the data in batches.

Ok, thank you!

Ok, so I managed to avoid memory problems by using get_batches and generators instead of get_data and numpy arrays.

Or at least that’s what I thought, because I’ve encountered a problem at the end of the lesson which I’m not able to solve. When I try to fit the model here:

fit_model(model, batches, val_batches, nb_epoch=2)

I’m getting the following error:

Epoch 1/2

ValueError Traceback (most recent call last)
in ()
----> 1 fit_model(model, batches, val_batches, nb_epoch=2)

in fit_model(model, batches, val_batches, nb_epoch)
1 def fit_model(model, batches, val_batches, nb_epoch=1):
2 model.fit_generator(batches, samples_per_epoch=batches.n, nb_epoch=nb_epoch,
----> 3 validation_data=val_batches, nb_val_samples=val_batches.n)

/home/user/anaconda2/lib/python2.7/site-packages/keras/models.pyc in fit_generator(self, generator, samples_per_epoch, nb_epoch, verbose, callbacks, validation_data, nb_val_samples, class_weight, max_q_size, nb_worker, pickle_safe, initial_epoch, **kwargs)
933 nb_worker=nb_worker,
934 pickle_safe=pickle_safe,
–> 935 initial_epoch=initial_epoch)
936
937 def evaluate_generator(self, generator, val_samples,

/home/user/anaconda2/lib/python2.7/site-packages/keras/engine/training.pyc in fit_generator(self, generator, samples_per_epoch, nb_epoch, verbose, callbacks, validation_data, nb_val_samples, class_weight, max_q_size, nb_worker, pickle_safe, initial_epoch)
1555 outs = self.train_on_batch(x, y,
1556 sample_weight=sample_weight,
-> 1557 class_weight=class_weight)
1558
1559 if not isinstance(outs, list):

/home/user/anaconda2/lib/python2.7/site-packages/keras/engine/training.pyc in train_on_batch(self, x, y, sample_weight, class_weight)
1312 sample_weight=sample_weight,
1313 class_weight=class_weight,
-> 1314 check_batch_axis=True)
1315 if self.uses_learning_phase and not isinstance(K.learning_phase, int):
1316 ins = x + y + sample_weights + [1.]

/home/user/anaconda2/lib/python2.7/site-packages/keras/engine/training.pyc in _standardize_user_data(self, x, y, sample_weight, class_weight, check_batch_axis, batch_size)
1027 self.internal_input_shapes,
1028 check_batch_axis=False,
-> 1029 exception_prefix=‘model input’)
1030 y = standardize_input_data(y, self.output_names,
1031 output_shapes,

/home/user/anaconda2/lib/python2.7/site-packages/keras/engine/training.pyc in standardize_input_data(data, names, shapes, check_batch_axis, exception_prefix)
122 ’ to have shape ’ + str(shapes[i]) +
123 ’ but got array with shape ’ +
–> 124 str(array.shape))
125 return arrays
126

ValueError: Error when checking model input: expected lambda_input_1 to have shape (None, 3, 224, 224) but got array with shape (32, 3, 256, 256)

I’m assuming it has to do with non-matching shapes of arrays, but I can’t really understand where the problem is and why that mismatch is happening.

Any help on this?

Can you do a model.summary() and check how your model is organized. I think I saw that error once where I wasn’t using Padding2D and my MaxPooling was dividing by 3. The original image sizes where divisible by 3, but the reduced size (without the padding) weren’t. So I changed the maxpooling to be by 2 or I added the padding.

VGG was trained on imagenet using images that are 224224. You have passed images 256256.

In your get_batches there will be a line that calls gen.flow_from_directory. This needs the parameter target_size=(224, 224).

1 Like