当前位置: 首页 > article >正文

tf.Keras (tf-1.15)使用记录2-基于tf.keras.layers创建层

tf.keras.layers是keras的主要网络创建方法,里面已经有成熟的网络层,也可以通过继承的方式自定义神经网络层。
在keras的model定义中,为了保证所有对数据的操作都是可追溯、可保存、可反向传播,需要保证对数据的任何操作都是基于tf.keras.layers的父类的,否则模型就可能出问题。

1、使用tf.keras.layers自带的层

注意下面这些都是类,还需要实例化之后传入x,即layer(x)

Dense (全连接层)

layer = tf.keras.layers.Dense(units, activation=None, use_bias=True)
  • units: 输出空间的维度(神经元数量)
  • activation: 激活函数,如 ‘relu’, ‘sigmoid’, ‘tanh’ 等
  • use_bias: 是否使用偏置项

Dropout

layer = tf.keras.layers.Dropout(rate, noise_shape=None, seed=None)
  • rate: 需要丢弃的输入比例,范围在 0 到 1 之间
  • noise_shape: 可选,用于指定丢弃模式的形状
  • seed: 可选,用于设置随机种子

BatchNormalization

layer = tf.keras.layers.BatchNormalization(axis=-1, momentum=0.99, epsilon=0.001, center=True, scale=True)
  • axis: 需要规范化的轴
  • momentum: 移动平均的动量
  • epsilon: 添加到方差的小数值,以避免除以零
  • center: 如果为True,则减去均值
  • scale: 如果为True,则乘以标准差的倒数

Embedding(返回值会增加一维)
Embedding 层用于将正整数(索引值)转换为固定大小的稠密向量。这种层通常用于处理文本数据,将单词映射为向量,这些向量更适合神经网络处理。

layer = tf.keras.layers.Embedding(input_dim, output_dim, embeddings_initializer='uniform', mask_zero=False)
  • input_dim: 词汇表大小(最大整数索引 + 1)
  • output_dim: 嵌入向量的维度
  • embeddings_initializer: 嵌入矩阵的初始化方法
  • mask_zero: 是否将 0 视为需要屏蔽的特殊值
  • 注意,一般embedding都是第一层,传入input_length=n_features参数用来指示有几个整数特征用来被处理。使用示例:
import pandas as pd
import numpy as np
import tensorflow as tf
from sklearn.model_selection import train_test_split

# 创建示例数据
n_samples = 1000
n_features = 5
max_value = 100

data = np.random.randint(0, max_value, size=(n_samples, n_features))
labels = np.random.randint(0, 2, size=(n_samples,))

df = pd.DataFrame(data, columns=[f'feature_{i}' for i in range(n_features)])
df['label'] = labels

# 分割训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(df.drop('label', axis=1), df['label'], test_size=0.2, random_state=42)

# 创建模型
model = tf.keras.Sequential([
    tf.keras.layers.Embedding(input_dim=max_value, output_dim=32, input_length=n_features),  #  输出 (None, 5, 32) ;参数量为100 * 32 * 5
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(64, activation='relu'),
    tf.keras.layers.Dense(1, activation='sigmoid')
])
# 打印模型摘要
model.summary()

LSTM

layer = tf.keras.layers.LSTM(units, activation='tanh', recurrent_activation='sigmoid', use_bias=True, return_sequences=False)
  • units: 输出空间的维度
  • activation: 激活函数
  • recurrent_activation: 循环步骤中使用的激活函数
  • use_bias: 是否使用偏置向量
  • return_sequences: 是否返回完整序列或仅返回最后一个输出

GRU

layer = tf.keras.layers.GRU(units, activation='tanh', recurrent_activation='sigmoid', use_bias=True, return_sequences=False)

参数含义与 LSTM 相同

Bidirectional (双向包装器)

layer = tf.keras.layers.Bidirectional(layer, merge_mode='concat')
  • layer: 要包装的 RNN 层实例
  • merge_mode: 定义如何组合正向和反向 RNN 的输出,可以是 ‘sum’, ‘mul’, ‘concat’, ‘ave’ 等

LayerNormalization

layer = tf.keras.layers.LayerNormalization(axis=-1, epsilon=0.001, center=True, scale=True)
  • axis: 要规范化的轴
  • epsilon: 添加到方差的小数值,以避免除以零
  • center: 如果为True,则减去均值
  • scale: 如果为True,则乘以标准差的倒数

除了上面的神经网络层,以下是一些常用的操作层,这些操作都默认不改变第一维度的batch_size:

Reshape

