code: def test_encoder_decoder_backwards_compatibility():
      old_config = {
          "input_features": [
              {
                  "name": "text_feature",
                  "type": "text",
                  "preprocessing": {
                      "missing_value_strategy": "drop_row",
                  },
                  "encoder": "rnn",
                  "bidirectional": True,
                  "representation": "dense",
                  "num_layers": 2,
              },
              {
                  "name": "image_feature_1",
                  "type": "image",
                  "preprocessing": {
                      "height": 7.5,
                      "width": 7.5,
                      "num_channels": 4,
                  },
                  "encoder": "resnet",
                  "num_channels": 4,
                  "dropout": 0.1,
                  "resnet_size": 100,
              },
              {
                  "name": "image_feature_2",
                  "type": "image",
                  "tied": "image_feature_1",
                  "preprocessing": {
                      "height": 7.5,
                      "width": 7.5,
                      "num_channels": 4,
                  },
                  "encoder": "resnet",
              },
          ],
          "output_features": [
              {
                  "name": "category_feature",
                  "type": "category",
                  "top_k": 3,
                  "preprocessing": {
                      "missing_value_strategy": BFILL,
                  },
                  "decoder": "classifier",
                  "num_classes": 10,
                  "use_bias": False,
              },
              {
                  "name": "binary_feature",
                  "type": "binary",
                  "dependencies": ["category_feature"],
                  "loss": {
                      "type": "cross_entropy",
                  },
                  "reduce_dependencies": "mean",
                  "decoder": "regressor",
                  "use_bias": True,
                  "bias_initializer": "constant",
              },
              {
                  "name": "vector_feature",
                  "type": "vector",
                  "decoder": "projector",
                  "num_fc_layers": 5,
                  "output_size": 128,
                  "activation": "tanh",
                  "dropout": 0.1,
              },
          ],
      }
  
      for feature in old_config[INPUT_FEATURES]:
          _upgrade_encoder_decoder_params(feature, True)
  
      for feature in old_config[OUTPUT_FEATURES]:
          _upgrade_encoder_decoder_params(feature, False)
  
      assert old_config == {
          "input_features": [
              {
                  "name": "text_feature",
                  "type": "text",
                  "preprocessing": {
                      "missing_value_strategy": "drop_row",
                  },
                  "encoder": {
                      "type": "rnn",
                      "bidirectional": True,
                      "representation": "dense",
                      "num_layers": 2,
                  },
              },
              {
                  "name": "image_feature_1",
                  "type": "image",
                  "preprocessing": {
                      "height": 7.5,
                      "width": 7.5,
                      "num_channels": 4,
                  },
                  "encoder": {
                      "type": "resnet",
                      "num_channels": 4,
                      "dropout": 0.1,
                      "resnet_size": 100,
                  },
              },
              {
                  "name": "image_feature_2",
                  "type": "image",
                  "tied": "image_feature_1",
                  "preprocessing": {
                      "height": 7.5,
                      "width": 7.5,
                      "num_channels": 4,
                  },
                  "encoder": {"type": "resnet"},
              },
          ],
          "output_features": [
              {
                  "name": "category_feature",
                  "type": "category",
                  "num_classes": 10,
                  "top_k": 3,
                  "preprocessing": {
                      "missing_value_strategy": BFILL,
                  },
                  "decoder": {
                      "type": "classifier",
                      "fc_use_bias": False,
                      "use_bias": False,
                  },
              },
              {
                  "name": "binary_feature",
                  "type": "binary",
                  "dependencies": ["category_feature"],
                  "loss": {
                      "type": "cross_entropy",
                  },
                  "reduce_dependencies": "mean",
                  "decoder": {
                      "type": "regressor",
                      "fc_use_bias": True,
                      "fc_bias_initializer": "constant",
                      "bias_initializer": "constant",
                      "use_bias": True,
                  },
              },
              {
                  "name": "vector_feature",
                  "type": "vector",
                  "decoder": {
                      "type": "projector",
                      "num_fc_layers": 5,
                      "fc_output_size": 128,
                      "fc_activation": "tanh",
                      "fc_dropout": 0.1,
                      "output_size": 128,
                      "activation": "tanh",
                      "dropout": 0.1,
                  },
              },
          ],
      }
  
imports: import copy
  import math
  from typing import Any, Dict
  import pytest
  from ludwig.constants import BATCH_SIZE, BFILL, CLASS_WEIGHTS, DEFAULTS, EVAL_BATCH_SIZE, EXECUTOR, HYPEROPT, INPUT_FEATURES, LEARNING_RATE_SCHEDULER, LOSS, NUMBER, OUTPUT_FEATURES, PREPROCESSING, SCHEDULER, SPLIT, TRAINER, TYPE
  from ludwig.schema.model_config import ModelConfig
  from ludwig.schema.trainer import ECDTrainerConfig
  from ludwig.utils.backward_compatibility import _update_backend_cache_credentials, _upgrade_encoder_decoder_params, _upgrade_feature, _upgrade_preprocessing_split, upgrade_config_dict_to_latest_version, upgrade_missing_value_strategy, upgrade_model_progress
  from ludwig.utils.trainer_utils import TrainerMetric
label_desc: Use image node_id 3 for calling a global function with example usage: test_encoder_decoder_backwards_compatibility() without return types