1import tensorflow as tf
2
3# stop the training with condition
4class myCallback(tf.keras.callbacks.Callback):
5 def on_epoch_end(self, epoch, logs={}): # compare at the end of each epoch
6 if(logs.get('accuracy') > 0.99):
7 self.model.stop_training = True
8
9mnist = tf.keras.datasets.mnist
10(x_train, y_train),(x_test, y_test) = mnist.load_data()
11x_train, x_test = x_train / 255.0, x_test / 255.0 # normalize
12
13callbacks = myCallback() # define the callback
14
15model = tf.keras.models.Sequential([
16 tf.keras.layers.Flatten(input_shape=(28, 28)), # Takes that square and
17 # turns it into a 1 dim
18 tf.keras.layers.Dense(512, activation=tf.nn.relu),
19 tf.keras.layers.Dense(10, activation=tf.nn.softmax) # 10 outputs
20])
21
22model.compile(optimizer='adam',
23 loss='sparse_categorical_crossentropy',
24 metrics=['accuracy'])
25
26model.fit(x_train, y_train, epochs=10, callbacks=[callbacks])
Comments (notebook):
- Adding more Neurons we have to do more calculations, slowing down the process, but get more accurate.
- The first layer in your network should be the same shape as your data.
- The number of neurons in the last layer should match the number of classes you are classifying for.
- Extra layers are often necessary.
- Flatten as the name implies, converts your multidimensional matrices (
Batch.Size x Img.W x Img.H x Kernel.Size
) to a nice single 2-dimensional matrix: (Batch.Size x (Img.W x Img.H x Kernel.Size)
). During backpropagation it also converts back your delta of size (Batch.Size x (Img.W x Img.H x Kernel.Size)
) to the original (Batch.Size x Img.W x Img.H x Kernel.Size
).
- Dense layer is of course the standard fully connected layer.
1# the same as in MINST
2# different at below line of loading data
3mnist = tf.keras.datasets.fashion_mnist
1import tensorflow as tf
2mnist = tf.keras.datasets.fashion_mnist
3
4class myCallback(tf.keras.callbacks.Callback):
5 def on_epoch_end(self, epochs, logs={}) :
6 if(logs.get('accuracy') is not None and logs.get('accuracy') >= 0.998) :
7 print('\\nReached 99.8% accuracy so cancelling training!')
8 self.model.stop_training = True
9
10(training_images, training_labels), (test_images, test_labels) = mnist.load_data()
11# Why reshape?
12# The first convolution expects a single tensor containing everything,
13# so instead of 60000 28x28x1 items in a list, we have a single 4D list
14# that is 60000x28x28x1
15#
16# training_images' shape (before reshape): (60000, 28, 28)
17# training_images' shape (after reshape): (60000, 28, 28, 1)
18# trainaing_labels' shape: (60000,)
19training_images=training_images.reshape(60000, 28, 28, 1)
20training_images=training_images / 255.0
21test_images = test_images.reshape(10000, 28, 28, 1)
22test_images=test_images/255.0
23
24model = tf.keras.models.Sequential([
25 tf.keras.layers.Conv2D(64, (3,3), activation='relu', input_shape=(28, 28, 1)),
26 tf.keras.layers.MaxPooling2D(2, 2),
27 tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
28 tf.keras.layers.MaxPooling2D(2,2),
29 tf.keras.layers.Flatten(),
30 tf.keras.layers.Dense(128, activation='relu'),
31 tf.keras.layers.Dense(10, activation='softmax')
32])
33
34model.compile(optimizer='adam',
35 loss='sparse_categorical_crossentropy',
36 metrics=['accuracy'])
37
38callbacks = myCallback()
39
40model.fit(training_images, training_labels, epochs=5, callbacks=[callbacks])
41test_loss = model.evaluate(test_images, test_labels)
1model.summary() # model detail
1Model: "sequential_1"
2_________________________________________________________________
3Layer (type) Output Shape Param
4=================================================================
5conv2d (Conv2D) (None, 26, 26, 64) 640
6 # for every image, 64 convolution has been tried
7 # 26 (=28-2) because we use 3x3 filter and we can't
8 # count on edges, so the picture is 2 smaller on x and y.
9 # if 5x5 filter => 4 smaller on x and y.
10_________________________________________________________________
11max_pooling2d (MaxPooling2D) (None, 13, 13, 64) 0
12_________________________________________________________________
13conv2d_1 (Conv2D) (None, 11, 11, 64) 36928
14_________________________________________________________________
15max_pooling2d_1 (MaxPooling2 (None, 5, 5, 64) 0
16_________________________________________________________________
17flatten_1 (Flatten) (None, 1600) 0
18_________________________________________________________________
19dense_2 (Dense) (None, 128) 204928
20_________________________________________________________________
21dense_3 (Dense) (None, 10) 1290
22=================================================================
23Total params: 243,786
24Trainable params: 243,786
25Non-trainable params: 0
Refs:
- Kernel in image processing: examples with images.
- Pooling layer: non-linear down-sampling.
More?
- Image Filtering — Lode's Computer Graphics Tutorial
- Applying Convolutions on top of our Deep neural network will make training → It depends on many factors. It might make your training faster or slower, and a poorly designed Convolutional layer may even be less efficient than a plain DNN!
- What is a Convolution? → A technique to isolate features in images
- What is a Pooling? → A technique to reduce the information in an image while maintaining features
- How do Convolutions improve image recognition? → They isolate features in images
- After passing a 3x3 conv filter over a 28x28 image, how big will the output be? → 26x26{:.img-30}
- After max pooling a 26x26 image with a 2x2 filter, how big will the output be? → 13x13
Using layer API, something like below, check more in the notebook.
1import matplotlib.pyplot as plt
2f, axarr = plt.subplots()
3
4from tensorflow.keras import models
5layer_outputs = [layer.output for layer in model.layers]
6activation_model = tf.keras.models.Model(inputs = model.input, outputs = layer_outputs)
7
8for x in range(0,4):
9 f1 = activation_model.predict(test_images[FIRST_IMAGE].reshape(1, 28, 28, 1))[x]
10 axarr[0,x].imshow(f1[0, : , :, CONVOLUTION_NUMBER], cmap='inferno')
11 axarr[0,x].grid(False)
12 ...
An example of classifying horses and humans!
1# make images more used for training
2# (focus on object, split cleary objects, label images,...)
3# also help to augmenting data (rotate, skew, flip,...)
4from tensorflow.keras.preprocessing.image import ImageDataGenerator
5
6train_datagen = ImageDataGenerator(rescale=1./255)
7 # normalize -> No need to convert images and then put in the training
8 # do the scaling on the fly
9train_generator = train_datagen.flow_from_directory(
10 train_dir, # dir contains the dir containing your images
11 # -> be careful!
12 target_size=(300, 300), # images will be resized when loaded, genial!
13 # because NN always needs that!
14 # -> experimenting with diff sizes without
15 # impacting your source data
16 batch_size=128,
17 class_mode="binary" # 2 diff things
18)
19
20test_datagen = ImageDataGenerator(rescale=1./255) # normalize
21validation_generator = test_datagen.flow_from_directory(
22 validation_dir, # dir contains the dir containing your images
23 target_size=(300, 300),
24 batch_size=32,
25 class_mode="binary"
26)
More docs: