TF2.0 自定義層、自定義模塊、自定義模型構建

目錄

頭文件

1、加載數據集

2、自定義層(Dense層)

3、自定義模塊(設定兩個Dense爲一個模塊)

4、自定深度神經網絡模型

5、訓練深度神經網絡模型


 

頭文件

import numpy as np
import tensorflow as tf
import datetime
import os

from tensorflow.keras.layers import Dense, Flatten, Conv2D, MaxPool2D

1、加載數據集

def load_dataset():
    mnist = np.load("mnist.npz")
    return mnist['x_train']/255.0, mnist['y_train'], mnist['x_test']/255.0, mnist['y_test']

x_train, y_train, x_test, y_test = load_dataset()

print (np.shape(x_train))

x_train = x_train[..., tf.newaxis]
x_test = x_test[..., tf.newaxis]

train_ds = tf.data.Dataset.from_tensor_slices((x_train, y_train)).shuffle(10000).batch(32)
test_ds = tf.data.Dataset.from_tensor_slices((x_test, y_test)).batch(32)

2、自定義層(Dense層)

class MyDense(tf.keras.layers.Layer):
    def __init__(self, units=32, **kwargs):
        super(MyDense, self).__init__(**kwargs)
        self.units = units

    def build(self, input_shape):
        super(MyDense, self).build(input_shape) # 相當於設置self.build = True
        self.w = self.add_weight(shape=(input_shape[-1], self.units),
                                 initializer='random_normal',
                                 trainable=True,
                                 name='w')
        self.b = self.add_weight(shape=(self.units, ),
                                 initializer='random_normal',
                                 trainable=True,
                                 name='b')

    def call(self, inputs):
        return tf.matmul(inputs, self.w) + self.b

    def get_config(self):
        config = super(MyDense, self).get_config()
        config.update({'units': self.units})
        return config

3、自定義模塊(設定兩個Dense爲一個模塊)

class MyBlock(tf.keras.Model):
    def __init__(self, units=[32, 32]):
        super(MyBlock, self).__init__(name='')

        self.dense1 = MyDense(units[0])
        self.dense2 = MyDense(units[1])

    def call(self, input_tensor):
        x = self.dense1(input_tensor)
        return self.dense2(x)

4、自定深度神經網絡模型

包括卷積層,最大池化層,MyBlock,以及輸出層

class MyModel(tf.keras.Model):
    def __init__(self, num_classes=10):
        super(MyModel, self).__init__()

        self.conv1 = Conv2D(4, 3, activation='relu')
        self.pool1 = MaxPool2D(pool_size=(2, 2))
        self.conv2 = Conv2D(6, 3, activation='relu')
        self.pool2 = MaxPool2D(pool_size=(2, 2))
        self.flatten = Flatten()
        self.block = MyBlock(units=[60, 40])
        self.d = Dense(10)

    @tf.function(input_signature=[tf.TensorSpec([None, 28, 28, 1], tf.float32, name='inputs')])
    def call(self, input_tensor):
        x = self.conv1(input_tensor)
        x = self.pool1(x)
        x = self.conv2(x)
        x = self.pool2(x)
        x = self.flatten(x)
        x = self.block(x)
        return self.d(x)

5、訓練深度神經網絡模型

def training_model():
    Epochs = 10
    model = MyModel()
    loss_obj = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
    optimizer = tf.keras.optimizers.Adam(0.001)

    train_loss = tf.keras.metrics.Mean(name='train_loss')
    test_loss = tf.keras.metrics.Mean(name='test_loss')
    test_acc = tf.keras.metrics.SparseCategoricalAccuracy(name='test_acc')

    def train_step(images, labels):
        with tf.GradientTape() as tape:
            logits = model(images)
            loss = loss_obj(labels, logits)

        grads = tape.gradient(loss, model.trainable_variables)
        optimizer.apply_gradients(zip(grads, model.trainable_variables))

        train_loss(loss)

    def test_step(images, labels):
        logits = model(images)
        loss = loss_obj(labels, logits)

        test_loss(loss)
        test_acc(labels, logits)

    for epoch in range(Epochs):
        train_loss.reset_states()
        test_loss.reset_states()
        test_acc.reset_states()

        for images, labels in train_ds:
            train_step(images, labels)

        for images, labels in test_ds:
            test_step(images, labels)


        tmp = 'Epoch {}, train_loss: {}, test_loss: {}, test_acc: {}'
        print (tmp.format(epoch+1, train_loss.result(), test_loss.result(), test_acc.result()))


training_model()

實驗結果

Epoch 1, train_loss: 0.28127846121788025, test_loss: 0.11484793573617935, test_acc: 0.963699996471405
Epoch 2, train_loss: 0.11530549079179764, test_loss: 0.08538637310266495, test_acc: 0.974399983882904
Epoch 3, train_loss: 0.09448453783988953, test_loss: 0.08153647184371948, test_acc: 0.9735000133514404
Epoch 4, train_loss: 0.08528731763362885, test_loss: 0.0694243535399437, test_acc: 0.9779000282287598
Epoch 5, train_loss: 0.07687702775001526, test_loss: 0.06510015577077866, test_acc: 0.9782000184059143
Epoch 6, train_loss: 0.07208435237407684, test_loss: 0.07370095700025558, test_acc: 0.9765999913215637
Epoch 7, train_loss: 0.06807399541139603, test_loss: 0.060320284217596054, test_acc: 0.98089998960495
Epoch 8, train_loss: 0.06528966128826141, test_loss: 0.06324119865894318, test_acc: 0.9799000024795532
Epoch 9, train_loss: 0.061740703880786896, test_loss: 0.06062839925289154, test_acc: 0.9799000024795532
Epoch 10, train_loss: 0.06004393473267555, test_loss: 0.05968930572271347, test_acc: 0.9799000024795532

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章