(三)深度学习计算 -- 3 自定义层

3. 自定义层

本节将介绍如何自定义一个层,从而可以被重复调用。

import tensorflow as tf
import numpy as np

3.1 custom layer without parameters

3.1.1 自定义层

定义一个不含模型参数的自定义层:

class CenteredLayer(tf.keras.layers.Layer):
    def __init__(self):
        super().__init__()
        
    def call(self,inputs):
        return inputs - tf.reduce_mean(inputs)

其中,CenteredLayer类通过继承tf.keras.layers.Layer类,自定义了一个将输入减掉均值后输出的层,并将层的计算定义在了call函数里。


该层的实例化及前向计算:

layer = CenteredLayer()
layer(np.array([1,2,3,4,5]))

输出:

<tf.Tensor: id=16, shape=(5,), dtype=int64, numpy=array([-2, -1,  0,  1,  2])>

3.1.2 模型构造

利用该层构造模型:

net = tf.keras.Sequential()
net.add(tf.keras.layers.Flatten())
net.add(tf.keras.layers.Dense(20))
net.add(CenteredLayer())

Y = net(X)
Y

输出:

<tf.Tensor: id=47, shape=(2, 20), dtype=float32, numpy=
array([[ 0.34438056,  0.06978315, -0.41926566,  0.2242881 ,  0.29170805,
         0.11057639,  0.23599279, -0.23065972,  0.63485736,  0.21090072,
        -0.330887  , -0.3979441 ,  0.1462583 , -0.12568481,  0.5106406 ,
         0.77171034,  0.17244986, -0.67148066,  0.807409  , -0.07428499],
       [ 0.3037144 , -0.58068335, -0.3071456 , -0.2411271 , -0.00998123,
        -0.21790652, -0.10612971, -0.7001431 ,  0.40697873, -0.58122313,
        -0.97674805, -0.13996252,  0.07470441, -0.5286119 ,  0.4424529 ,
         0.20922649,  0.3125742 ,  0.2707773 ,  1.024564  , -0.9360792 ]],
      dtype=float32)>

自定义层输出的均值:

tf.reduce_mean(Y)

输出:

<tf.Tensor: id=49, shape=(), dtype=float32, numpy=-1.7881394e-08>


3.2 custom layer with parameters

此外,支持自定义含模型参数的自定义层。

3.2.1 自定义层

模型参数可通过训练学得:

class myDense(tf.keras.layers.Layer):
    def __init__(self, units):
        super().__init__()
        self.units = units
        
    def build(self, input_shape):
    """
    input_shape: 第一次运行call()时,参数inputs的形状。
    tf.keras.layers.Layer.add_weight: Adds a new variable to the layer.
    """
        self.w = self.add_weight(name='w',
                                 shape=(input_shape[-1], self.units),
                                 initializer=tf.random_normal_initializer())
        self.b = self.add_weight(name='b',
                                 shape=(self.units),
                                 initializer=tf.zeros_initializer())
        
    def call(self, inputs):
        y_pred = tf.matmul(inputs, self.w) + self.b
        return y_pred

实例化及前向计算:

dense = myDense(3)
Y = dense(X)
Y

输出:

<tf.Tensor: id=32, shape=(2, 3), dtype=float32, numpy=
array([[-0.05748406,  0.128207  , -0.02014272],
       [-0.07343882,  0.11930768, -0.09989622]], dtype=float32)>

访问模型参数:

dense.get_weights()

输出:

[array([[ 0.03788483,  0.05446365, -0.00342109],
        [ 0.01979028,  0.07090656, -0.00471796],
        [-0.00542502,  0.07547017, -0.07470261],
        [ 0.00170084, -0.00170659, -0.07881869],
        [ 0.02729396,  0.07794935, -0.01462456],
        [-0.01458358, -0.01152581,  0.0183306 ],
        [-0.05630199,  0.0834111 ,  0.05665946],
        [-0.03011301, -0.01305497,  0.01113685],
        [ 0.07111349,  0.04045207, -0.00295244],
        [ 0.06290419, -0.02640768, -0.04089865],
        [ 0.02854273,  0.04196091, -0.01317766],
        [-0.01049933, -0.04766244, -0.04543113],
        [-0.05666549,  0.06246523, -0.06552341],
        [ 0.02021227,  0.0038689 ,  0.11742865],
        [ 0.06721621,  0.00784351, -0.00665099],
        [-0.04588777, -0.02955816, -0.01156068],
        [-0.0953302 , -0.04818133,  0.01506012],
        [-0.02355155, -0.03037887, -0.09637806],
        [-0.04718609,  0.02179381,  0.02490507],
        [ 0.02174933, -0.01841915, -0.00988414]], dtype=float32),
 array([0., 0., 0.], dtype=float32)]

查看模型参数shape:

dense.get_weights()[0].shape

输出:

(20, 3)

3.2.2 模型构造

模型构造及实例化:

net = tf.keras.models.Sequential()
net.add(myDense(8))
net.add(myDense(1))
Y = net(X)
Y

输出:

<tf.Tensor: id=57, shape=(2, 1), dtype=float32, numpy=
array([[0.01952953],
       [0.01150553]], dtype=float32)>


参考

《动手学深度学习》(TF2.0版)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值