layer = tf.keras.layers.Reshape(target_shape) # target_shape是一个tuple

改变输入的形状,不改变数据。

import tensorflow as tf
import numpy as np

# 创建一个模型,将 (batch, 12) 的输入重塑为 (batch, 3, 4)
model = tf.keras.Sequential([
    tf.keras.layers.Input(shape=(12,)),
    tf.keras.layers.Reshape((3, 4))
])

# 测试模型
input_data = np.array([[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]])
output = model.predict(input_data)

print("Input shape:", input_data.shape) # Input shape: (1, 12)
print("Output shape:", output.shape) # Output shape: (1, 3, 4)

Flatten

layer = tf.keras.layers.Flatten()

将输入展平成一维。

Permute

layer = tf.keras.layers.Permute(dims)

按指定模式重排输入的维度,本质上是进行维度的交换,最常用的场景是对张量进行后两维度的转置,比如注意力计算中的K的转置。

import tensorflow as tf
import numpy as np

# 创建一个模型,将输入的维度从 (batch, dim1, dim2, dim3) 变为 (batch, dim3, dim1, dim2)
model = tf.keras.Sequential([
    tf.keras.layers.Input(shape=(10, 20, 30)),
    tf.keras.layers.Permute((3, 1, 2))  # 不会处理0维度因为是batchsize;123->321
])

# 测试模型
input_data = np.random.rand(1, 10, 20, 30)
output = model(input_data)

print("Input shape:", input_data.shape)  # (1, 10, 20, 30)
print("Output shape:", output.shape)  # (1, 30, 10, 20)

RepeatVector

layer = tf.keras.layers.RepeatVector(n)

重复输入 n 次。在batch后面增加一维度n,把整个向量都重复n遍。

Lambda

layer = tf.keras.layers.Lambda(function)

封装任意表达式为 Keras 层;这个函数非常有意思,可以把很多数学运算直接封装成tf.keras的layers,例如:

# 将输入乘以2
layer1 = tf.keras.layers.Lambda(lambda x: x * 2)

# 自定义一个激活函数
def custom_activation(x):
    return tf.nn.tanh(x) * tf.nn.sigmoid(x)
layer2 = tf.keras.layers.Lambda(custom_activation)

# 将2D输入转换为3D
layer3 = tf.keras.layers.Lambda(lambda x: tf.expand_dims(x, axis=-1))

# 复杂操作
def complex_operation(x):
    # 假设x是一个2D张量
    mean = tf.reduce_mean(x, axis=-1, keepdims=True)
    centered = x - mean
    return tf.nn.l2_normalize(centered, axis=-1)
layer4 = tf.keras.layers.Lambda(complex_operation)

# 待参数的函数
def parameterized_function(x, a):
    return x * a
layer5 = tf.keras.layers.Lambda(lambda x: parameterized_function(x, a=0.5))

# 处理多个输入
layer6 = tf.keras.layers.Lambda(lambda inputs: inputs[0] * inputs[1])

Concatenate

layer = tf.keras.layers.Concatenate(axis=-1)

沿指定轴连接一系列输入。

Add

layer = tf.keras.layers.Add()

计算输入的和。

Subtract

layer = tf.keras.layers.Subtract()

计算两个输入的差。

Multiply

layer = tf.keras.layers.Multiply()

计算输入的元素级乘积。

Average

layer = tf.keras.layers.Average()

计算输入的平均值。

Maximum

layer = tf.keras.layers.Maximum()

计算输入的逐元素最大值。

Minimum

layer = tf.keras.layers.Minimum()

计算输入的逐元素最小值。

2、自定义自己的层

注意需要继承tf.keras.layers.Layer父类,以及注意传入**kwargs关键字参数。

1)自定义一个dense层

self.add_weight方法是用来初始化模型参数的。

import tensorflow as tf

class MyDenseLayer(tf.keras.layers.Layer):
    def __init__(self, num_outputs, activation=None,  **kwargs):
        super(MyDenseLayer, self).__init__(**kwargs)
        self.num_outputs = num_outputs
        self.activation = tf.keras.activations.get(activation)

    def build(self, input_shape):
        self.w = self.add_weight("kernel",
                                      shape=[int(input_shape[-1]),
                                             self.num_outputs])

        self.b = self.add_weight("bias",
                                    shape=[self.num_outputs,],
                                    initializer='zeros')

    def call(self, input):
        z = tf.matmul(input, self.w) + self.b
        return self.activation(z) if self.activation else z

