如何将自定义树添加到自定义的Keras层?

发布于 2025-02-02 19:52:56 字数 2475 浏览 1 评论 0原文

我正在尝试将以下教程汇总在一起:

  1. a href =“ https://www.tensorflow.org/decision_forests/tutorials/advanced_colab#creating_a_model_model_model_model_by_by_by_by_handhande
  2. < a href =“ https://www.tensorflow.org/guide/keras/custom_layers_and_models” rel =“ nofollow noreferrer”>通过subclassing
  3. 组成决策森林和神经网络模型

目标是1。创建一个自定义树,2。将其嵌入自定义层,并将其组合到3中。与其他层的模型。

问题在于,在步骤1中,通过使用RandomForestBuilder,该模型被序列化并进行了序列化,从而导致对象的keras.saving.saved.saved_model.load.coremodel.coremodel,

但是,该教程在步骤3中。通过tfdf.keras嵌入了树层。 理想情况下, RandomForestModel

理想情况下,自定义层将通过在其构造函数中调用Random ForestBuilder创建自定义树,但是,鉴于模型的导出和加载,这并不简单。

则会出现错误的错误

下面给出了输入层的结构的错误,如果省略了前者的错误,

builder = tfdf.builder.RandomForestBuilder(
    path="/tmp/manual_model",
    objective = tfdf.py_tree.objective.RegressionObjective(label='tree_result')
)

Tree = tfdf.py_tree.tree.Tree
SimpleColumnSpec = tfdf.py_tree.dataspec.SimpleColumnSpec
ColumnType = tfdf.py_tree.dataspec.ColumnType
RegressionValue = tfdf.py_tree.value.RegressionValue

NonLeafNode = tfdf.py_tree.node.NonLeafNode
LeafNode = tfdf.py_tree.node.LeafNode
NumericalHigherThanCondition = tfdf.py_tree.condition.NumericalHigherThanCondition
CategoricalIsInCondition = tfdf.py_tree.condition.CategoricalIsInCondition

tree = Tree(
    NonLeafNode(
        condition=CategoricalIsInCondition(
            feature=SimpleColumnSpec(name='feature_name', type=ColumnType.CATEGORICAL),
            mask=['class_1'],
            missing_evaluation=False
        ),
        pos_child = LeafNode(value=RegressionValue(value=0.5)),
        neg_child = LeafNode(value=RegressionValue(value=0.6))
    )
)

builder.add_tree(tree)
builder.close()
custom_tree = tf.keras.models.load_model("/tmp/manual_model")

class CustomTree(tf.keras.layers.Layer):
  def __init__(self, custom_tree):
    super(CustomTree, self).__init__()
    self.custom_tree = custom_tree

  def call(self, inputs):
    return self.custom_tree(inputs)


input_layer = tf.keras.layers.Input(shape=(None,), name='feature_name', dtype=tf.string)
output_layer = CustomTree(custom_tree)(input_layer)

model = tf.keras.models.Model(input_layer, output_layer, name='SomeModel')

model.predict(tf.data.Dataset.from_tensor_slices(
    {'feature_name': ['class_1','class_2']}
).batch(1))

I am trying to bring together the following tutorials:

  1. Creating decision tree by hand
  2. Custom layers via subclassing
  3. Composing Decision Forest and Neural Network models

The goal is to 1. Create a custom tree, 2. Embed it into a custom layer and 3. combine it in a model with other layers.

The problem is that in step 1. by using the RandomForestBuilder, the model is serialized and deserialized resulting in object of type keras.saving.saved_model.load.CoreModel

However, the tutorial in step 3. embeds the tree layer via tfdf.keras.RandomForestModel

Ideally, the custom layer would create the custom tree by calling RandomForestBuilder in its constructor, however, this is not straightforward given the exporting and loading of the model.

The below gives error for the structure of the input layer and if the former is omitted gives error for no matching concrete function to call loaded from the SavedModel:

Step 1:

builder = tfdf.builder.RandomForestBuilder(
    path="/tmp/manual_model",
    objective = tfdf.py_tree.objective.RegressionObjective(label='tree_result')
)

Tree = tfdf.py_tree.tree.Tree
SimpleColumnSpec = tfdf.py_tree.dataspec.SimpleColumnSpec
ColumnType = tfdf.py_tree.dataspec.ColumnType
RegressionValue = tfdf.py_tree.value.RegressionValue

