Deep Learning with Python - Unit 2: Convolutional Neural Networks

Page 1 sur 17Lecteur de document UniversityLib

Deep Learning with Python - Unit 2: Convolutional Neural Networks

Computer Science - Deep Learning · lab

Voir tous les documents en intelligence artificielle et données

Deep learnig with Python

Unit 2 : Convolutional Neural Networks

Tutor: Dr. Haithem Hermessi

November 2021

A/Y: 2021/2022

1

1 Convolutional Neural Networks

1.1 MNIST Data Set - Basic Approach

1.1.1 Get the MNIST Data

In [3]: import tensorflow as tf

from tensorflow.examples.tutorials.mnist import input_data

mnist = input_data.read_data_sets("MNIST_data/",one_hot=True)

Extracting MNIST_data/train-images-idx3-ubyte.gz

Extracting MNIST_data/train-labels-idx1-ubyte.gz

Extracting MNIST_data/t10k-images-idx3-ubyte.gz

Extracting MNIST_data/t10k-labels-idx1-ubyte.gz

In [4]: mnist.train.images

Out[4]: array([[ 0., 0., 0., ..., 0., 0., 0.],

[ 0., 0., 0., ..., 0., 0., 0.],

[ 0., 0., 0., ..., 0., 0., 0.],

...,

[ 0., 0., 0., ..., 0., 0., 0.],

[ 0., 0., 0., ..., 0., 0., 0.],

[ 0., 0., 0., ..., 0., 0., 0.]], dtype=float32)

In [5]: mnist.train.num_examples

Out[5]: 55000

In [6]: mnist.test.num_examples

Out[6]: 10000

In [7]: mnist.validation.num_examples

Out[7]: 5000

2

1.1.2 Visualizing the Data

In [9]: import matplotlib.pyplot as plt

%matplotlib inline

mnist.train.images[1].shape

plt.imshow(mnist.train.images[1].reshape(28,28))

Out[9]: <matplotlib.image.AxesImage at 0x16883d333c8>

In [10]: plt.imshow(mnist.train.images[1].reshape(28,28),cmap='gist_gray')

Out[10]: <matplotlib.image.AxesImage at 0x16883d9b198>

3

In [11]: mnist.train.images[1].max()

Out[11]: 1.0

In [13]: plt.imshow(mnist.train.images[1].reshape(784,1),

cmap='gist_gray',aspect=0.02)

Out[13]: <matplotlib.image.AxesImage at 0x16883e46b70>

4

1.1.3 Create the Model

In [14]: x = tf.placeholder(tf.float32,shape=[None,784])

10 because 0-9 possible numbers

W = tf.Variable(tf.zeros([784,10]))

b = tf.Variable(tf.zeros([10]))

Create the Graph

y = tf.matmul(x,W) + b

Loss and Optimizer

y_true = tf.placeholder(tf.float32,[None,10])

Cross Entropy

cross_entropy = tf.reduce_mean(

tf.nn.softmax_cross_entropy_with_logits(

labels=y_true, logits=y))

optimizer = tf.train.GradientDescentOptimizer(

learning_rate=0.5)

train = optimizer.minimize(cross_entropy)

1.1.4 Create Session

In [16]: init = tf.global_variables_initializer()

with tf.Session() as sess:

sess.run(init)

Train the model for 1000 steps on the training set

Using built in batch feeder from mnist for convenience

for step in range(1000):

batch_x , batch_y = mnist.train.next_batch(100)

sess.run(train,feed_dict={x:batch_x,y_true:batch_y})

Test the Train Model

matches = tf.equal(tf.argmax(y,1),tf.argmax(y_true,1))

acc = tf.reduce_mean(tf.cast(matches,tf.float32))

print(sess.run(acc,feed_dict={

x:mnist.test.images,y_true:mnist.test.labels}))

0.9159

1.2 MNIST with CNN

In [17]: import tensorflow as tf

from tensorflow.examples.tutorials.mnist import input_data

