Keras three mainstream model construction methods: sequence model, function model, and subclass model development practice, taking real smoke recognition scene data as an example

Keras and PyTorch are two commonly used deep learning frameworks, both of which provide high-level APIs for building and training neural networks.

Keras:

Keras is a high-level neural network API that can run on multiple low-level deep learning frameworks, such as TensorFlow and CNTK. The following are the features and benefits of Keras:

advantage:

  • Easy to use: Keras has a concise API design, easy to get started and use, suitable for rapid prototyping and experimentation.
  • Flexibility: Keras provides a high-level API and a modular architecture that can flexibly build various types of neural network models.
  • Reusability: Keras models can be easily saved and loaded, and models can be easily shared, deployed and migrated.
  • Community support: Keras has a large community support and an active developer community, providing a large number of documents, tutorials and sample code.

shortcoming:

  • Functional limitations: Compared to underlying frameworks such as TensorFlow and PyTorch, Keras may have limitations in some advanced functions and customization.
  • Scalability: While Keras provides an easy-to-use API, it may be limited on complex models that require a lot of customization and scalability.
  • Flexibility: Keras is mainly designed for simple processes. When complex non-standard tasks need to be processed, Keras is less flexible.

Applicable scene:

  • Beginners: For newcomers, Keras is an ideal choice because of its simplicity and ease of use, with extensive documentation and examples to help get started quickly.
  • Rapid prototyping: Keras can quickly build and iterate models, suitable for rapid prototyping and rapid experimental verification.
  • General computer vision and natural language processing tasks: Keras provides a large number of pre-trained models and tools for computer vision and natural language processing, which are suitable for the development and application of general tasks.

PyTorch:

PyTorch is a dynamic graph deep learning framework that emphasizes ease of use and low-latency debugging. The following are the features and benefits of PyTorch:

advantage:

  • Dynamic graphs: PyTorch uses dynamic graphs to make model building and debugging more flexible and intuitive, allowing models to be viewed and debugged in real time.
  • Free control: Compared with the static graph framework, PyTorch can more freely control the complex logic of the model and explore new network architectures.
  • Algorithm development: PyTorch provides a rich mathematical operation library and automatic derivation function, which is suitable for algorithm research and customized model development.
  • Community support: PyTorch has an active community and a large number of open source projects, providing a wealth of resources and support.

shortcoming:

  • Deployment complexity: Compared with high-level API frameworks such as Keras, PyTorch requires developers to deal more with model deployment and production environments.
  • Static optimization: Compared with static graph frameworks, such as TensorFlow, PyTorch cannot perform static graph optimization, and may be slightly inferior in performance.
  • Barriers to entry: Compared to Keras, PyTorch can have some steep learning curves for beginners.

Applicable scene:

  • Research and custom models: PyTorch is suitable for research and experimentation, as well as custom model development that requires flexibility and a high degree of freedom.
  • Advanced computer vision and natural language processing tasks: PyTorch has extensive applications in the fields of computer vision and natural language processing, and is rich in various pre-trained models and resources.

In the previous two articles, the overall system summary recorded the three mainstream methods of developing and building models in the two mainstream frameworks Keras and PyTroch, and corresponding basic example implementations were given. If you are interested, you can read it by yourself. :

“Summary records three mainstream ways of Keras development and construction of neural network models: sequence model, function model, subclass model”

“Summary and record the three mainstream ways of building neural network models in PyTorch: nn.Sequential builds the model in layer order, inherits the nn.Module base class to build a custom model, inherits the nn.Module base class to build the model and assists in using the model container to encapsulate it”

The main purpose of this article is to develop and practice these three different types of model building methods based on real business data scenarios, and conduct comparative analysis of the results.

First, let’s take a look at the data set:

As for the model structure here, you can build your own design. It doesn’t matter how many layers you have. I mainly refer to the network structure of VGG to build the network model. First, let’s look at the sequence model construction implementation:

def initModel(h=100, w=100, way=3):
    """
    column model
    """
    input_shape = (h, w, way)
    model = Sequential()
    model.add(
        Conv2D(
            64,
            (3, 3),
            strides=(1, 1),
            input_shape = input_shape,
            padding="same",
            activation="relu",
            kernel_initializer="uniform",
        )
    )
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(
        Conv2D(
            128,
            (3, 2),
            strides=(1, 1),
            padding="same",
            activation="relu",
            kernel_initializer="uniform",
        )
    )
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(
        Conv2D(
            256,
            (3, 3),
            strides=(1, 1),
            padding="same",
            activation="relu",
            kernel_initializer="uniform",
        )
    )
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(
        Conv2D(
            512,
            (3, 3),
            strides=(1, 1),
            padding="same",
            activation="relu",
            kernel_initializer="uniform",
        )
    )
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(
        Conv2D(
            512,
            (3, 3),
            strides=(1, 1),
            padding="same",
            activation="relu",
            kernel_initializer="uniform",
        )
    )
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model. add(Flatten())
    model.add(Dense(820, activation="relu"))
    model. add(Dropout(0.1))
    model.add(Dense(820, activation="relu"))
    model. add(Dropout(0.1))
    model.add(Dense(numbers, activation="softmax"))
    return model

