TensorFlow 概述

  • 常用的部分API
    在这里插入图片描述

  • 像 Numpy 一样使用

    tf.constant()
    tf.add()
    tf.multiply()
    tf.square()
    tf.exp()
    tf.sqrt()
    tf.reshape()
    tf.squeeze()
    tf.tile()
    tf.reduce_mean()
    tf.reduce_sum()
    tf.math.log() # 还有很多...
    
  • Keras 在keras.backend中有自己的底层API,例如

    K = keras.backend
    K.square(K.transpose(t)) + 10
    
  • NumPy 默认使用64位精度,TensorFlow 使用32位精度。当从 NumPy 数组创建张量时,请确保 dtype=tf.float32

  • 类型转换 tf.cast()

    t2 = tf.constant(40., dtype=tf.float64)
    tf.constant(2.0) + tf.cast(t2, tf.float32)
    
  • 使用可变的张量 tf.Variable, 因为需要反向传播进行调整,另外还可能需要改变其他参数(如动量优化器跟踪过去的梯度)

  • 其他数据结构:稀疏张量 tf.SparseTensor,张量数组 tf.TensorArray,不规则张量 tf.SparseTensor

  • 加载数据集

    import tensorflow_datasets as tfds
    datasets = tfds.load(name="mnist")
    mnist_train, mnist_test = datasets["train"], datasets["test"]
    

定制模型和训练算法-详见hands-on-ml-12.3

自定义损失函数-示例

def huber_fn(y_true, y_pred):
    error = y_true - y_pred
    is_small_error = tf.abs(error) < 1
    squared_loss = tf.square(error) / 2
    linear_loss  = tf.abs(error) - 0.5
    return tf.where(is_small_error, squared_loss, linear_loss)

# 应用示例
model.compile(loss=huber_fn, optimizer="nadam", metrics=["mae"])

保存和加载包含自定义组件的模型

  • 保存包含自定义损失函数的模型效果很好,因为Keras会保存函数的名称
  • 每次加载时,需要提供一个字典,将函数名称映射到实际函数
    model = keras.models.load_model("my_model_with_a_custom_loss.h5",custom_objects={"huber_fn": huber_fn})
    

自定义激活函数、初始化、正则化和约束

def my_softplus(z): # tf.nn.softplus(z)
return tf.math.log(tf.exp(z) + 1.0)

def my_glorot_initializer(shape, dtype=tf.float32):
stddev = tf.sqrt(2. / (shape[0] + shape[1]))
return tf.random.normal(shape, stddev=stddev, dtype=dtype)

def my_l1_regularizer(weights):
return tf.reduce_sum(tf.abs(0.01 * weights))

def my_positive_weights(weights): # tf.nn.relu(weights)
return tf.where(weights < 0., tf.zeros_like(weights), weights)

# 应用示例
layer = keras.layers.Dense(1, activation=my_softplus,
                        kernel_initializer=my_glorot_initializer,
                        kernel_regularizer=my_l1_regularizer,
                        kernel_constraint=my_positive_weights)

自定义层-identical block

  • 创建不带任何权重的自定义层 keras.layers.Lambda
    exponential_layer = keras.layers.Lambda(lambda x: tf.exp(x))
    

自定义模型-以残差块为例

在这里插入图片描述

class ResidualBlock(keras.layers.Layer):
    def __init__(self, n_layers, n_neurons, **kwargs):
        super().__init__(**kwargs)
        self.hidden = [keras.layers.Dense(n_neurons, activation="elu",
                                          kernel_initializer="he_normal")
                       for _ in range(n_layers)]
    def call(self, inputs):
        Z = inputs
        for layer in self.hidden:
            Z = layer(Z)
        return inputs + Z

class ResidualRegressor(keras.models.Model):
    def __init__(self, output_dim, **kwargs):
        super().__init__(**kwargs)
        self.hidden1 = keras.layers.Dense(30, activation="elu",
                                          kernel_initializer="he_normal")
        self.block1 = ResidualBlock(2, 30)
        self.block2 = ResidualBlock(2, 30)
        self.out = keras.layers.Dense(output_dim)
    def call(self, inputs):
        Z = self.hidden1(inputs)
        for _ in range(1 + 3):
            Z = self.block1(Z)
        Z = self.block2(Z)
        return self.out(Z)
  • 可以像使用任何其他模型一样使用此模型(compile, fit, evaluate, predict)
  • 如果还要使用 save() 方法保存模型并使用 keras.models.load_model() 函数加载模型,则必须在 ResidualBlock类 和 ResidualRegressor类 中都实现 get_config() 方法
  • 可以使用 save_weights() 和 load_weights() 方法保存和加载权重。

自定义基于模型内部的损失和指标

自动微分求梯度

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