mnist = input_data.read_data_sets("MNIST_data/",one_hot=True)

Extracting MNIST_data/train-images-idx3-ubyte.gz

Extracting MNIST_data/train-labels-idx1-ubyte.gz

Extracting MNIST_data/t10k-images-idx3-ubyte.gz

5

Extracting MNIST_data/t10k-labels-idx1-ubyte.gz

1.2.1 Helper Functions

In [18]: """

Function to help intialize random weights for fully connected

or convolutional layers, we leave the shape attribute as a

parameter for this.

"""

def init_weights(shape):

init_random_dist = tf.truncated_normal(shape, stddev=0.1)

return tf.Variable(init_random_dist)

def init_bias(shape):

init_bias_vals = tf.constant(0.1, shape=shape)

return tf.Variable(init_bias_vals)

Create a 2D convolution using builtin conv2d from TF. From those docs:

Publicité

Computes a 2-D convolution given 4-D input and filter tensors.

Given an input tensor of shape [batch, in_height, in_width, in_channels] and a lter /

kernel tensor of shape [filter_height, filter_width, in_channels, out_channels], this op

performs the following:

1. Flattens the lter to a 2-D matrix with shape [filter_height filter_width

in_channels, output_channels].

2. Extracts image patches from the input tensor to form a virtual tensor of shape [batch,

out_height, out_width,

filter_height filter_width in_channels].

3. For each patch, right-multiplies the lter matrix and the image patch vector.

Create a max pooling layer, again using built in TF functions:

Performs the max pooling on the input.

Args:

value: A 4-D Tensor with shape [batch, height, width, channels] and

type tf.float32.

ksize: A list of ints that has length >= 4. The size of the window for

each dimension of the input tensor.

strides: A list of ints that has length >= 4. The stride of the sliding

window for each dimension of the input tensor.

padding: A string, either 'VALID' or 'SAME'.

Using the conv2d function, we'll return an actual convolutional layer here that uses an ReLu

activation.

In [19]: def conv2d(x, W):

return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')

def max_pool_2by2(x):

return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],

6

strides=[1, 2, 2, 1], padding='SAME')

def convolutional_layer(input_x, shape):

W = init_weights(shape)

b = init_bias([shape[3]])

return tf.nn.relu(conv2d(input_x, W) + b)

def normal_full_layer(input_layer, size):

input_size = int(input_layer.get_shape()[1])

W = init_weights([input_size, size])

b = init_bias([size])

return tf.matmul(input_layer, W) + b

1.2.2 Placeholders

In [20]: x = tf.placeholder(tf.float32,shape=[None,784])

y_true = tf.placeholder(tf.float32,shape=[None,10])

1.2.3 Layers

In [21]: x_image = tf.reshape(x,[-1,28,28,1])

"""

Using a 6by6 filter here, used 5by5 in video,

you can play around with the filter size. You

can change the 32 output, that essentially

represents the amount of filters used.You need

to pass in 32 to the next input though, the 1

comes from the original input of a single image.

"""

convo_1 = convolutional_layer(x_image,shape=[6,6,1,32])

convo_1_pooling = max_pool_2by2(convo_1)

"""

Using a 6by6 filter here, used 5by5 in video,

you can play around with the filter size. You can

actually change the 64 output if you want, you can

think of that as a representation of the amount of

6by6 filters used.

"""

convo_2 = convolutional_layer(convo_1_pooling,shape=[6,6,32,64])

convo_2_pooling = max_pool_2by2(convo_2)

"""

Why 7 by 7 image? Because we did 2 pooling layers,

so (28/2)/2 = 7. 64 then just comes from the output

of the previous Convolution.

"""

convo_2_flat = tf.reshape(convo_2_pooling,[-1,7764])

full_layer_one = tf.nn.relu(normal_full_layer(convo_2_flat,1024))

NOTE THE PLACEHOLDER HERE!

hold_prob = tf.placeholder(tf.float32)