# 使用自定义层创建模型
model = tf.keras.Sequential([
    MyDenseLayer(32, activation='relu', input_shape=(222,)),  # 注意这个input必须指定
    MyDenseLayer(64, activation='relu'),
    tf.keras.layers.Dense(10, activation='softmax')
])

model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
model.summary()
2)自定义一个单调层(mixing net)和一个重复层

call函数的输入inputs就是固定的,build函数每次实例化只调用一次。

class MonoDense(tf.keras.layers.Layer):
    def __init__(self, output_dim, activation='elu', is_b=True, **kwargs):
        super(MonoDense, self).__init__(**kwargs)
        self.activation = tf.keras.activations.get(activation)        
        self.output_dim = output_dim
        self.is_b = is_b
        print('monotonic model initial!')
    
    def build(self, input_shape):
        # 确保输入是一个包含三个元素的列表
        assert isinstance(input_shape, list) and len(input_shape) >= 2
    
    def call(self, inputs):
        if self.is_b:
            inputs_x, inputs_w, inputs_b =inputs[0], inputs[1], inputs[2]

            input_shape = tf.shape(inputs_x)

            self.input_dim = input_shape[1]
            self.batch_size = input_shape[0]
            # print(self.batch_size, self.input_dim, self.output_dim)

            w = tf.reshape(inputs_w, [self.batch_size, self.input_dim, self.output_dim])
            # print(inputs)

            b = tf.reshape(inputs_b, [self.batch_size, 1, self.output_dim])
            # print(inputs)

            inputs_x = tf.reshape(inputs_x, [self.batch_size, 1, self.input_dim])
            output = tf.matmul(inputs_x, tf.maximum(w, 0)) + b
            output2 = tf.reshape(output, [self.batch_size, self.output_dim])
        else:
            inputs_x, inputs_w=inputs[0], inputs[1]

            input_shape = tf.shape(inputs_x)

            self.input_dim = input_shape[1]
            self.batch_size = input_shape[0]
            # print(self.batch_size, self.input_dim, self.output_dim)
            w = tf.reshape(inputs_w, [self.batch_size, self.input_dim, self.output_dim])
            # print(inputs)
            inputs_x = tf.reshape(inputs_x, [self.batch_size, 1, self.input_dim])
            output = tf.matmul(inputs_x, tf.maximum(w, 0))
            output2 = tf.reshape(output, [self.batch_size, self.output_dim])
            
        return self.activation(output2)
    
    
class RepeatToMatrixLayer(tf.keras.layers.Layer):
    def __init__(self, n, max_t, **kwargs):
        super(RepeatToMatrixLayer, self).__init__(**kwargs)
        self.n = n
        self.max_t = max_t

    def call(self, inputs):
        inputs2 = tf.reshape(inputs, [-1])
        return (tf.tile(tf.expand_dims(inputs2, axis=-1), [1, self.n]) + 1) / (self.max_t + 1)  # 做了一个归一化处理
    

 layer1 = RepeatToMatrixLayer(16, 32, name='my_repeat_layer')
 layer2 = MonoDense(64, activation='tanh', name='my_z_with_t', is_b=True)  # 这里的激活函数比较重要

http://www.kler.cn/a/528361.html

相关文章:

  • arkts bridge使用示例
  • deepseek核心技术:MLA架构-多头潜在注意力
  • 【HarmonyOS之旅】基于ArkTS开发(三) -> 兼容JS的类Web开发(二)
  • 基于Python的药物相互作用预测模型AI构建与优化(上.文字部分)
  • Python从0到100(八十六):神经网络-ShuffleNet通道混合轻量级网络的深入介绍
  • 电子电气架构 --- 在智能座舱基础上定义人机交互
  • 【JavaEE】Spring(7):统一功能处理
  • mac连接linux服务器
  • 4 Hadoop 面试真题
  • linux的用法
  • 数据结构初探:链表之单链表篇
  • 玉米苗和杂草识别分割数据集labelme格式1997张3类别
  • 【Linux】opencv在arm64上提示找不到libjasper-dev
  • 【涟漪散点图】——1
  • C#从XmlDocument提取完整字符串
  • Spring Boot 实例解析:配置文件
  • oracle:子查询
  • Autogen_core源码:_subscription.py
  • https的原理
  • Cesium+Vue3教程(011):打造数字城市
  • 网络工程师 (12)软件开发与测试
  • CNN的各种知识点(三):有关于VGG16 的结构展开的问题(1)
  • 【C++篇】哈希表
  • Maya的id贴图
  • Linux网络 HTTP cookie 与 session
  • html的字符实体和颜色表示