一小时学会TensorFlow2之自定义层

目录
  • 概述
  • Sequential
  • Model & Layer
  • 案例
    • 数据集介绍
    • 完整代码

概述

通过自定义网络, 我们可以自己创建网络并和现有的网络串联起来, 从而实现各种各样的网络结构.

Sequential

Sequential 是 Keras 的一个网络容器. 可以帮助我们将多层网络封装在一起.

通过 Sequential 我们可以把现有的层已经我们自己的层实现结合, 一次前向传播就可以实现数据从第一层到最后一层的计算.

格式:

tf.keras.Sequential(
    layers=None, name=None
)

例子:

# 5层网络模型
model = tf.keras.Sequential([
    tf.keras.layers.Dense(256, activation=tf.nn.relu),
    tf.keras.layers.Dense(128, activation=tf.nn.relu),
    tf.keras.layers.Dense(64, activation=tf.nn.relu),
    tf.keras.layers.Dense(32, activation=tf.nn.relu),
    tf.keras.layers.Dense(10)
])

Model & Layer

通过 Model 和 Layer 的__init__call()我们可以自定义层和模型.

Model:

class My_Model(tf.keras.Model):  # 继承Model

    def __init__(self):
        """
        初始化
        """

        super(My_Model, self).__init__()
        self.fc1 = My_Dense(784, 256)  # 第一层
        self.fc2 = My_Dense(256, 128)  # 第二层
        self.fc3 = My_Dense(128, 64)  # 第三层
        self.fc4 = My_Dense(64, 32)  # 第四层
        self.fc5 = My_Dense(32, 10)  # 第五层

    def call(self, inputs, training=None):
        """
        在Model被调用的时候执行
        :param inputs: 输入
        :param training: 默认为None
        :return: 返回输出
        """

        x = self.fc1(inputs)
        x = tf.nn.relu(x)
        x = self.fc2(x)
        x = tf.nn.relu(x)
        x = self.fc3(x)
        x = tf.nn.relu(x)
        x = self.fc4(x)
        x = tf.nn.relu(x)
        x = self.fc5(x)

        return x

Layer:

class My_Dense(tf.keras.layers.Layer):  # 继承Layer

    def __init__(self, input_dim, output_dim):
        """
        初始化
        :param input_dim:
        :param output_dim:
        """

        super(My_Dense, self).__init__()

        # 添加变量
        self.kernel = self.add_variable("w", [input_dim, output_dim])  # 权重
        self.bias = self.add_variable("b", [output_dim])  # 偏置

    def call(self, inputs, training=None):
        """
        在Layer被调用的时候执行, 计算结果
        :param inputs: 输入
        :param training: 默认为None
        :return: 返回计算结果
        """

        # y = w * x + b
        out = inputs @ self.kernel + self.bias

        return out

案例

数据集介绍

CIFAR-10 是由 10 类不同的物品组成的 6 万张彩色图片的数据集. 其中 5 万张为训练集, 1 万张为测试集.

完整代码

import tensorflow as tf

def pre_process(x, y):

    # 转换x
    x = 2 * tf.cast(x, dtype=tf.float32) / 255 - 1  # 转换为-1~1的形式
    x = tf.reshape(x, [-1, 32 * 32 * 3])  # 把x铺平

    # 转换y
    y = tf.convert_to_tensor(y)  # 转换为0~1的形式
    y = tf.one_hot(y, depth=10)  # 转成one_hot编码

    # 返回x, y
    return x, y

def get_data():
    """
    获取数据
    :return:
    """

    # 获取数据
    (X_train, y_train), (X_test, y_test) = tf.keras.datasets.cifar10.load_data()

    # 调试输出维度
    print(X_train.shape)  # (50000, 32, 32, 3)
    print(y_train.shape)  # (50000, 1)

    # squeeze
    y_train = tf.squeeze(y_train)  # (50000, 1) => (50000,)
    y_test = tf.squeeze(y_test)  # (10000, 1) => (10000,)

    # 分割训练集
    train_db = tf.data.Dataset.from_tensor_slices((X_train, y_train)).shuffle(10000, seed=0)
    train_db = train_db.batch(batch_size).map(pre_process).repeat(iteration_num)  # 迭代20次

    # 分割测试集
    test_db = tf.data.Dataset.from_tensor_slices((X_test, y_test)).shuffle(10000, seed=0)
    test_db = test_db.batch(batch_size).map(pre_process)

    return train_db, test_db