full_one_dropout = tf.nn.dropout(full_layer_one,keep_prob=hold_prob)

7

y_pred = normal_full_layer(full_one_dropout,10)

1.2.4 Loss Function, Optimizer, Init

In [23]: cross_entropy = tf.reduce_mean(

tf.nn.softmax_cross_entropy_with_logits(

labels=y_true,logits=y_pred))

optimizer = tf.train.AdamOptimizer(learning_rate=0.0001)

train = optimizer.minimize(cross_entropy)

init = tf.global_variables_initializer()

1.2.5 Session

In [24]: # You might want to use graphics acceleration.

steps = 5000

with tf.Session() as sess:

sess.run(init)

for i in range(steps):

batch_x , batch_y = mnist.train.next_batch(50)

sess.run(train,feed_dict={x:batch_x,y_true:batch_y,hold_prob:0.5})

PRINT OUT A MESSAGE EVERY 100 STEPS

if i%500 == 0:

print('Currently on step {}'.format(i))

print('Accuracy is:')

Test the Train Model

matches = tf.equal(tf.argmax(y_pred,1),tf.argmax(y_true,1))

acc = tf.reduce_mean(tf.cast(matches,tf.float32))

print(sess.run(acc,feed_dict={

x:mnist.test.images,y_true:mnist.test.labels,hold_prob:1.0}))

print('\n')

Currently on step 0

Publicité

Accuracy is:

0.0851

Currently on step 500

Accuracy is:

0.9476

Currently on step 1000

Accuracy is:

0.9651

Currently on step 1500

Accuracy is:

8

0.9742

step

Currently on

Accuracy is:

0.9773

2000

step

Currently on

Accuracy is:

0.9814

2500

step

Currently on

Accuracy is:

0.9832

3000

step

Currently on

Accuracy is:

0.9827

3500

step

Currently on

Accuracy is:

0.9853

4000

step

Currently on

Accuracy is:

0.9857

4500

1.3 CNN Exercise

We'll be using the CIFAR-10 dataset, which is very famous dataset for image recognition!

The CIFAR-10 dataset consists of 60000 32x32 colour images in 10 classes, with 6000 images

per class. There are 50000 training images and 10000 test images.

The dataset is divided into ve training batches and one test batch, each with 10000 images.

The test batch contains exactly 1000 randomly-selected images from each class. The training

batches contain the remaining images in random order, but some training batches may contain

more images from one class than another. Between them, the training batches contain exactly 5000

images from each class.

9

1.3.1 Step 0: Get the Data

The archive contains the les data_batch_1, data_batch_2, ..., data_batch_5, as well as test_batch.

Each of these les is a Python "pickled" object produced with cPickle.

Load the Data. Use the Code Below to load the data:

In [1]: CIFAR_DIR = 'cifar-10-batches-py/'

def unpickle(file):

import pickle

with open(file, 'rb') as fo:

cifar_dict = pickle.load(fo, encoding='bytes')

return cifar_dict

dirs = ['batches.meta','data_batch_1',

'data_batch_2','data_batch_3',

'data_batch_4','data_batch_5',

'test_batch']

all_data = [0,1,2,3,4,5,6]

for i,direc in zip(all_data,dirs):

all_data[i] = unpickle(CIFAR_DIR+direc)

batch_meta = all_data[0]

data_batch1 = all_data[1]

data_batch2 = all_data[2]

data_batch3 = all_data[3]

data_batch4 = all_data[4]

data_batch5 = all_data[5]

test_batch = all_data[6]

data_batch1.keys()

Out[1]: dict_keys([b'batch_label', b'labels', b'data', b'filenames'])

Loaded in this way, each of the batch les contains a dictionary with the following elements:

  • data -- a 10000x3072 numpy array of uint8s. Each row of the array stores a 32x32 colour image.

The rst 1024 entries contain the red channel values, the next 1024 the green, and the nal 1024

the blue. The image is stored in row-major order, so that the rst 32 entries of the array are the

