深度学习6-自定义层详解

文章目录

      • 1.如何自定义层
      • 2.三种方法自定义层
        • 方法一
        • 方法二
        • 方法三
        • 添加不可训练参数
      • 3.自定义层的注意事项
        • 注意一
        • 注意二
        • 注意三
        • 注意四
        • 注意五
      • 4.案例讲解

深度学习6-自定义层详解_第1张图片

1.如何自定义层

深度学习6-自定义层详解_第2张图片
深度学习6-自定义层详解_第3张图片
深度学习6-自定义层详解_第4张图片
深度学习6-自定义层详解_第5张图片
深度学习6-自定义层详解_第6张图片

2.三种方法自定义层

深度学习6-自定义层详解_第7张图片
深度学习6-自定义层详解_第8张图片

方法一

import tensorflow as tf

#自定义全连接层
class Linear(tf.keras.layers.Layer):

    def __init__(self, units=1, input_dim=4):
        super(Linear, self).__init__() 
        
        # 随机初始化张量
        w_init = tf.random_normal_initializer()
        # tf.Variable用来初始化一些变量
        self.w = tf.Variable(initial_value=w_init(shape=(input_dim, units),dtype='float32'), trainable=True)
        
        b_init = tf.zeros_initializer()
        self.b = tf.Variable(initial_value=b_init(shape=(units,),dtype='float32'),trainable=True)

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


x = tf.constant(data) #(150,4)
linear_layer = Linear(units = 1, input_dim=4) 
y = linear_layer(x)
print(y.shape) #(150,1)

方法二

# 使用self.add_weight来创建变量
class Linear(tf.keras.layers.Layer):
    
    def __init__(self,units=1,input_dim=4):
        super(Linear,self).__init__()
        
        self.w = self.add_weight(shape=(input_dim,units),
                                initializer = 'random_normal',
                                trainable = True)
        
        self.b = self.add_weight(shape=(units,),
                                initializer = 'zeros',
                                trainable = True)
        
    def call(self,inputs):
        # 定义前向传播
        return tf.matmul(inputs,self.w) + self.b
    

x = tf.constant(data)
linear_layer = Linear(units=1,input_dim=4)
y = linear_layer(x)
print(y.shape)    # (150, 1)

方法三

# build函数中创建变量
class Linear(tf.keras.layers.Layer):
    
    def __init__(self,units = 32):
        super(Linear,self).__init__()
        self.units = units
        
    def build(self,input_shape):   # (150,4)
        
        self.w = self.add_weight(shape=(input_shape[-1],self.units),
                                initializer = 'random_normal',
                                trainable = True)
        
        self.b = self.add_weight(shape=(self.units,),
                                initializer = 'random_normal',
                                trainable = True)
        super(Linear,self).build(input_shape)
        
    def call(self,inputs):
        return tf.matmul(inputs,self.w) + self.b
    
    
x = tf.constant(data)  # (150,4)
linear_layer = Linear(units=1)
y = linear_layer(x)
print(y.shape)  # (150, 1) 

添加不可训练参数

class Linear(tf.keras.layers.Layer):

    def __init__(self, units=32):
        super(Linear, self).__init__()
        self.units = units			# 隐层

    def build(self, input_shape):
        
        self.w = self.add_weight(shape=(input_shape[-1], self.units),
                                 initializer='random_normal',
                                 trainable=True)
        # 将trainable设置为False,如果进行反向传播,b就不可训练
        self.b = self.add_weight(shape=(self.units,),
                                 initializer='random_normal',
                                 trainable=False)
        super(Linear,self).build(input_shape)

    def call(self, inputs):
        return tf.matmul(inputs, self.w) + self.b
    
    
    
x = tf.constant(data)
linear_layer = Linear(units = 1)
y = linear_layer(x)
print(y.shape)

深度学习6-自定义层详解_第9张图片

3.自定义层的注意事项

注意一

深度学习6-自定义层详解_第10张图片
深度学习6-自定义层详解_第11张图片

注意二

深度学习6-自定义层详解_第12张图片

注意三

深度学习6-自定义层详解_第13张图片
深度学习6-自定义层详解_第14张图片

注意四

在这里插入图片描述

注意五

深度学习6-自定义层详解_第15张图片

4.案例讲解

# build函数中创建变量用来自定义层
# 自定义一个全连接层
import tensorflow as tf
# 全连接层
class MyDense(tf.keras.layers.Layer):
    def __init__(self,units=32,**kwargs):
        self.units = units
        super(MyDense,self).__init__(**kwargs)
    
    # build函数一般定义Layer需要被训练的参数
    def build(self,input_shape):
        # 初始化张量
        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')
        super(MyDense,self).build(input_shape)    # 相当于设置self.build = True
        
    # call方法一般定义正向传播运算逻辑,__call__方法调用它
    def call(self,inputs):
        # 定义前向传播
        return tf.matmul(inputs,self.w) + self.b
    
    # 如果要让自定义的Layer通过函数Functional API组合成模型时可以序列化,需要自定义get_config方法
    # get_config作用是获取该层的参数配置以便模型保存时使用
    def get_config(self):
        config = super(MyDense,self).get_config()
        config.update({
     'units':self.units})
        return config


from sklearn import datasets
iris = datasets.load_iris()
data = iris.data
labels = iris.target
data.shape   # (150,4)
labels.shape # (150,)


# shuffle数据打乱
import numpy as np
data = np.concatenate((data,labels.reshape(150,1)),axis=-1)
np.random.shuffle(data)
labels = data[:,-1]
data = data[:,:4]


# 函数式构建网络
inputs = tf.keras.Input(shape=(4,))   # 输入
x = MyDense(units=16)(inputs)         # 含有16个神经元的第一层隐层
x= tf.nn.tanh(x)                      # 激活函数
x = MyDense(units=3)(x)               # 输出层
predictions = tf.nn.softmax(x)        # 激活函数
model = tf.keras.Model(inputs = inputs,outputs=predictions)  # 模型



# 定义优化器、损失函数、评估函数
model.compile(optimizer=tf.keras.optimizers.Adam(),                                  # Adam
             loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),   # 交叉熵损失函数
              metrics=[tf.keras.metrics.SparseCategoricalAccuracy()])                # acc准确率

model.fit(data,labels,batch_size=32,epochs=100,shuffle=True)


# 保存模型
model.save('keras_model_tf_version.h5')
# 告诉模型如何可解析重建自定义网络层
_custom_objects = {
     
    'MyDense':MyDense,
}

# 加载模型
new_model = tf.keras.models.load_model('keras_model_tf_version.h5',custom_objects=_custom_objects)
y_pred = new_model.predict(data)

np.argmax(y_pred,axis=1)

深度学习6-自定义层详解_第16张图片
深度学习6-自定义层详解_第17张图片

你可能感兴趣的:(深度学习,深度学习,tensorflow,神经网络,自定义层)