class My_Dense(tf.keras.layers.Layer):  # 继承Layer

    def __init__(self, input_dim, output_dim):
        """
        初始化
        :param input_dim:
        :param output_dim:
        """

        super(My_Dense, self).__init__()

        # 添加变量
        self.kernel = self.add_weight("w", [input_dim, output_dim])  # 权重
        self.bias = self.add_weight("b", [output_dim])  # 偏置

    def call(self, inputs, training=None):
        """
        在Layer被调用的时候执行, 计算结果
        :param inputs: 输入
        :param training: 默认为None
        :return: 返回计算结果
        """

        # y = w * x + b
        out = inputs @ self.kernel + self.bias

        return out

class My_Model(tf.keras.Model):  # 继承Model

    def __init__(self):
        """
        初始化
        """

        super(My_Model, self).__init__()
        self.fc1 = My_Dense(32 * 32 * 3, 256)  # 第一层
        self.fc2 = My_Dense(256, 128)  # 第二层
        self.fc3 = My_Dense(128, 64)  # 第三层
        self.fc4 = My_Dense(64, 32)  # 第四层
        self.fc5 = My_Dense(32, 10)  # 第五层

    def call(self, inputs, training=None):
        """
        在Model被调用的时候执行
        :param inputs: 输入
        :param training: 默认为None
        :return: 返回输出
        """

        x = self.fc1(inputs)
        x = tf.nn.relu(x)
        x = self.fc2(x)
        x = tf.nn.relu(x)
        x = self.fc3(x)
        x = tf.nn.relu(x)
        x = self.fc4(x)
        x = tf.nn.relu(x)
        x = self.fc5(x)

        return x

# 定义超参数
batch_size = 256  # 一次训练的样本数目
learning_rate = 0.001  # 学习率
iteration_num = 20  # 迭代次数
optimizer = tf.keras.optimizers.Adam(learning_rate=learning_rate)  # 优化器
loss = tf.losses.CategoricalCrossentropy(from_logits=True)  # 损失
network = My_Model()  # 实例化网络

# 调试输出summary
network.build(input_shape=[None, 32 * 32 * 3])
print(network.summary())

# 组合
network.compile(optimizer=optimizer,
                loss=loss,
                metrics=["accuracy"])

if __name__ == "__main__":
    # 获取分割的数据集
    train_db, test_db = get_data()

    # 拟合
    network.fit(train_db, epochs=5, validation_data=test_db, validation_freq=1)

输出结果:

Model: "my__model"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
my__dense (My_Dense) multiple 786688
_________________________________________________________________
my__dense_1 (My_Dense) multiple 32896
_________________________________________________________________
my__dense_2 (My_Dense) multiple 8256
_________________________________________________________________
my__dense_3 (My_Dense) multiple 2080
_________________________________________________________________
my__dense_4 (My_Dense) multiple 330
=================================================================
Total params: 830,250
Trainable params: 830,250
Non-trainable params: 0
_________________________________________________________________
None
(50000, 32, 32, 3)
(50000, 1)
2021-06-15 14:35:26.600766: I tensorflow/compiler/mlir/mlir_graph_optimization_pass.cc:176] None of the MLIR Optimization Passes are enabled (registered 2)
Epoch 1/5
3920/3920 [==============================] - 39s 10ms/step - loss: 0.9676 - accuracy: 0.6595 - val_loss: 1.8961 - val_accuracy: 0.5220
Epoch 2/5
3920/3920 [==============================] - 41s 10ms/step - loss: 0.3338 - accuracy: 0.8831 - val_loss: 3.3207 - val_accuracy: 0.5141
Epoch 3/5
3920/3920 [==============================] - 41s 10ms/step - loss: 0.1713 - accuracy: 0.9410 - val_loss: 4.2247 - val_accuracy: 0.5122
Epoch 4/5
3920/3920 [==============================] - 41s 10ms/step - loss: 0.1237 - accuracy: 0.9581 - val_loss: 4.9458 - val_accuracy: 0.5050
Epoch 5/5
3920/3920 [==============================] - 42s 11ms/step - loss: 0.1003 - accuracy: 0.9666 - val_loss: 5.2425 - val_accuracy: 0.5097