red channel values of the rst row of the image. * labels -- a list of 10000 numbers in the range 0-9.

The number at index i indicates the label of the ith image in the array data.

The dataset contains another le, called batches.meta. It too contains a Python dictionary

object. It has the following entries:

label_names -- a 10-element list which gives meaningful names to the numeric labels in the

labels array described above. For example, label_names[0] == "airplane", label_names[1] ==

"automobile", etc.

1.3.2 Display a single image using matplotlib.

In [2]: import matplotlib.pyplot as plt

import numpy as np

%matplotlib inline

10

X = data_batch1[b"data"]

"""

Images are flattened, so we transpose here to view!

"""

X = X.reshape(10000, 3, 32, 32).transpose(0,2,3,1).astype("uint8")

Publicité

plt.imshow(X[0])

Out[2]: <matplotlib.image.AxesImage at 0x2172221a828>

In [3]: plt.imshow(X[1])

Out[3]: <matplotlib.image.AxesImage at 0x217222acbe0>

11

In [4]: plt.imshow(X[4])

Out[4]: <matplotlib.image.AxesImage at 0x2172231b630>

12

1.3.3 Helper Functions for Dealing With Data.

In [5]: def one_hot_encode(vec, vals=10):

#For use to one-hot encode the 10- possible labels

n = len(vec)

out = np.zeros((n, vals))

out[range(n), vec] = 1

return out

class CifarHelper():

def __init__(self):

self.i = 0

self.all_train_batches = [

data_batch1,data_batch2,

data_batch3,data_batch4,data_batch5]

self.test_batch = [test_batch]

self.training_images = None

self.training_labels = None

self.test_images = None

self.test_labels = None

def set_up_images(self):

print("Setting Up Training Images and Labels")

self.training_images = np.vstack(

[d[b"data"] for d in self.all_train_batches])

train_len = len(self.training_images)

self.training_images = self.training_images.reshape(

train_len,3,32,32).transpose(0,2,3,1)/255

self.training_labels = one_hot_encode(

np.hstack([d[b"labels"] for d in self.all_train_batches]), 10)

print("Setting Up Test Images and Labels")

self.test_images = np.vstack([d[b"data"] for d in self.test_batch])

test_len = len(self.test_images)

self.test_images = self.test_images.reshape(

test_len,3,32,32).transpose(0,2,3,1)/255

self.test_labels = one_hot_encode(np.hstack(

[d[b"labels"] for d in self.test_batch]), 10)

def next_batch(self, batch_size):

x = self.training_images[self.i:self.i+batch_size].reshape(batch_size,32,32,3) y

= self.training_labels[self.i:self.i+batch_size]

self.i = (self.i + batch_size) % len(self.training_images)

return x, y

In [6]: # Before Your tf.Session run these two lines

ch = CifarHelper()

ch.set_up_images()

During your session to grab the next batch use this line

(Just like we did for mnist.train.next_batch)

batch = ch.next_batch(100)

13

Setting Up Training Images and Labels

Setting Up Test Images and Labels

1.3.4 Creating the Model

Import tensor ow

Create 2 placeholders, x and y_true. Their shapes should be:

Create one more placeholder called hold_prob. No need for shape here. This placeholder

will just hold a single probability for the dropout.

Helper Functions Grab the helper functions from MNIST with CNN (or recreate them here

yourself for a hard challenge!). You'll need:

init_weights

init_bias

conv2d

max_pool_2by2

convolutional_layer

normal_full_layer

In [9]: x = tf.placeholder(tf.float32,shape=[None,32,32,3])

y_true = tf.placeholder(tf.float32,shape=[None,10])

hold_prob = tf.placeholder(tf.float32)

def init_weights(shape):

init_random_dist = tf.truncated_normal(shape, stddev=0.1)

return tf.Variable(init_random_dist)

def init_bias(shape):

init_bias_vals = tf.constant(0.1, shape=shape)

return tf.Variable(init_bias_vals)

