In the event you’ve checked out Keras fashions on Github, you’ve most likely observed that there are some alternative ways to create fashions in Keras. There’s the Sequential mannequin which lets you outline a complete mannequin in a single line, often with some line breaks for readability, then there’s the useful interface that enables for extra sophisticated mannequin architectures, and there’s additionally the Mannequin subclass which helps reusability. On this article, we’re going to discover the alternative ways to create fashions in Keras, together with their benefits and downsides to equip you with the data it’s essential create your individual machine studying fashions in Keras.
After you finishing this tutorial, you’ll study:
- Completely different ways in which Keras gives to construct fashions
- Tips on how to use the Sequential class, useful interface, and subclassing keras.Mannequin to construct Keras fashions
- When to make use of the totally different strategies to create Keras fashions
Let’s get began!

Three Methods to Construct Machine Studying Fashions in Keras
Picture by Mike Szczepanski. Some rights reserved.
Overview
This tutorial is break up into 3 elements, masking the alternative ways to constructing machine studying fashions in Keras:
- Utilizing the Sequential class
- Utilizing Keras’ useful interface
- Subclassing keras.Mannequin
Utilizing the Sequential class
The Sequential Mannequin is simply because the title implies. It consists of a sequence of layers, one after the opposite. From the Keras documentation,
“A Sequential mannequin is suitable for a plain stack of layers the place every layer has precisely one enter tensor and one output tensor.”
It’s a easy, easy-to-use option to get began constructing your Keras mannequin. To begin, import the Tensorflow, after which the Sequential mannequin:
import tensorflow as tf from tensorflow.keras import Sequential |
Then, we are able to begin constructing our machine studying mannequin by stacking numerous layers collectively. For our instance, let’s construct a LeNet5 mannequin with the basic CIFAR-10 picture dataset because the enter:
from tensorflow.keras.layers import Dense, Enter, Flatten, Conv2D, MaxPool2D
mannequin = Sequential([ Input(shape=(32,32,3,)), Conv2D(filters=6, kernel_size=(5,5), padding=“same”, activation=“relu”), MaxPool2D(pool_size=(2,2)), Conv2D(filters=16, kernel_size=(5,5), padding=“same”, activation=“relu”), MaxPool2D(pool_size=(2, 2)), Conv2D(filters=120, kernel_size=(5,5), padding=“same”, activation=“relu”), Flatten(), Dense(units=84, activation=“relu”), Dense(units=10, activation=“softmax”), ])
print (mannequin.abstract()) |
Discover that we’re simply passing in an array of the layers that we wish our mannequin to include into the Sequential mannequin constructor. mannequin.abstract(), we are able to see the mannequin’s structure.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
_________________________________________________________________ Layer (sort) Output Form Param # ================================================================= conv2d_3 (Conv2D) (None, 32, 32, 6) 456
max_pooling2d_2 (MaxPooling (None, 16, 16, 6) 0 2D)
conv2d_4 (Conv2D) (None, 16, 16, 16) 2416
max_pooling2d_3 (MaxPooling (None, 8, 8, 16) 0 2D)
conv2d_5 (Conv2D) (None, 8, 8, 120) 48120
flatten_1 (Flatten) (None, 7680) 0
dense_2 (Dense) (None, 84) 645204
dense_3 (Dense) (None, 10) 850
================================================================= Whole params: 697,046 Trainable params: 697,046 Non–trainable params: 0 _________________________________________________________________ |
And simply to check out the mannequin, let’s go forward and cargo the CIFAR-10 dataset and run mannequin.compile and mannequin.match:
from tensorflow import keras
(trainX, trainY), (testX, testY) = keras.datasets.cifar10.load_data() mannequin.compile(optimizer=“adam”, loss=tf.keras.losses.SparseCategoricalCrossentropy(), metrics=“acc”)
historical past = mannequin.match(x=trainX, y=trainY, batch_size=256, epochs=10, validation_data=(testX, testY)) |
which supplies us this output.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
Epoch 1/10 196/196 [==============================] – 13s 10ms/step – loss: 2.7669 – acc: 0.3648 – val_loss: 1.4869 – val_acc: 0.4713 Epoch 2/10 196/196 [==============================] – 2s 8ms/step – loss: 1.3883 – acc: 0.5097 – val_loss: 1.3654 – val_acc: 0.5205 Epoch 3/10 196/196 [==============================] – 2s 8ms/step – loss: 1.2239 – acc: 0.5694 – val_loss: 1.2908 – val_acc: 0.5472 Epoch 4/10 196/196 [==============================] – 2s 8ms/step – loss: 1.1020 – acc: 0.6120 – val_loss: 1.2640 – val_acc: 0.5622 Epoch 5/10 196/196 [==============================] – 2s 8ms/step – loss: 0.9931 – acc: 0.6498 – val_loss: 1.2850 – val_acc: 0.5555 Epoch 6/10 196/196 [==============================] – 2s 9ms/step – loss: 0.8888 – acc: 0.6903 – val_loss: 1.3150 – val_acc: 0.5646 Epoch 7/10 196/196 [==============================] – 2s 8ms/step – loss: 0.7882 – acc: 0.7229 – val_loss: 1.4273 – val_acc: 0.5426 Epoch 8/10 196/196 [==============================] – 2s 8ms/step – loss: 0.6915 – acc: 0.7582 – val_loss: 1.4574 – val_acc: 0.5604 Epoch 9/10 196/196 [==============================] – 2s 8ms/step – loss: 0.5934 – acc: 0.7931 – val_loss: 1.5304 – val_acc: 0.5631 Epoch 10/10 196/196 [==============================] – 2s 8ms/step – loss: 0.5113 – acc: 0.8214 – val_loss: 1.6355 – val_acc: 0.5512 |
That’s fairly good for a primary move at a mannequin. Placing the code for LeNet5 utilizing a Sequential mannequin collectively,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
import tensorflow as tf from tensorflow.keras import Sequential from tensorflow.keras.layers import Dense, Enter, Flatten, Conv2D, MaxPool2D
(trainX, trainY), (testX, testY) = keras.datasets.cifar10.load_data()
mannequin = Sequential([ Input(shape=(32,32,3,)), Conv2D(filters=6, kernel_size=(5,5), padding=“same”, activation=“relu”), MaxPool2D(pool_size=(2,2)), Conv2D(filters=16, kernel_size=(5,5), padding=“same”, activation=“relu”), MaxPool2D(pool_size=(2, 2)), Conv2D(filters=120, kernel_size=(5,5), padding=“same”, activation=“relu”), Flatten(), Dense(units=84, activation=“relu”), Dense(units=10, activation=“softmax”), ])
print (mannequin.abstract())
mannequin.compile(optimizer=“adam”, loss=tf.keras.losses.SparseCategoricalCrossentropy(), metrics=“acc”) historical past = mannequin.match(x=trainX, y=trainY, batch_size=256, epochs=10, validation_data=(testX, testY)) |
Now, let’s discover what the opposite methods of setting up Keras fashions can do, beginning with the useful interface!
Utilizing Keras’ Useful Interface
The subsequent methodology of setting up Keras fashions that we’ll be exploring is utilizing Keras’ useful interface. The useful interface makes use of the layers as capabilities as a substitute, taking in a Tensor and outputting a Tensor as nicely. The useful interface is a extra versatile method of representing a Keras mannequin as we’re not restricted solely to sequential fashions which have layers stacked on prime of each other. As an alternative, we are able to construct fashions that department into a number of paths, have a number of inputs, and so on.
Contemplate an Add
layer that takes inputs from two or extra paths and provides the tensors collectively.
Since this can’t be represented as a linear stack of layers because of the a number of inputs, we’d be unable to outline it utilizing a Sequential object. Right here’s the place Keras’ useful interface is available in. We will outline an Add layer with two enter tensors as such:
from tensorflow.keras.layers import Add add_layer = Add()([layer1, layer2]) |
Now that we’ve seen a fast instance of the useful interface, let’s check out what the LeNet5 mannequin that we outlined by instantiating a Sequential class would seem like utilizing a useful interface.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
import tensorflow as tf from tensorflow.keras.layers import Dense, Enter, Flatten, Conv2D, MaxPool2D from tensorflow.keras.fashions import Mannequin
input_layer = Enter(form=(32,32,3,)) x = Conv2D(filters=6, kernel_size=(5,5), padding=“identical”, activation=“relu”)(input_layer) x = MaxPool2D(pool_size=(2,2))(x) x = Conv2D(filters=16, kernel_size=(5,5), padding=“identical”, activation=“relu”)(x) x = MaxPool2D(pool_size=(2, 2))(x) x = Conv2D(filters=120, kernel_size=(5,5), padding=“identical”, activation=“relu”)(x) x = Flatten()(x) x = Dense(models=84, activation=“relu”)(x) x = Dense(models=10, activation=“softmax”)(x)
mannequin = Mannequin(inputs=input_layer, outputs=x)
print(mannequin.abstract()) |
And searching on the mannequin abstract,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
_________________________________________________________________ Layer (sort) Output Form Param # ================================================================= input_2 (InputLayer) [(None, 32, 32, 3)] 0
conv2d_6 (Conv2D) (None, 32, 32, 6) 456
max_pooling2d_2 (MaxPooling (None, 16, 16, 6) 0 2D)
conv2d_7 (Conv2D) (None, 16, 16, 16) 2416
max_pooling2d_3 (MaxPooling (None, 8, 8, 16) 0 2D)
conv2d_8 (Conv2D) (None, 8, 8, 120) 48120
flatten_2 (Flatten) (None, 7680) 0
dense_4 (Dense) (None, 84) 645204
dense_5 (Dense) (None, 10) 850
================================================================= Whole params: 697,046 Trainable params: 697,046 Non–trainable params: 0 _________________________________________________________________ |
As we are able to see, the mannequin structure is similar for each LeNet5 fashions that we have now carried out utilizing the useful interface or the Sequential class.
Now that we’ve seen find out how to use Keras’ useful interface, let’s have a look at a mannequin structure that we are able to implement utilizing the useful interface however not with the Sequential class. For this instance, we’ll have a look at the residual block launched in ResNet. Visually, the residual block seems to be like this:
We will see {that a} mannequin outlined utilizing the Sequential class can be unable to assemble such a block because of the skip connection which prevents this block from being represented as a easy stack of layers. Utilizing the useful interface, that is a method we are able to outline a ResNet block:
def residual_block(x, filters): # retailer the enter tensor to be added later because the identification identification = x # change the strides to do like pooling layer (must see whether or not we join earlier than or after this layer although) x = Conv2D(filters = filters, kernel_size=(3, 3), strides = (1, 1), padding=“identical”)(x) x = BatchNormalization()(x) x = relu(x) x = Conv2D(filters = filters, kernel_size=(3, 3), padding=“identical”)(x) x = BatchNormalization()(x) x = Add()([identity, x]) x = relu(x)
return x |
Then, we are able to construct a easy community utilizing these residual blocks utilizing the useful interface as nicely.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
input_layer = Enter(form=(32,32,3,)) x = Conv2D(filters=32, kernel_size=(3, 3), padding=“identical”, activation=“relu”)(input_layer) x = residual_block(x, 32) x = Conv2D(filters=64, kernel_size=(3, 3), strides=(2, 2), padding=“identical”, activation=“relu”)(x) x = residual_block(x, 64) x = Conv2D(filters=128, kernel_size=(3, 3), strides=(2, 2), padding=“identical”, activation=“relu”)(x) x = residual_block(x, 128) x = Flatten()(x) x = Dense(models=84, activation=“relu”)(x) x = Dense(models=10, activation=“softmax”)(x)
mannequin = Mannequin(inputs=input_layer, outputs = x) print(mannequin.abstract())
mannequin.compile(optimizer=“adam”, loss=tf.keras.losses.SparseCategoricalCrossentropy(), metrics=“acc”)
historical past = mannequin.match(x=trainX, y=trainY, batch_size=256, epochs=10, validation_data=(testX, testY)) |
Operating this code and looking out on the mannequin abstract and coaching outcomes,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
__________________________________________________________________________________________________ Layer (sort) Output Form Param # Linked to ================================================================================================== input_1 (InputLayer) [(None, 32, 32, 3)] 0 []
conv2d (Conv2D) (None, 32, 32, 32) 896 [‘input_1[0][0]’]
conv2d_1 (Conv2D) (None, 32, 32, 32) 9248 [‘conv2d[0][0]’]
batch_normalization (BatchNorm (None, 32, 32, 32) 128 [‘conv2d_1[0][0]’] alization)
tf.nn.relu (TFOpLambda) (None, 32, 32, 32) 0 [‘batch_normalization[0][0]’]
conv2d_2 (Conv2D) (None, 32, 32, 32) 9248 [‘tf.nn.relu[0][0]’]
batch_normalization_1 (BatchNo (None, 32, 32, 32) 128 [‘conv2d_2[0][0]’] rmalization)
add (Add) (None, 32, 32, 32) 0 [‘conv2d[0][0]’, ‘batch_normalization_1[0][0]’]
tf.nn.relu_1 (TFOpLambda) (None, 32, 32, 32) 0 [‘add[0][0]’]
conv2d_3 (Conv2D) (None, 16, 16, 64) 18496 [‘tf.nn.relu_1[0][0]’]
conv2d_4 (Conv2D) (None, 16, 16, 64) 36928 [‘conv2d_3[0][0]’]
batch_normalization_2 (BatchNo (None, 16, 16, 64) 256 [‘conv2d_4[0][0]’] rmalization)
tf.nn.relu_2 (TFOpLambda) (None, 16, 16, 64) 0 [‘batch_normalization_2[0][0]’]
conv2d_5 (Conv2D) (None, 16, 16, 64) 36928 [‘tf.nn.relu_2[0][0]’]
batch_normalization_3 (BatchNo (None, 16, 16, 64) 256 [‘conv2d_5[0][0]’] rmalization)
add_1 (Add) (None, 16, 16, 64) 0 [‘conv2d_3[0][0]’, ‘batch_normalization_3[0][0]’]
tf.nn.relu_3 (TFOpLambda) (None, 16, 16, 64) 0 [‘add_1[0][0]’]
conv2d_6 (Conv2D) (None, 8, 8, 128) 73856 [‘tf.nn.relu_3[0][0]’]
conv2d_7 (Conv2D) (None, 8, 8, 128) 147584 [‘conv2d_6[0][0]’]
batch_normalization_4 (BatchNo (None, 8, 8, 128) 512 [‘conv2d_7[0][0]’] rmalization)
tf.nn.relu_4 (TFOpLambda) (None, 8, 8, 128) 0 [‘batch_normalization_4[0][0]’]
conv2d_8 (Conv2D) (None, 8, 8, 128) 147584 [‘tf.nn.relu_4[0][0]’]
batch_normalization_5 (BatchNo (None, 8, 8, 128) 512 [‘conv2d_8[0][0]’] rmalization)
add_2 (Add) (None, 8, 8, 128) 0 [‘conv2d_6[0][0]’, ‘batch_normalization_5[0][0]’]
tf.nn.relu_5 (TFOpLambda) (None, 8, 8, 128) 0 [‘add_2[0][0]’]
flatten (Flatten) (None, 8192) 0 [‘tf.nn.relu_5[0][0]’]
dense (Dense) (None, 84) 688212 [‘flatten[0][0]’]
dense_1 (Dense) (None, 10) 850 [‘dense[0][0]’]
================================================================================================== Whole params: 1,171,622 Trainable params: 1,170,726 Non–trainable params: 896 __________________________________________________________________________________________________ None Epoch 1/10 196/196 [==============================] – 21s 46ms/step – loss: 3.4463 acc: 0.3635 – val_loss: 1.8015 – val_acc: 0.3459 Epoch 2/10 196/196 [==============================] – 8s 43ms/step – loss: 1.3267 – acc: 0.5200 – val_loss: 1.3895 – val_acc: 0.5069 Epoch 3/10 196/196 [==============================] – 8s 43ms/step – loss: 1.1095 – acc: 0.6062 – val_loss: 1.2008 – val_acc: 0.5651 Epoch 4/10 196/196 [==============================] – 9s 44ms/step – loss: 0.9618 – acc: 0.6585 – val_loss: 1.5411 – val_acc: 0.5226 Epoch 5/10 196/196 [==============================] – 9s 44ms/step – loss: 0.8656 – acc: 0.6968 – val_loss: 1.1012 – val_acc: 0.6234 Epoch 6/10 196/196 [==============================] – 8s 43ms/step – loss: 0.7622 – acc: 0.7361 – val_loss: 1.1355 – val_acc: 0.6168 Epoch 7/10 196/196 [==============================] – 9s 44ms/step – loss: 0.6801 – acc: 0.7602 – val_loss: 1.1561 – val_acc: 0.6187 Epoch 8/10 196/196 [==============================] – 8s 43ms/step – loss: 0.6106 – acc: 0.7905 – val_loss: 1.1100 – val_acc: 0.6401 Epoch 9/10 196/196 [==============================] – 9s 43ms/step – loss: 0.5367 – acc: 0.8146 – val_loss: 1.2989 – val_acc: 0.6058 Epoch 10/10 196/196 [==============================] – 9s 47ms/step – loss: 0.4776 – acc: 0.8348 – val_loss: 1.0098 – val_acc: 0.6757 |
And mixing the code for our easy community utilizing residual blocks,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
import tensorflow as tf from tensorflow import keras from keras.layers import Enter, Conv2D, BatchNormalization, Add, MaxPool2D, Flatten, Dense from keras.activations import relu from tensorflow.keras.fashions import Mannequin
def residual_block(x, filters): # retailer the enter tensor to be added later because the identification identification = x # change the strides to do like pooling layer (must see whether or not we join earlier than or after this layer although) x = Conv2D(filters = filters, kernel_size=(3, 3), strides = (1, 1), padding=“identical”)(x) x = BatchNormalization()(x) x = relu(x) x = Conv2D(filters = filters, kernel_size=(3, 3), padding=“identical”)(x) x = BatchNormalization()(x) x = Add()([identity, x]) x = relu(x)
return x
(trainX, trainY), (testX, testY) = keras.datasets.cifar10.load_data()
input_layer = Enter(form=(32,32,3,)) x = Conv2D(filters=32, kernel_size=(3, 3), padding=“identical”, activation=“relu”)(input_layer) x = residual_block(x, 32) x = Conv2D(filters=64, kernel_size=(3, 3), strides=(2, 2), padding=“identical”, activation=“relu”)(x) x = residual_block(x, 64) x = Conv2D(filters=128, kernel_size=(3, 3), strides=(2, 2), padding=“identical”, activation=“relu”)(x) x = residual_block(x, 128) x = Flatten()(x) x = Dense(models=84, activation=“relu”)(x) x = Dense(models=10, activation=“softmax”)(x)
mannequin = Mannequin(inputs=input_layer, outputs = x) print(mannequin.abstract())
mannequin.compile(optimizer=“adam”, loss=tf.keras.losses.SparseCategoricalCrossentropy(), metrics=“acc”)
historical past = mannequin.match(x=trainX, y=trainY, batch_size=256, epochs=10, validation_data=(testX, testY)) |
Subclassing keras.Mannequin
Keras additionally gives an object-oriented strategy to creating fashions, which might assist with reusability and permits us to symbolize the fashions that we wish to create as courses. This illustration is perhaps extra intuitive, since we are able to take into consideration fashions as a set of layers strung collectively to type our community.
To start subclassing keras.Mannequin, we first must import it.
from tensorflow.keras.fashions import Mannequin |
Then, we are able to begin subclassing Mannequin. First, we have to construct the layers that we wish to use in our methodology calls since we solely wish to instantiate these layers as soon as as a substitute of every time we name our mannequin. To maintain in keeping with earlier examples, let’s construct a LeNet5 mannequin right here as nicely.
class LeNet5(tf.keras.Mannequin): def __init__(self): tremendous(LeNet5, self).__init__() #creating layers in initializer self.conv1 = Conv2D(filters=6, kernel_size=(5,5), padding=“identical”, activation=“relu”) self.max_pool2x2 = MaxPool2D(pool_size=(2,2)) self.conv2 = Conv2D(filters=16, kernel_size=(5,5), padding=“identical”, activation=“relu”) self.conv3 = Conv2D(filters=120, kernel_size=(5,5), padding=“identical”, activation=“relu”) self.flatten = Flatten() self.fc2 = Dense(models=84, activation=“relu”) self.fc3 = Dense(models=10, activation=“softmax”) |
Then, we override the decision methodology to outline what occurs when the mannequin known as. We override it with our mannequin which makes use of the layers that we have now constructed within the initializer.
def name(self, input_tensor): # do not create layers right here, must create the layers in initializer, # in any other case you’re going to get the tf.Variable can solely be created as soon as error conv1 = self.conv1(input_tensor) maxpool1 = self.max_pool2x2(conv1) conv2 = self.conv2(maxpool1) maxpool2 = self.max_pool2x2(conv2) conv3 = self.conv3(maxpool2) flatten = self.flatten(conv3) fc2 = self.fc2(flatten) fc3 = self.fc3(fc2)
return fc3 |
It is very important have all of the layers created on the class constructor, not contained in the name()
methodology. It’s as a result of the name()
methodology might be invoked a number of occasions with totally different enter tensor. However we wish to use the identical layer objects in every name so we are able to optimize their weight. We will then instantiate our new LeNet5 class and use it as a part of a mannequin:
input_layer = Enter(form=(32,32,3,)) x = LeNet5()(input_layer)
mannequin = Mannequin(inputs=input_layer, outputs=x)
print(mannequin.abstract(expand_nested=True)) |
And we are able to see that the mannequin has the identical variety of parameters because the earlier two variations of LeNet5 that we constructed beforehand and has the identical construction inside it as nicely.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
_________________________________________________________________ Layer (sort) Output Form Param # ================================================================= input_1 (InputLayer) [(None, 32, 32, 3)] 0
le_net5 (LeNet5) (None, 10) 697046 |¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯| | conv2d (Conv2D) a number of 456 | | | | max_pooling2d (MaxPooling2D a number of 0 | | ) | | | | conv2d_1 (Conv2D) a number of 2416 | | | | conv2d_2 (Conv2D) a number of 48120 | | | | flatten (Flatten) a number of 0 | | | | dense (Dense) a number of 645204 | | | | dense_1 (Dense) a number of 850 | ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ ================================================================= Whole params: 697,046 Trainable params: 697,046 Non–trainable params: 0 _________________________________________________________________ |
Combining the entire code to create our LeNet5 subclass of keras.Mannequin,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
import tensorflow as tf from tensorflow.keras.layers import Dense, Enter, Flatten, Conv2D, MaxPool2D from tensorflow.keras.fashions import Mannequin
class LeNet5(tf.keras.Mannequin): def __init__(self): tremendous(LeNet5, self).__init__() #creating layers in initializer self.conv1 = Conv2D(filters=6, kernel_size=(5,5), padding=“identical”, activation=“relu”) self.max_pool2x2 = MaxPool2D(pool_size=(2,2)) self.conv2 = Conv2D(filters=16, kernel_size=(5,5), padding=“identical”, activation=“relu”) self.conv3 = Conv2D(filters=120, kernel_size=(5,5), padding=“identical”, activation=“relu”) self.flatten = Flatten() self.fc2 = Dense(models=84, activation=“relu”) self.fc3=Dense(models=10, activation=“softmax”)
def name(self, input_tensor): #do not add layers right here, must create the layers in initializer, in any other case you’re going to get the tf.Variable can solely be created as soon as error x = self.conv1(input_tensor) x = self.max_pool2x2(x) x = self.conv2(x) x = self.max_pool2x2(x) x = self.conv3(x) x = self.flatten(x) x = self.fc2(x) x = self.fc3(x) return x input_layer = Enter(form=(32,32,3,)) x = LeNet5()(input_layer) mannequin = Mannequin(inputs=input_layer, outputs=x) print(mannequin.abstract(expand_nested=True)) |
Additional Studying
This part gives extra sources on the subject if you’re trying to go deeper.
Papers:
APIs:
Abstract
On this publish, you could have seen three alternative ways to create fashions in Keras, specifically, utilizing the Sequential class, useful interface and subclassing keras.Mannequin. You may have additionally seen examples of the identical LeNet5 mannequin being constructed utilizing the totally different strategies and seen a use case which might be executed utilizing the useful interface however not with the Sequential class.
Particularly, you discovered:
- Completely different ways in which Keras gives to construct fashions
- Tips on how to use the Sequential class, useful interface, and subclassing keras.Mannequin to construct Keras fashions
- When to make use of the totally different strategies to create Keras fashions