美文网首页
10、模型概览与一个实例

10、模型概览与一个实例

作者: 是黄小胖呀 | 来源:发表于2020-12-15 20:24 被阅读0次

    一、模型概览

    #基本概念

    #0Keras 有两个重要的概念: 模型(Model) 和 层(Layer) 

    #1层将各种计算流程和变量进行了封装(例如基本的全连接层,CNN 的卷积层、池化层等)

    #2模型则将各种层进行组织和连接,并封装成一个整体,描述了如何将输入数据通过各种层以及运算而得到输出。

    #3Keras 在 tf.keras.layers 下内置了深度学习中大量常用的的预定义层,同时也允许我们自定义层。

    #4Keras 模型以类的形式呈现,我们可以通过继承 tf.keras.Model 这个 Python 类来定义自己的模型。

    #5在继承类中,我们需要重写 init() (构造函数,初始化)和 call(input) (模型调用)两个方法,同时也可以根据需要增加自>    定义的方法。

    class MyModel(tf.keras.Model):

        def __init__(self):

            super().__init__()    # Python 2 下使用 super(MyModel, self).__init__()

            # 此处添加初始化代码(包含 call 方法中会用到的层),例如

            # layer1 = tf.keras.layers.BuiltInLayer(...)

            # layer2 = MyCustomLayer(...)

        def call(self, input):

            # 此处添加模型调用的代码(处理输入并返回输出),例如

            # x = layer1(input)

            # output = layer2(x)

            return output

        # 还可以添加自定义的方法

    模型图示

    例子:

    import tensorflow as tf

    X = tf.constant([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])

    y = tf.constant([[10.0], [20.0]])

    class Linear(tf.keras.Model):

        def __init__(self):

            super().__init__()

            self.dense = tf.keras.layers.Dense(

                units=1,

                activation=None,

                kernel_initializer=tf.zeros_initializer(),

                bias_initializer=tf.zeros_initializer()

            )

        def call(self, input):

            output = self.dense(input)

            return output

    # 以下代码结构与前节类似

    model = Linear()

    optimizer = tf.keras.optimizers.SGD(learning_rate=0.01)

    for i in range(100):

        with tf.GradientTape() as tape:

            y_pred = model(X)      # 调用模型 y_pred = model(X) 而不是显式写出 y_pred = a * X + b

            loss = tf.reduce_mean(tf.square(y_pred - y))

        grads = tape.gradient(loss, model.variables)    # 使用 model.variables 这一属性直接获得模型中的所有变量

        optimizer.apply_gradients(grads_and_vars=zip(grads, model.variables))

    print(model.variables)

    1、我们没有显式地声明 a 和 b 两个变量并写出 y_pred = a X + b 这一线性变换,而是建立了一个继承了 tf.keras.Model 的模型类 Linear 。这个类在初始化部分实例化了一个 *全连接层 ( tf.keras.layers.Dense ),并在 call 方法中对这个层进行调用,实现了线性变换的计算。

    2、Keras 的全连接层:线性变换 + 激活函数

    全连接层 主要参数

    3、为什么模型类是重载 call() 方法而不是 call() 方法?

    在 Python 中,对类的实例 myClass 进行形如 myClass() 的调用等价于 myClass.call() (具体请见本章初 “前置知识” 的 call() 部分)。那么看起来,为了使用 ypred = model(X) 的形式调用模型类,应该重写 call() 方法才对呀?原因是 Keras 在模型调用的前后还需要有一些自己的内部操作,所以暴露出一个专门用于重载的 call() 方法。 tf.keras.Model 这一父类已经包含 call() 的定义。 _call() 中主要调用了 call() 方法,同时还需要在进行一些 keras 的内部操作。这里,我们通过继承 tf.keras.Model 并重载 call() 方法,即可在保持 keras 结构的同时加入模型调用的代码。

    二、一个实例:使用多层感知机完成 MNIST 手写体数字图片数据集 [LeCun1998] 的分类任务。

    模型的构建: tf.keras.Model 和 tf.keras.layers

    多层感知机的模型类实现与上面的线性模型类似,使用 tf.keras.Model 和 tf.keras.layers 构建,所不同的地方在于层数增加了(顾名思义,“多层” 感知机),以及引入了非线性激活函数(这里使用了 ReLU 函数 , 即下方的 activation=tf.nn.relu )。该模型输入一个向量(比如这里是拉直的 1×784 手写体数字图片),输出 10 维的向量,分别代表这张图片属于 0 到 9 的概率。

    代码主要分为几个部分:

    1、引入/导入包

    2、定义训练数据处理

    3、定义模型

    4、进行训练

    5、评估结果

    代码如下:它跑成功了呀~~~

    10 import tensorflow as tf

     11import numpy as np

     12 

     13 class MNISTLoader():

     14    def __init__(self):

     15        mnist = tf.keras.datasets.mnist

     16        (self.train_data, self.train_label), (self.test_data, self.test_label) = mnist.load_data()

     17        # MNIST中的图像默认为uint8(0-255的数字)。以下代码将其归一化到0-1之间的浮点数,并在最后增加一维作为颜色通道

     18        self.train_data = np.expand_dims(self.train_data.astype(np.float32) /255.0, axis=-1)      # [60000, 28, 28, 1]

     19        self.test_data = np.expand_dims(self.test_data.astype(np.float32) /255.0, axis=-1)        # [10000, 28, 28, 1]

     20        self.train_label = self.train_label.astype(np.int32)    # [60000]

     21        self.test_label = self.test_label.astype(np.int32)      # [10000]

     22        self.num_train_data, self.num_test_data = self.train_data.shape[0], self.test_data.shape[0]

     23 

     24    def get_batch(self, batch_size):

     25        # 从数据集中随机取出batch_size个元素并返回

     26        index = np.random.randint(0, np.shape(self.train_data)[0], batch_size)

     27        return self.train_data[index, :], self.train_label[index]

     28 

     29 class MLP(tf.keras.Model):

     30    def __init__(self):

     31        super().__init__()

     32        self.flatten = tf.keras.layers.Flatten()    # Flatten层将除第一维(batch_size)以外的维度展平

     33        self.dense1 = tf.keras.layers.Dense(units=100, activation=tf.nn.relu)

     34        self.dense2 = tf.keras.layers.Dense(units=10)

     35 

     36    def call(self, inputs):        # [batch_size, 28, 28, 1]

     37        x = self.flatten(inputs)    # [batch_size, 784]

     38        x = self.dense1(x)          # [batch_size, 100]

     39        x = self.dense2(x)          # [batch_size, 10]

     40        output = tf.nn.softmax(x)

     41        return output

     42 

     43num_epochs = 5

     44batch_size = 50

     45learning_rate = 0.001

     46 

     47model = MLP()

     48data_loader = MNISTLoader()

     49optimizer = tf.keras.optimizers.Adam(learning_rate=learning_rate)

     50 

     51num_batches = int(data_loader.num_train_data // batch_size * num_epochs)

     52 for batch_index in range(num_batches):

     53        X, y = data_loader.get_batch(batch_size)

     54        with tf.GradientTape() as tape:

     55            y_pred = model(X)

     56            loss = tf.keras.losses.sparse_categorical_crossentropy(y_true=y, y_pred=y_pred)

     57            loss = tf.reduce_mean(loss)

     58            print("batch %d: loss %f" % (batch_index, loss.numpy()))

     59        grads = tape.gradient(loss, model.variables)

     60        optimizer.apply_gradients(grads_and_vars=zip(grads, model.variables))

     61 

     62sparse_categorical_accuracy = tf.keras.metrics.SparseCategoricalAccuracy()

     63num_batches = int(data_loader.num_test_data // batch_size)

     64 for batch_index in range(num_batches):

     65        start_index, end_index = batch_index * batch_size, (batch_index +1) * batch_size

     66        y_pred = model.predict(data_loader.test_data[start_index: end_index])

     67        sparse_categorical_accuracy.update_state(y_true=data_loader.test_label[start_index: end_index], y_pred=y_pred)

     68print("test accuracy: %f" % sparse_categorical_accuracy.result())

    参考资料

    1、简单粗暴 TensorFlow 2.0 模型(Model)与层(Layer)

    https://www.bookstack.cn/read/TensorFlow2.0/spilt.1.c868281a01ad8ec0.md

    2、简单粗暴 TensorFlow 2.0 基础示例:多层感知机(MLP) 

    https://www.bookstack.cn/read/TensorFlow2.0/spilt.2.c868281a01ad8ec0.md

    相关文章

      网友评论

          本文标题:10、模型概览与一个实例

          本文链接:https://www.haomeiwen.com/subject/anxggktx.html