Code
Code
Code
The Dataset
## The Dataset
In this exercise, you will train a model to recognize fresh and rotten fruits.
The dataset comes from Kaggle, a great place to go if you're interested in
starting a project after this class. The dataset structure is in the data/fruits
folder. There are 6 categories of fruits: fresh apples, fresh oranges, fresh
bananas, rotten apples, rotten oranges, and rotten bananas. This will mean that
your model will require an output layer of 6 neurons to do the categorization
successfully. You'll also need to compile the model with
categorical_crossentropy, as we have more than two categories.
Image
Load ImageNet Base Model
## Load ImageNet Base Model
We encourage you to start with a model pretrained on ImageNet. Load the model
with the correct weights, set an input shape, and choose to remove the last
layers of the model. Remember that images have three dimensions: a height, and
width, and a number of channels. Because these pictures are in color, there will
be three channels for red, green, and blue. We've filled in the input shape for
you. This cannot be changed or the assessment will fail. If you need a reference
for setting up the pretrained model, please take a look at notebook 05b where we
implemented transfer learning.
base_model = keras.applications.VGG16(
weights='imagenet',
input_shape=(224, 224, 3),
include_top=False)
from tensorflow import keras
base_model = keras.applications.VGG16(
weights='imagenet',
input_shape=(224, 224, 3),
include_top=False)
sumary()
base_model.summary()
Model: "vgg16"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_3 (InputLayer) [(None, 224, 224, 3)] 0
_________________________________________________________________
block1_conv1 (Conv2D) (None, 224, 224, 64) 1792
_________________________________________________________________
block1_conv2 (Conv2D) (None, 224, 224, 64) 36928
_________________________________________________________________
block1_pool (MaxPooling2D) (None, 112, 112, 64) 0
_________________________________________________________________
block2_conv1 (Conv2D) (None, 112, 112, 128) 73856
_________________________________________________________________
block2_conv2 (Conv2D) (None, 112, 112, 128) 147584
_________________________________________________________________
block2_pool (MaxPooling2D) (None, 56, 56, 128) 0
_________________________________________________________________
block3_conv1 (Conv2D) (None, 56, 56, 256) 295168
_________________________________________________________________
block3_conv2 (Conv2D) (None, 56, 56, 256) 590080
_________________________________________________________________
block3_conv3 (Conv2D) (None, 56, 56, 256) 590080
_________________________________________________________________
block3_pool (MaxPooling2D) (None, 28, 28, 256) 0
_________________________________________________________________
block4_conv1 (Conv2D) (None, 28, 28, 512) 1180160
_________________________________________________________________
block4_conv2 (Conv2D) (None, 28, 28, 512) 2359808
_________________________________________________________________
block4_conv3 (Conv2D) (None, 28, 28, 512) 2359808
_________________________________________________________________
block4_pool (MaxPooling2D) (None, 14, 14, 512) 0
_________________________________________________________________
block5_conv1 (Conv2D) (None, 14, 14, 512) 2359808
_________________________________________________________________
block5_conv2 (Conv2D) (None, 14, 14, 512) 2359808
_________________________________________________________________
block5_conv3 (Conv2D) (None, 14, 14, 512) 2359808
_________________________________________________________________
block5_pool (MaxPooling2D) (None, 7, 7, 512) 0
=================================================================
Total params: 14,714,688
Trainable params: 14,714,688
Non-trainable params: 0
_________________________________________________________________
Freeze Base Model
Next, we suggest freezing the base model, as done in notebook 05b. This is done
so that all the learning from the ImageNet dataset does not get destroyed in the
initial training.
x = base_model(inputs, training=False)
model.compile(loss=keras.losses.CategoricalCrossentropy(from_logits=True),
metrics=[keras.metrics.CategoricalAccuracy()])
model.compile(loss=keras.losses.CategoricalCrossentropy(from_logits=True),
metrics=[keras.metrics.CategoricalAccuracy()])
## Augment the Data
If you'd like, try to augment the data to improve the dataset. Feel free to look
at notebook 04a and notebook 05b for augmentation examples. There is also
documentation for the Keras ImageDataGenerator class. This step is optional, but
it may be helpful to get to 92% accuracy.
datagen_train = ImageDataGenerator(
samplewise_center=True, # set each sample mean to 0
rotation_range=10, # randomly rotate images in the range (degrees, 0 to 180)
zoom_range=0.1, # Randomly zoom image
width_shift_range=0.1, # randomly shift images horizontally (fraction of
total width)
height_shift_range=0.1, # randomly shift images vertically (fraction of
total height)
horizontal_flip=True, # randomly flip images
vertical_flip=False,
) # we don't expect Bo to be upside-down so we will not flip vertically
datagen_train = ImageDataGenerator(
samplewise_center=True, # set each sample mean to 0
rotation_range=10, # randomly rotate images in the range (degrees, 0 to 180)
zoom_range=0.1, # Randomly zoom image
width_shift_range=0.1, # randomly shift images horizontally (fraction of
total width)
height_shift_range=0.1, # randomly shift images vertically (fraction of
total height)
horizontal_flip=True, # randomly flip images
vertical_flip=False,
) # we don't expect Bo to be upside-down so we will not flip vertically
model.fit(train_it,
validation_data=valid_it,
steps_per_epoch=train_it.samples/train_it.batch_size,
validation_steps=valid_it.samples/valid_it.batch_size,
epochs=20)
Epoch 1/20
37/36 [==============================] - 26s 712ms/step - loss: 1.6059 -
categorical_accuracy: 0.4272 - val_loss: 1.4281 - val_categorical_accuracy:
0.6231
Epoch 2/20
37/36 [==============================] - 17s 460ms/step - loss: 1.3729 -
categorical_accuracy: 0.6827 - val_loss: 1.3399 - val_categorical_accuracy:
0.7082
Epoch 3/20
37/36 [==============================] - 17s 465ms/step - loss: 1.3108 -
categorical_accuracy: 0.7343 - val_loss: 1.3325 - val_categorical_accuracy:
0.7082
Epoch 4/20
37/36 [==============================] - 17s 463ms/step - loss: 1.2945 -
categorical_accuracy: 0.7462 - val_loss: 1.2802 - val_categorical_accuracy:
0.7660
Epoch 5/20
37/36 [==============================] - 17s 465ms/step - loss: 1.2862 -
categorical_accuracy: 0.7572 - val_loss: 1.2959 - val_categorical_accuracy:
0.7508
Epoch 6/20
37/36 [==============================] - 17s 467ms/step - loss: 1.2755 -
categorical_accuracy: 0.7690 - val_loss: 1.2879 - val_categorical_accuracy:
0.7538
Epoch 7/20
37/36 [==============================] - 17s 469ms/step - loss: 1.2701 -
categorical_accuracy: 0.7733 - val_loss: 1.2607 - val_categorical_accuracy:
0.7751
Epoch 8/20
37/36 [==============================] - 17s 464ms/step - loss: 1.2315 -
categorical_accuracy: 0.8164 - val_loss: 1.1881 - val_categorical_accuracy:
0.8480
Epoch 9/20
37/36 [==============================] - 17s 462ms/step - loss: 1.1358 -
categorical_accuracy: 0.9162 - val_loss: 1.1488 - val_categorical_accuracy:
0.8997
Epoch 10/20
37/36 [==============================] - 17s 466ms/step - loss: 1.1100 -
categorical_accuracy: 0.9442 - val_loss: 1.1201 - val_categorical_accuracy:
0.9331
Epoch 11/20
37/36 [==============================] - 17s 464ms/step - loss: 1.0948 -
categorical_accuracy: 0.9543 - val_loss: 1.1124 - val_categorical_accuracy:
0.9392
Epoch 12/20
37/36 [==============================] - 17s 467ms/step - loss: 1.0860 -
categorical_accuracy: 0.9653 - val_loss: 1.1145 - val_categorical_accuracy:
0.9301
Epoch 13/20
37/36 [==============================] - 17s 467ms/step - loss: 1.0812 -
categorical_accuracy: 0.9695 - val_loss: 1.1137 - val_categorical_accuracy:
0.9271
Epoch 14/20
37/36 [==============================] - 17s 466ms/step - loss: 1.0720 -
categorical_accuracy: 0.9763 - val_loss: 1.0911 - val_categorical_accuracy:
0.9514
Epoch 15/20
37/36 [==============================] - 17s 468ms/step - loss: 1.0705 -
categorical_accuracy: 0.9763 - val_loss: 1.1043 - val_categorical_accuracy:
0.9422
Epoch 16/20
37/36 [==============================] - 17s 468ms/step - loss: 1.0666 -
categorical_accuracy: 0.9805 - val_loss: 1.0828 - val_categorical_accuracy:
0.9574
Epoch 17/20
37/36 [==============================] - 17s 467ms/step - loss: 1.0670 -
categorical_accuracy: 0.9805 - val_loss: 1.0965 - val_categorical_accuracy:
0.9392
Epoch 18/20
37/36 [==============================] - 17s 468ms/step - loss: 1.0638 -
categorical_accuracy: 0.9848 - val_loss: 1.0849 - val_categorical_accuracy:
0.9605
Epoch 19/20
37/36 [==============================] - 17s 463ms/step - loss: 1.0602 -
categorical_accuracy: 0.9873 - val_loss: 1.0830 - val_categorical_accuracy:
0.9605
Epoch 20/20
37/36 [==============================] - 17s 463ms/step - loss: 1.0621 -
categorical_accuracy: 0.9856 - val_loss: 1.0872 - val_categorical_accuracy:
0.9574
<tensorflow.python.keras.callbacks.History at 0x7f05d4b0f828>
Unfreeze Model for Fine Tuning
If you have reached 92% validation accuracy already, this next step is optional.
If not, we suggest fine tuning the model with a very low learning rate.
Once you are satisfied with the validation accuracy, evaluate the model by
executing the following cell. The evaluate function will return a tuple, where
the first value is your loss, and the second value is your accuracy. To pass, the
model will need have an accuracy value of 92% or higher.
)
model.evaluate(valid_it, steps=valid_it.samples/valid_it.batch_size)
11/10 [================================] - 1s 134ms/step - loss: 1.0665 -
categorical_accuracy: 0.9757
[1.066458821296692, 0.975683867931366]
Run the Assessment
## Run the Assessment
To assess your model run the following two cells.
Image