到此这篇关于一小时学会TensorFlow2之自定义层的文章就介绍到这了,更多相关TensorFlow2自定义层内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 解决Pytorch自定义层出现多Variable共享内存错误问题

    错误信息: RuntimeError: in-place operations can be only used on variables that don't share storage with any other variables, but detected that there are 4 objects sharing it 自动求导是很方便, 但是想想, 如果两个Variable共享内存, 再对这个共享的内存的数据进行修改, 就会引起错误! 一般是由于 inplace操作或是ind

  • keras Lambda自定义层实现数据的切片方式,Lambda传参数

    1.代码如下: import numpy as np from keras.models import Sequential from keras.layers import Dense, Activation,Reshape from keras.layers import merge from keras.utils.visualize_util import plot from keras.layers import Input, Lambda from keras.models impo

  • 使用Keras加载含有自定义层或函数的模型操作

    当我们导入的模型含有自定义层或者自定义函数时,需要使用custom_objects来指定目标层或目标函数. 例如: 我的一个模型含有自定义层"SincConv1D",需要使用下面的代码导入: from keras.models import load_model model = load_model('model.h5', custom_objects={'SincConv1D': SincConv1D}) 如果不加custom_objects指定目标层Layer,则会出现以下报错:

  • 解决Keras 自定义层时遇到版本的问题

    在2.2.0版本前, from keras import backend as K from keras.engine.topology import Layer class MyLayer(Layer): def __init__(self, output_dim, **kwargs): self.output_dim = output_dim super(MyLayer, self).__init__(**kwargs) def build(self, input_shape): # 为该层

  • 一小时学会TensorFlow2之自定义层

    目录 概述 Sequential Model & Layer 案例 数据集介绍 完整代码 概述 通过自定义网络, 我们可以自己创建网络并和现有的网络串联起来, 从而实现各种各样的网络结构. Sequential Sequential 是 Keras 的一个网络容器. 可以帮助我们将多层网络封装在一起. 通过 Sequential 我们可以把现有的层已经我们自己的层实现结合, 一次前向传播就可以实现数据从第一层到最后一层的计算. 格式: tf.keras.Sequential( layers=No

  • 一小时学会TensorFlow2之全连接层

    目录 概述 keras.layers.Dense keras.Squential 概述 全链接层 (Fully Connected Layer) 会把一个特质空间线性变换到另一个特质空间, 在整个网络中起到分类器的作用. keras.layers.Dense keras.layers.Dense可以帮助我们实现全连接. 格式: tf.keras.layers.Dense( units, activation=None, use_bias=True, kernel_initializer='glo

  • 一小时学会TensorFlow2之基本操作1实例代码

    目录 概述 创建数据 创建常量 创建数据序列 创建图变量 tf.zeros tf.ones tf.zeros_like tf.ones_like tf.fill tf.gather tf.random 正态分布 均匀分布 打乱顺序 获取数据信息 获取数据维度 数据是否为张量 数据转换 转换成张量 转换数据类型 转换成 numpy 概述 TensorFlow2 的基本操作和 Numpy 的操作很像. 今天带大家来看一看 TensorFlow 的基本数据操作. 创建数据 详细讲解一下 TensorF

  • 一小时学会TensorFlow2之基本操作2实例代码

    目录 索引操作 简单索引 Numpy 式索引 使用 : 进行索引 tf.gather tf.gather_nd tf.boolean_mask 切片操作 简单切片 step 切片 维度变换 tf.reshape tf.transpose tf.expand_dims tf.squeeze Boardcasting tf.boardcast_to tf.tile 数学运算 加减乘除 log & exp pow & sqrt 矩阵相乘 @ 索引操作 简单索引 索引 (index) 可以帮助我们

  • 一小时学会TensorFlow2之Fashion Mnist

    目录 描述 Tensorboard 创建 summary 存入数据 metrics metrics.Mean() metrics.Accuracy() 变量更新 &重置 案例 pre_process 函数 get_data 函数 train 函数 test 函数 main 函数 完整代码 可视化 描述 Fashion Mnist 是一个类似于 Mnist 的图像数据集. 涵盖 10 种类别的 7 万 (6 万训练集 + 1 万测试集) 个不同商品的图片. Tensorboard Tensorbo

  • 一小时学会TensorFlow2之大幅提高模型准确率

    目录 过拟合 Regulation 公式 例子 动量 公式 例子 学习率递减 过程 例子 Early Stopping Dropout 过拟合 当训练集的的准确率很高, 但是测试集的准确率很差的时候就, 我们就遇到了过拟合 (Overfitting) 的问题. 如图: 过拟合产生的一大原因是因为模型过于复杂. 下面我们将通过讲述 5 种不同的方法来解决过拟合的问题, 从而提高模型准确度. Regulation Regulation 可以帮助我们通过约束要优化的参数来防止过拟合. 公式 未加入 r

  • Python入门教程 超详细1小时学会Python

    为什么使用Python    假设我们有这么一项任务:简单测试局域网中的电脑是否连通.这些电脑的ip范围从192.168.0.101到192.168.0.200. 思路:用shell编程.(Linux通常是bash而Windows是批处理脚本).例如,在Windows上用ping ip 的命令依次测试各个机器并得到控制台输出.由于ping通的时候控制台文本通常是"Reply from ... " 而不通的时候文本是"time out ... " ,所以,在结果中进行

随机推荐