Lesson 2 discussion

ok … got it … so basically they are identical, if like in the above example, one of the filters was rotated by 90 degrees for example.

1 Like

Precisely :slight_smile:

A small correction to your point earlier:
"look closely at the code at the top of the image. It shows that:

convolve(arr, np.rot90(filt, 2))

gives identical results to:

convolve(arr, np.rot90(filt, 2)) >>should instead be >> correlate(arr, filt)

"

1 Like

Oops! Thanks. Will edit it now.

I’m getting to this a week later so you probably already solved this issue but for others who may encounter it:
I had to install tensorflow through the jupyter notebook, by:

  1. connecting to the main jupyter page
  2. clicking the ‘Conda’ link at the top
  3. search for ‘tensorflow’ in the bottom left
  4. clicking the right arrow to get it to install

Now I can run through the convolution-intro.ipynb and tensorflow imports properly.

4 Likes

Quick question - I was revisiting all the notebooks and for the lesson2.ipynb notebook and I get the error message below. The valid/ and train/ subdirectories have the required structure/content, was wondering if anyone has run into this. Thanks!

Message

Notebook line:
val_data = get_data(val_batches)

Error:

TypeError Traceback (most recent call last)
in ()
----> 1 val_data = get_data(val_batches)

/home/ubuntu/nbs/utils.pyc in get_data(path)
77
78 def get_data(path):
—> 79 batches = get_batches(path, shuffle=False, batch_size=1, class_mode=None)
80 return np.concatenate([batches.next() for i in range(batches.nb_sample)])
81

/home/ubuntu/nbs/utils.pyc in get_batches(dirname, gen, shuffle, batch_size, class_mode)
69 def get_batches(dirname, gen=image.ImageDataGenerator(), shuffle=True, batch_size=4, class_mode=‘categorical’):
70 return gen.flow_from_directory(dirname, target_size=(224,224),
—> 71 class_mode=class_mode, shuffle=shuffle, batch_size=batch_size)
72
73

/home/ubuntu/anaconda2/lib/python2.7/site-packages/keras/preprocessing/image.pyc in flow_from_directory(self, directory, target_size, color_mode, classes, class_mode, batch_size, shuffle, seed, save_to_dir, save_prefix, save_format)
288 dim_ordering=self.dim_ordering,
289 batch_size=batch_size, shuffle=shuffle, seed=seed,
–> 290 save_to_dir=save_to_dir, save_prefix=save_prefix, save_format=save_format)
291
292 def standardize(self, x):

/home/ubuntu/anaconda2/lib/python2.7/site-packages/keras/preprocessing/image.pyc in init(self, directory, image_data_generator, target_size, color_mode, dim_ordering, classes, class_mode, batch_size, shuffle, seed, save_to_dir, save_prefix, save_format)
553 if not classes:
554 classes = []
–> 555 for subdir in sorted(os.listdir(directory)):
556 if os.path.isdir(os.path.join(directory, subdir)):
557 classes.append(subdir)

TypeError: coercing to Unicode: need string or buffer, DirectoryIterator found

2 Likes

get_data() has been changed to take a path, rather than a generator. So it should be something like:

get_data(path+'train')

Search the forum for ‘get_data’ to learn about the reason behind this change, if you’re interested.

6 Likes

great, thanks !

I’m currently looking at the Kaggle Leaf Classification Competition. They give .csv files for train and test, and a file of images called “images”. I am guessing that I need to use a system like you did with MNIST to filter the given image. However, I’m not exactly sure how I take the data (Image below) and access it in a script. I saw that for MNIST, you did “data = np.load(“MNIST_data/train.npz”)”. Why did you write .npz even though Kaggle gives the MNIST data as .csv?

Image of .csv file:
(in Excel):

(in Jupyter Notebook):

Also, what do “Margin”, “Shape”, and “Texture” mean? I’m guessing one of them is a value from white to black.

The kaggle data page has brief descriptions of each of those columns. To view and use the images, see the examples here: https://www.kaggle.com/c/leaf-classification/kernels .

The .npz file is a file I saved myself, using numpy.

To open a csv file, use pandas.open_csv()

I ran into a memory issue running the 2nd notebook on my p2 instance when using get_data(path + ‘train’) from the most recent utils.py. This is the output of free -m after loading train and valid sets using get_data:

