- 快召唤伙伴们来围观吧
- 微博 QQ QQ空间 贴吧
- 文档嵌入链接
- <iframe src="https://www.slidestalk.com/GDG/TensorFlow_Keras_customize_component?embed" frame border="0" width="640" height="360" scrolling="no" allowfullscreen="true">复制
- 微信扫一扫分享
TensorFlow Keras 自定义组件的实现机制和代码实践
孔晓泉,机器学习方向-谷歌开发技术专家(Google Developer Expert for Machine Learning)。TensorFlow 和 TensorFlow Addons contributor。上海 TensorFlow User Group (TFUG) 社区主要组织者。Rasa (an open-source conversational AI framework) SuperHero contributor 和 Rasa 中国社区 Founder。曾就职于 Alibaba Group 从事 NLP (Natural Language Processing) 算法和框架研发工作。拥有多年的 NLP 算法研发和落地经验。
- TensorFlow Keras 简介
- Keras 原生扩展机制
- TensorFlow Keras 扩展机制
- 编写你的自定义扩展代码
- 面向代码编程
展开查看详情
1 .
2 .孔晓泉 谷歌开发技术专家(GDE)(Machine Learning方向) TensorFlow 和 TensorFlow Addons contributor。 TFUG社区主要组织者。Rasa (an open-source conversational AI framework) SuperHero contributor 和 Rasa 中国社区 Founder。曾就职于 Alibaba Group 从事 NLP 算法和框架研发工作。
3 .TensorFlow Keras 自定义组件 实现机制和代码实践
4 .• TensorFlow Keras 简介 • Keras 原生扩展机制 • TensorFlow Keras 扩展机制 • 编写你的自定义扩展代码 • 面向代码编程
5 .TensorFlow Keras 简介
6 .TensorFlow Keras 是 TensorFlow 对 Keras API 规范的实现。 Keras API 规范不是 https://keras.io/ 的那个 Keras 具体实现。 Keras API 规范定了一组用于构建和训练模型的高级 API。 其具有简单直观、容易学习、写起来代码简洁、扩展方便等特点。 Keras API 目前已经成为多数机器学习框架在 User level API 设计上的重点参考对 象。
7 .Keras API 规范 涵盖: - 模型的表达 - 损失的表达 - 优化器 - 激活函数 - metric的计算 - 插件机制
8 .TensorFlow Keras VS Keras Keras (https://keras.io/) 的多个 backend 中就有 TensorFlow. 那么原生的 Keras 和 TensorFlow Keras 有什么区别呢? TensorFlow Keras 其中包括对 TensorFlow 特定功能的支持, 例如 Eager Execution,tf.data pipeline 和 Estimator。 tf.keras 使 TensorFlow 易于使用,而不会牺牲灵活性和性能。
9 .François Chollet
10 .Keras 原生扩展机制
11 .自定义 Layer
12 .自定义 metric
13 .自定义 Callback
14 .TensorFlow Keras 扩展机制
15 .TensorFlow Keras: • 兼容 Karas • 为 Keras (https://keras.io/) 编写的自定义组件无需修改即可 直接在 TensorFlow Keras 调用 • 增加了自己的实现方案 • 采用了更加现代更加灵活的自定义实现方式 • 对独有的 Eager Execution 的支持 • tf.function 自动生成图
16 .自定义 Layer class Sparsemax(tf.keras.layers.Layer): def __init__(self, axis=-1, **kwargs): super(Sparsemax, self).__init__(**kwargs) self.supports_masking = True self.axis = axis def call(self, inputs): return sparsemax(inputs, axis=self.axis) def get_config(self): config = {'axis': self.axis} base_config = super(Sparsemax, self).get_config() return dict(list(base_config.items()) + list(config.items())) def compute_output_shape(self, input_shape): return input_shape
17 .自定义 Loss class ContrastiveLoss(tf.keras.losses.Loss): def __init__(self, margin=1.0, reduction=tf.keras.losses.Reduction.SUM_OVER_BATCH_SIZE, name="contrasitve_loss"): super(ContrastiveLoss, self).__init__(reduction=reduction, name=name) self.margin = margin def call(self, y_true, y_pred): return contrastive_loss(y_true, y_pred, self.margin) def get_config(self): config = { "margin": self.margin, } base_config = super(ContrastiveLoss, self).get_config() return dict(list(base_config.items()) + list(config.items()))
18 .自定义 Metric class RSquare(tf.keras.metrics.Metric): def __init__(self, name='r_square', dtype=tf.float32): super(RSquare, self).__init__(name=name, dtype=dtype) self.squared_sum = self.add_weight("squared_sum", initializer="zeros") self.sum = self.add_weight("sum", initializer="zeros") self.res = self.add_weight("residual", initializer="zeros") self.count = self.add_weight("count", initializer="zeros") def update_state(self, y_true, y_pred): y_true = tf.convert_to_tensor(y_true, tf.float32) y_pred = tf.convert_to_tensor(y_pred, tf.float32) self.squared_sum.assign_add(tf.reduce_sum(y_true**2)) self.sum.assign_add(tf.reduce_sum(y_true)) self.res.assign_add( tf.reduce_sum(tf.square(tf.subtract(y_true, y_pred)))) self.count.assign_add(tf.cast(tf.shape(y_true)[0], tf.float32)) def result(self): mean = self.sum / self.count total = self.squared_sum - 2 * self.sum * mean + self.count * mean**2 return 1 - (self.res / total) def reset_states(self): # The state of the metric will be reset at the start of each epoch. self.squared_sum.assign(0.0) self.sum.assign(0.0) self.res.assign(0.0) self.count.assign(0.0)
19 .编写你的自定义扩展代码
20 .自定义 Layer class <LayerNmae>(tf.keras.layers.Layer): def __init__(self): // your code here def build(self, input_shape): // your code here def call(self, inputs): // your code here def get_config(self): // your code here def compute_output_shape(self, input_shape): // your code here
21 .自定义 Layer > __init__ class <LayerNmae>(tf.keras.layers.Layer): use_XXX=True, def __init__(self): XXX_initializer='glorot_uniform’, // your code here XXX_regularizer=None, XXX_constraint=None, def build(self, input_shape): // your code here def call(self, inputs): // your code here def get_config(self): // your code here def compute_output_shape(self, input_shape): // your code here
22 .自定义 Layer > build class <LayerNmae>(tf.keras.layers.Layer): if self.use_XXX: def __init__(self): self.XXX = self.add_weight( // your code here 'XXX', shape=[self.XXX,], def build(self, input_shape): initializer=self.XXX_initializer, // your code here regularizer=self.XXX_regularizer, constraint=self.XXX_constraint, def call(self, inputs): dtype=self.dtype, // your code here trainable=True) else: def get_config(self): self.XXX = None // your code here self.built = True def compute_output_shape(self, input_shape): // your code here
23 .自定义 Layer > call class <LayerNmae>(tf.keras.layers.Layer): return tensor_shape.TensorShape(input_shape) def __init__(self): // your code here def build(self, input_shape): // your code here def call(self, inputs): // your code here def get_config(self): // your code here def compute_output_shape(self, input_shape): // your code here
24 .自定义 Layer > call class <LayerNmae>(tf.keras.layers.Layer): outputs = tf.math.mat_mul(inputs, self.XXX) def __init__(self): return outputs // your code here def build(self, input_shape): // your code here def call(self, inputs): // your code here def get_config(self): // your code here def compute_output_shape(self, input_shape): // your code here
25 .自定义 Layer > call config = { ‘XXX’: self.XXX, class <LayerNmae>(tf.keras.layers.Layer): ‘activation’: def __init__(self): activations.serialize(self.activation), // your code here ‘use_XXX’: self.use_XXX, ‘XXX_initializer’: def build(self, input_shape): initializers.serialize(self.kernel_XXX), // your code here ‘XXX_regularizer’: regularizers.serialize(self.XXX_regularizer), def call(self, inputs): ‘XXX_constraint’: // your code here constraints.serialize(self.XXX_constraint) } def get_config(self): // your code here base_config = super(LayerNmae,self).get_config() def compute_output_shape(self, input_shape): return dict(list(base_config.items()) + // your code here list(config.items()))
26 .自定义 Loss class <LossName>(tf.keras.losses.Loss): def __init__(self, // your code here def call(self, y_true, y_pred): // your code here def get_config(self): // your code here
27 .自定义 Loss class <LossName>(tf.keras.losses.Loss): __init__ 和 get_config 的作用和 def __init__(self, Layer 层的同名方法相似 // your code here def call(self, y_true, y_pred): call() 函数的内容需要实现者自 // your code here 行实现,返回一个实数,这样优 化器才能利用梯度优化网络权重 def get_config(self): // your code here
28 .自定义 Metric class MetricName(tf.keras.metrics.Metric): def __init__(self, name=‘<metric_name>’): // your code here def update_state(self, y_true, y_pred): // your code here def result(self): // your code here def reset_states(self): # The state of the metric will be reset at the start of each epoch. // your code here def get_config(self): // your code here
29 .自定义 Metric class MetricName(tf.keras.metrics.Metric): __init__ 与 get_config 和前面的 def __init__(self, name=‘<metric_name>’): Layer 和 Loss 类的同名方法是 // your code here 一样的 def update_state(self, y_true, y_pred): // your code here 同时,由于 Metric 是有状态的, 所以在 __init__ 里使用 def result(self): self.add_weight() 增加一个状态 // your code here 变量 def reset_states(self): # The state of the metric will be reset at the start of each epoch. // your code here def get_config(self): // your code here