def conv2d(x, W):

return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')

def max_pool_2by2(x):

return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],

strides=[1, 2, 2, 1], padding='SAME')

def convolutional_layer(input_x, shape):

W = init_weights(shape)

b = init_bias([shape[3]])

return tf.nn.relu(conv2d(input_x, W) + b)

def normal_full_layer(input_layer, size):

input_size = int(input_layer.get_shape()[1])

W = init_weights([input_size, size])

b = init_bias([size])

return tf.matmul(input_layer, W) + b

14

1.3.5 Create the Layers

Create a convolutional layer and a pooling layer as we did for MNIST. Its up to you what the

2d size of the convolution should be, but the last two digits need to be 3 and 32 because of the

3 color channels and 32 pixels. So for example you could use:

convo_1 = convolutional_layer(x,shape=[4,4,3,32])

Create the next convolutional and pooling layers. The last two dimensions of the convo_2

Publicité

layer should be 32,64

Now create a attened layer by reshaping the pooling layer into [-1,8 8 64] or [-1,4096]

Create a new full layer using the normal_full_layer function and passing in your attend

convolutional 2 layer with size=1024. (You could also choose to reduce this to something like

512)

Now create the dropout layer with tf.nn.dropout, remember to pass in your hold_prob place-

holder.

Finally set the output to y_pred by passing in the dropout layer into the normal_full_layer

function. The size should be 10 because of the 10 possible labels

In [10]: convo_1 = convolutional_layer(x,shape=[4,4,3,32])

convo_1_pooling = max_pool_2by2(convo_1)

convo_2 = convolutional_layer(convo_1_pooling,shape=[4,4,32,64])

convo_2_pooling = max_pool_2by2(convo_2)

convo_2_flat = tf.reshape(convo_2_pooling,[-1,8864])

full_layer_one = tf.nn.relu(normal_full_layer(convo_2_flat,1024))

full_one_dropout = tf.nn.dropout(full_layer_one,keep_prob=hold_prob)

y_pred = normal_full_layer(full_one_dropout,10)

1.3.6 Loss Function, Optimizer, Init

Create a cross_entropy loss function

Create the optimizer using an Adam Optimizer.

Create a variable to intialize all the global tf variables.

In [11]: cross_entropy = tf.reduce_mean(

tf.nn.softmax_cross_entropy_with_logits(labels=y_true,logits=y_pred))

optimizer = tf.train.AdamOptimizer(learning_rate=0.001)

train = optimizer.minimize(cross_entropy)

init = tf.global_variables_initializer()

15

1.3.7 Graph Session

Perform the training and test print outs in a Tf session and run your model!

In [12]: with tf.Session() as sess:

sess.run(tf.global_variables_initializer())

for i in range(5000):

batch = ch.next_batch(100)

sess.run(train, feed_dict={

x: batch[0], y_true: batch[1], hold_prob: 0.5})

PRINT OUT A MESSAGE EVERY 1000 STEPS

if i%500 == 0:

print('Currently on step {}'.format(i))

print('Accuracy is:')

Test the Train Model

matches = tf.equal(tf.argmax(y_pred,1),tf.argmax(y_true,1))

acc = tf.reduce_mean(tf.cast(matches,tf.float32))

print(sess.run(acc,feed_dict={

x:ch.test_images,y_true:ch.test_labels,hold_prob:1.0}))

print('\n')

step 0

Currently on

Accuracy is:

0.1

step

Currently on

Accuracy is:

0.5624

500

step

Currently on

Accuracy is:

0.6256

1000

step

Currently on

Accuracy is:

0.6316

1500

step

Currently on

Accuracy is:

0.6698

2000

step

Currently on

Accuracy is:

0.6721

2500

16

step 3000

Currently on

Accuracy is:

0.673

step

Currently on

Accuracy is:

0.6903

3500

step

Currently on

Accuracy is:

0.6932

4000

step

Currently on

Accuracy is:

0.6909

4500

17