NonLeafNode = tfdf.py_tree.node.NonLeafNode
LeafNode = tfdf.py_tree.node.LeafNode
NumericalHigherThanCondition = tfdf.py_tree.condition.NumericalHigherThanCondition
CategoricalIsInCondition = tfdf.py_tree.condition.CategoricalIsInCondition

tree = Tree(
    NonLeafNode(
        condition=CategoricalIsInCondition(
            feature=SimpleColumnSpec(name='feature_name', type=ColumnType.CATEGORICAL),
            mask=['class_1'],
            missing_evaluation=False
        ),
        pos_child = LeafNode(value=RegressionValue(value=0.5)),
        neg_child = LeafNode(value=RegressionValue(value=0.6))
    )
)

builder.add_tree(tree)
builder.close()
custom_tree = tf.keras.models.load_model("/tmp/manual_model")

Step 2:

class CustomTree(tf.keras.layers.Layer):
  def __init__(self, custom_tree):
    super(CustomTree, self).__init__()
    self.custom_tree = custom_tree

  def call(self, inputs):
    return self.custom_tree(inputs)


input_layer = tf.keras.layers.Input(shape=(None,), name='feature_name', dtype=tf.string)
output_layer = CustomTree(custom_tree)(input_layer)

model = tf.keras.models.Model(input_layer, output_layer, name='SomeModel')

model.predict(tf.data.Dataset.from_tensor_slices(
    {'feature_name': ['class_1','class_2']}
).batch(1))

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

夜未央樱花落 2025-02-09 19:52:56

找到以下解决方案:

  1. 以yggdrasil格式导出自定义树:

      builder = tfdf.builder.randomforestbuilder(
         model_format = tfdf.builder.modelformat.yggdrasil_decision_forest,
         路径= self._temp_directory,
         目标=客观)
     
  2. 通过关闭建筑商保存模型后,将树加载为Coremodel:

      builder.close()
    
     Inspector_lib = tfdf.component.inspector.inspector
     Inspector = Inspector_lib.make_inspector(self._temp_directory,file_prefix = none)
    
     custom_tree = tfdf.keras.coremodel(
         任务=目标。任务,
         学习者='手动',
         排名_group = none,
         temp_directory = self._temp_directory)
    
     custom_tree._set_from_yggdrasil_model(
         检查员
         self._temp_directory,
         file_prefix = none, 
         input_model_signature_fn = builder._input_model_signature_fn)
     
  3. 创建一个带有自定义拟合功能的tfdf.keras.cartmodel的模型子类,将自定义树结构分配给模型:

     类Customdt(tfdf.keras.cartmodel):
        def __init __(self,name = none,** kwargs):
            super(customdt,self).__ init __(名称=名称,** kwargs)
    
        def fit(self):
            custom_tree = self.create_custom_tree()
            self._model = custom_tree._model
            self._is_trained.sign(true)
            self.__semantics = custom_tree._semantics
     

Found the following solution:

  1. Export the custom tree in yggdrasil format:

     builder = tfdf.builder.RandomForestBuilder(
         model_format = tfdf.builder.ModelFormat.YGGDRASIL_DECISION_FOREST,
         path=self._temp_directory,
         objective = objective)
    
  2. After saving the model by closing the builder load the tree as CoreModel:

     builder.close()
    
     inspector_lib = tfdf.component.inspector.inspector
     inspector = inspector_lib.make_inspector(self._temp_directory, file_prefix=None)
    
     custom_tree = tfdf.keras.CoreModel(
         task=objective.task,
         learner='MANUAL',
         ranking_group=None,
         temp_directory=self._temp_directory)
    
     custom_tree._set_from_yggdrasil_model(
         inspector,
         self._temp_directory,
         file_prefix=None, 
         input_model_signature_fn=builder._input_model_signature_fn)
    
  3. Create a model subclass of tfdf.keras.CartModel with custom fit function that assigns the custom tree structure to the model:

    class CustomDT(tfdf.keras.CartModel):
        def __init__(self, name=None, **kwargs):
            super(CustomDT, self).__init__(name=name, **kwargs)
    
        def fit(self):
            custom_tree = self.create_custom_tree()
            self._model = custom_tree._model
            self._is_trained.assign(True)
            self._semantics = custom_tree._semantics
    
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文