The network structure output is as follows:

__________________________________________________________________
Layer (type) Output Shape Param #
==================================================== ================
conv2d_1 (Conv2D) (None, 100, 100, 64) 1792
____________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 50, 50, 64) 0
____________________________________________________________________
conv2d_2 (Conv2D) (None, 50, 50, 128) 49280
____________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 25, 25, 128) 0
____________________________________________________________________
conv2d_3 (Conv2D) (None, 25, 25, 256) 295168
____________________________________________________________________
max_pooling2d_3 (MaxPooling2 (None, 12, 12, 256) 0
____________________________________________________________________
conv2d_4 (Conv2D) (None, 12, 12, 512) 1180160
____________________________________________________________________
max_pooling2d_4 (MaxPooling2 (None, 6, 6, 512) 0
____________________________________________________________________
conv2d_5 (Conv2D) (None, 6, 6, 512) 2359808
____________________________________________________________________
max_pooling2d_5 (MaxPooling2 (None, 3, 3, 512) 0
____________________________________________________________________
flatten_1 (Flatten) (None, 4608) 0
____________________________________________________________________
dense_1 (Dense) (None, 820) 3779380
____________________________________________________________________
dropout_1 (Dropout) (None, 820) 0
____________________________________________________________________
dense_2 (Dense) (None, 820) 673220
____________________________________________________________________
dropout_2 (Dropout) (None, 820) 0
____________________________________________________________________
dense_3 (Dense) (None, 2) 1642
================================================== ================
Total params: 8,340,450
Trainable params: 8,340,450
Non-trainable params: 0
_______________________________________________________________

Next is the function model code implementation, as shown below:

def initModel(h=100, w=100, way=3):
    """
    function model
    """
    input_shape = (h, w, way)
    inputs = Input(shape=input_shape)
    X = Conv2D(
        64,
        (3, 3),
        strides=(1, 1),
        padding="same",
        activation="relu",
        kernel_initializer="uniform",
    )(inputs)
    X = Conv2D(
        64,
        (3, 3),
        strides=(1, 1),
        padding="same",
        activation="relu",
        kernel_initializer="uniform",
    )(X)
    X = MaxPooling2D(pool_size=(2, 2))(X)
    X = Conv2D(
        128,
        (3, 2),
        strides=(1, 1),
        padding="same",
        activation="relu",
        kernel_initializer="uniform",
    )(X)
    X = MaxPooling2D(pool_size=(2, 2))(X)
    X = Conv2D(
        256,
        (3, 3),
        strides=(1, 1),
        padding="same",
        activation="relu",
        kernel_initializer="uniform",
    )(X)
    X = MaxPooling2D(pool_size=(2, 2))(X)
    X = Conv2D(
        512,
        (3, 3),
        strides=(1, 1),
        padding="same",
        activation="relu",
        kernel_initializer="uniform",
    )(X)
    X = MaxPooling2D(pool_size=(2, 2))(X)
    X = Conv2D(
        512,
        (3, 3),
        strides=(1, 1),
        padding="same",
        activation="relu",
        kernel_initializer="uniform",
    )(X)
    X = MaxPooling2D(pool_size=(2, 2))(X)
    X = Flatten()(X)
    X = Dense(820, activation="relu")(X)
    X = Dropout(0.1)(X)
    X = Dense(820, activation="relu")(X)
    X = Dropout(0.1)(X)
    outputs = Dense(2, activation="sigmoid")(X)
    model = Model(input=inputs, output=outputs)
    return model

The model structure information output is as follows:

_______________________________________________________________
Layer (type) Output Shape Param #
================================================== ===============
input_1 (InputLayer) (None, 100, 100, 3) 0
____________________________________________________________________
conv2d_6 (Conv2D) (None, 100, 100, 64) 1792
____________________________________________________________________
conv2d_7 (Conv2D) (None, 100, 100, 64) 36928
____________________________________________________________________
max_pooling2d_6 (MaxPooling2 (None, 50, 50, 64) 0
____________________________________________________________________
conv2d_8 (Conv2D) (None, 50, 50, 128) 49280
____________________________________________________________________
max_pooling2d_7 (MaxPooling2 (None, 25, 25, 128) 0
____________________________________________________________________
conv2d_9 (Conv2D) (None, 25, 25, 256) 295168
____________________________________________________________________
max_pooling2d_8 (MaxPooling2 (None, 12, 12, 256) 0
____________________________________________________________________
conv2d_10 (Conv2D) (None, 12, 12, 512) 1180160
____________________________________________________________________
max_pooling2d_9 (MaxPooling2 (None, 6, 6, 512) 0
____________________________________________________________________
conv2d_11 (Conv2D) (None, 6, 6, 512) 2359808
____________________________________________________________________
max_pooling2d_10 (MaxPooling (None, 3, 3, 512) 0
____________________________________________________________________
flatten_2 (Flatten) (None, 4608) 0
____________________________________________________________________
dense_4 (Dense) (None, 820) 3779380
____________________________________________________________________
dropout_3 (Dropout) (None, 820) 0
____________________________________________________________________
dense_5 (Dense) (None, 820) 673220
____________________________________________________________________
dropout_4 (Dropout) (None, 820) 0
____________________________________________________________________
dense_6 (Dense) (None, 2) 1642
================================================== ===============
Total params: 8,377,378
Trainable params: 8,377,378
Non-trainable params: 0
_______________________________________________________________

Finally, the subclass model code implementation is as follows:

class initModel(Model):
    """
    subclass model
    """

    def __init__(self):
        super(initModel, self).__init__()
        self.conv2d1 = Conv2D(
            64,
            (3, 3),
            strides=(1, 1),
            padding="same",
            activation="relu",
            kernel_initializer="uniform",
        )
        self.conv2d2 = Conv2D(
            64,
            (3, 3),
            strides=(1, 1),
            padding="same",
            activation="relu",
            kernel_initializer="uniform",
        )
        self.pool1 = MaxPooling2D(pool_size=(2, 2))
        self.conv2d3 = Conv2D(
            128,
            (3, 2),
            strides=(1, 1),
            padding="same",
            activation="relu",
            kernel_initializer="uniform",
        )
        self.pool2 = MaxPooling2D(pool_size=(2, 2))
        self.conv2d4 = Conv2D(
            256,
            (3, 3),
            strides=(1, 1),
            padding="same",
            activation="relu",
            kernel_initializer="uniform",
        )
        self.pool3 = MaxPooling2D(pool_size=(2, 2))
        self.conv2d5 = Conv2D(
            512,
            (3, 3),
            strides=(1, 1),
            padding="same",
            activation="relu",
            kernel_initializer="uniform",
        )
        self.pool4 = MaxPooling2D(pool_size=(2, 2))
        self.conv2d6 = Conv2D(
            512,
            (3, 3),
            strides=(1, 1),
            padding="same",
            activation="relu",
            kernel_initializer="uniform",
        )
        self.pool5 = MaxPooling2D(pool_size=(2, 2))
        self.flatten = Flatten()
        self.dense1 = Dense(820, activation="relu")
        self.dropout1 = Dropout(0.1)
        self.dense2 = Dense(820, activation="relu")
        self.dropout2 = Dropout(0.1)
        self.dense3 = Dense(2, activation="sigmoid")


    def call(self, inputs):
        """
        call back
        """
        x = self.conv2d1(inputs)
        x = self.conv2d2(x)
        x = self.pool1(x)
        x = self.conv2d3(x)
        x = self.pool2(x)
        x = self.conv2d4(x)
        x = self.pool3(x)
        x = self.conv2d5(x)
        x = self.pool4(x)
        x = self.conv2d6(x)
        x = self.pool5(x)
        x = self.flatten(x)
        x = self.dense1(x)
        x = self.dropout1(x)
        x = self.dense2(x)
        x = self.dropout2(x)
        y = self.dense3(x)
        return y

After completing the construction of the model, you can load the corresponding data set to start training the model. The data set loading can be imitated in the form of the mnist data set. I will not go into details here. There are also corresponding implementations in my previous articles, as follows Shown:

# Data loading
X_train, X_test, y_train, y_test = loadData()
X_train = X_train.astype("float32")
X_test = X_test.astype("float32")
# Data normalization
X_train /= 255
X_test /= 255
# Data scramble
np.random.seed(200)
np.random.shuffle(X_train)
np.random.seed(200)
np.random.shuffle(y_train)
np.random.seed(200)
np.random.shuffle(X_test)
np.random.seed(200)
np.random.shuffle(y_test)
# Model
model=initModel()
model.compile(loss="binary_crossentropy", optimizer="sgd", metrics=["accuracy"])

The model evaluation test visualization implementation is as follows:

# Visualization
plt.clf()
plt.plot(history.history["acc"])
plt.plot(history.history["val_acc"])
plt.title("model accuracy")
plt.ylabel("accuracy")
plt.xlabel("epochs")
plt.legend(["train", "test"], loc="upper left")
plt.savefig(saveDir + "train_validation_acc.png")
plt.clf()
plt.plot(history.history["loss"])
plt.plot(history.history["val_loss"])
plt.title("model loss")
plt.ylabel("loss")
plt.xlabel("epochs")
plt.legend(["train", "test"], loc="upper left")
plt.savefig(saveDir + "train_validation_loss.png")
scores = model.evaluate(X_test, y_test, verbose=0)
print("Accuracy: %.2f%%" % (scores[1] * 100))

Let’s take a look at the results:
【Sequence model】

【Function Model】

[Subclass model]

There is a slight difference in the results, which should be related to training.

The visualization results are as follows:

In fact, the three methods are essentially the same. As long as you are familiar with one of them, other construction methods can be transformed based on the current construction method. There is no absolute only choice, only the choice that suits you best.

The knowledge points of the article match the official knowledge archives, and you can further learn relevant knowledge. Python introductory skill treeArtificial IntelligenceDeep Learning 334717 people are learning the system