total used free shared buff/cache available
Mem: 61406 56423 3294 8 1688 4576
Swap: 0 0 0

Even with a batch_size of 4 this didn’t leave me enough resources to run the rest of the notebook. However, I found that if I saved the arrays using save_array and then restarted the kernel and loaded the data using load_array, my memory usage was this:

total used free shared buff/cache available
Mem: 61406 29426 24046 8 7932 31572
Swap: 0 0 0

I was not executing the load_array lines on the original runthrough, so it’s not just an issue of duplicating the data. I was also not running any other notebooks or processes at the time. Any ideas what’s causing this behavior?

If you’re having memory troubles, use get_batches instead of get_data. get_batches only loads a batch of images into memory at a time. get_data loads the entire dataset into memory at once!

2 Likes

The lesson 2 notebook contains the code below for training multiple dense layers. What I don’t understand is:

  1. This code doesn’t seem to call finetune (as is done in the code above in the notebook to retrain the final dense layer in vgg), so I think we would need to call it for all the dense layers when implementing this code for a particular model?
  2. The note above this code in the notebook indicates to not skip the step of fine-tuning just the final layer first. Again, fine-tuning the final layer doesn’t seem to be called in this code, correct?

layers = model.layers

Get the index of the first dense layer…

first_dense_idx = [index for index,layer in enumerate(layers) if type(layer) is Dense][0]

…and set this and all subsequent layers to trainable

for layer in layers[first_dense_idx:]: layer.trainable=True

Thanks in advance.

Byron

The earlier section ‘Retrain last layer’s linear model’ is where the final layer was modified and trained. The section you’re looking at uses the model that was trained in that earlier section.

I realized that I was confused conceptually with fine tuning and training. In particular, I was thinking that the code I referenced was designed to replace and retrain the additional dense layers in that model (beyond the first dense layer), when in fact it’s just retraining those additional dense layers.

In some cases we may need to replace (and then retrain) multiple dense layers, correct?

You only really need to replace the last layer, so that it’s predicting the correct number of classes. You can still retrain the others. The only reason to replace more layers is if you want to change the architecture.

@rachel Is there any difference between method onehot() in second lesson notebook and keras’s to_categorical() ?

@janardhanp22 onehot is a wrapper around sklearn’s OneHotEncoder
http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html

In running a test case, I saw that onehot only encodes for the categories you give it, whereas to_categorical encodes for all categories between [0,max] for the max value you give it (even if you don’t use some of those values).

onehot(np.array([3,0,0,4]))
array([[ 0., 1., 0.],
[ 1., 0., 0.],
[ 1., 0., 0.],
[ 0., 0., 1.]])
to_categorical(np.array([3,0,0,4]))
array([[ 0., 0., 0., 1., 0.],
[ 1., 0., 0., 0., 0.],
[ 1., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 1.]])

@janardhanp22 @rachel it so happens I was looking at this with @bckenstler today - it appears that to_categorical() is better, since (for the reason Rachel mentions) it will consistently encode the validation set and training set in the same way.

1 Like

I took some time off work this week to go over the contents of the class, especially the code I didn’t have a chance to really seriously dive into. I decided to explore the ResNet model. I learned that to do this, first I had to save some VGG weights with which to build ResNet.

So I looked back at Lesson 2. I pulled out both the Lesson2.ipynb and the redux.ipynb. Both of them have the basic VGG model.

Starting with the lesson2.ipynb, everything is going great, the model is fine. The prediction are made here, and I believe should have a shape of (22500, 1000). I’m trying to return the basic ImageNet-style results, which consist of 1000 classes. But after

trn_features = model.predict(trn_data, batch_size=batch_size)
val_features = model.predict(val_data, batch_size=batch_size)
I run
trn_features.shape
which gives me
(22500, 512, 7, 7)

Clearly, after the final conv layer, I’ve got 512 channels of 7x7. But I need to have the normal ImageNet output of 1000 classes, so I can send it into this linear model:

lm = Sequential([ Dense(2, activation='softmax', input_shape=(1000,)) ])

Why is the vanilla VGG no longer returning 1000 classes? Has the VGG class changed so much between weeks 2 and 7? I’ve rewatched tons of different parts of the videos, but most likely, I’ve absolutely completely missed something (probably fundamental).

Thanks for your time.