Kedro - как передать вложенные параметры непосредственно в узел - PullRequest
2 голосов
/ 27 апреля 2020

kedro рекомендует сохранять параметры в conf/base/parameters.yml. Давайте предположим, что это выглядит так:

step_size: 1
model_params:
    learning_rate: 0.01
    test_data_ratio: 0.2
    num_train_steps: 10000

А теперь представьте, что у меня есть какой-то data_engineering конвейер, у которого nodes.py есть функция, которая выглядит примерно так:

def some_pipeline_step(num_train_steps):
    """
    Takes the parameter `num_train_steps` as argument.
    """
    pass

Как бы Я go о и передать эти вложенные параметры прямо в эту функцию в data_engineering/pipeline.py? Я безуспешно пытался:

from kedro.pipeline import Pipeline, node

from .nodes import split_data


def create_pipeline(**kwargs):
    return Pipeline(
        [
            node(
                some_pipeline_step,
                ["params:model_params.num_train_steps"],
                dict(
                    train_x="train_x",
                    train_y="train_y",
                ),
            )
        ]
    )

Я знаю, что я мог бы просто передать все параметры в функцию, используя ['parameters'], или просто передать все model_params параметры с помощью ['params:model_params'], но это кажется не элегантным, и я чувствую, что должен быть способ. Был бы признателен за любой вклад!

1 Ответ

1 голос
/ 27 апреля 2020

(Отказ от ответственности: я являюсь частью команды Kedro)

Спасибо за ваш вопрос. Текущая версия Kedro, к сожалению, не поддерживает вложенные параметры. Временным решением было бы использовать ключи верхнего уровня внутри узла (как вы уже указали) или украсить функцию узла каким-либо фильтром параметров, что тоже не элегантно.

Возможно, наиболее жизнеспособный Решением было бы настроить класс ProjectContextsrc/<package_name>/run.py), переписав метод _get_feed_dict следующим образом:

class ProjectContext(KedroContext):
    # ...


    def _get_feed_dict(self) -> Dict[str, Any]:
        """Get parameters and return the feed dictionary."""
        params = self.params
        feed_dict = {"parameters": params}

        def _add_param_to_feed_dict(param_name, param_value):
            """This recursively adds parameter paths to the `feed_dict`,
            whenever `param_value` is a dictionary itself, so that users can
            specify specific nested parameters in their node inputs.

            Example:

                >>> param_name = "a"
                >>> param_value = {"b": 1}
                >>> _add_param_to_feed_dict(param_name, param_value)
                >>> assert feed_dict["params:a"] == {"b": 1}
                >>> assert feed_dict["params:a.b"] == 1
            """
            key = "params:{}".format(param_name)
            feed_dict[key] = param_value

            if isinstance(param_value, dict):
                for key, val in param_value.items():
                    _add_param_to_feed_dict("{}.{}".format(param_name, key), val)

        for param_name, param_value in params.items():
            _add_param_to_feed_dict(param_name, param_value)

        return feed_dict

Обратите также внимание, что эта проблема уже была решена при разработке и станет доступным в следующем выпуске. Исправление использует подход из фрагмента выше.

...