code: def train(
      ctx: Context,
      role: Role,
      train_data: cpn.dataframe_input(roles=[GUEST, HOST]),
      validate_data: cpn.dataframe_input(
          roles=[GUEST, HOST], optional=True
      ),
      epochs: cpn.parameter(
          type=params.conint(gt=0), default=20, desc="max iteration num"
      ),
      batch_size: cpn.parameter(
          type=params.conint(ge=10),
          default=None,
          desc="batch size, None means full batch, otherwise should be no less than 10, default None",
      ),
      tol: cpn.parameter(type=params.confloat(ge=0), default=1e-4),
      early_stop: cpn.parameter(
          type=params.string_choice(["weight_diff", "diff", "abs"]),
          default="diff",
          desc="early stopping criterion, choose from {weight_diff, diff, abs}, if use weight_diff,"
          "weight will be revealed every epoch",
      ),
      learning_rate: cpn.parameter(
          type=params.confloat(ge=0), default=0.05, desc="learning rate"
      ),
      reveal_every_epoch: cpn.parameter(
          type=bool,
          default=False,
          desc="whether reveal encrypted result every epoch, "
          "only accept False for now",
      ),
      init_param: cpn.parameter(
          type=params.init_param(),
          default=params.InitParam(
              method="random_uniform",
              fit_intercept=True,
              random_state=None,
          ),
          desc="Model param init setting.",
      ),
      threshold: cpn.parameter(
          type=params.confloat(ge=0.0, le=1.0),
          default=0.5,
          desc="predict threshold for binary data",
      ),
      reveal_loss_freq: cpn.parameter(
          type=params.conint(ge=1),
          default=1,
          desc="rounds to reveal training loss, "
          "only effective if `early_stop` is 'loss'",
      ),
      train_output_data: cpn.dataframe_output(roles=[GUEST]),
      output_model: cpn.json_model_output(roles=[GUEST, HOST]),
      warm_start_model: cpn.json_model_input(
          roles=[GUEST, HOST], optional=True
      ),
  ):
      logger.info(f"enter sshe lr train")
      init_param = init_param.dict()
      ctx.mpc.init()
  
      train_model(
          ctx,
          role,
          train_data,
          validate_data,
          train_output_data,
          output_model,
          epochs,
          batch_size,
          learning_rate,
          tol,
          early_stop,
          init_param,
          reveal_every_epoch,
          reveal_loss_freq,
          threshold,
          warm_start_model,
      )
  
file_path: FATE/python/fate/components/components/sshe_lr.py
imports: import logging
  from fate.arch import Context
  from fate.arch.dataframe import DataFrame
  from fate.components.components.utils import consts, tools
  from fate.components.core import GUEST, HOST, Role, cpn, params
  from fate.ml.glm.hetero.sshe import SSHELogisticRegression
label_desc: Use image node_id 2 for calling a global function with example usage: train(ctx, role, train_data, validate_data, epochs, batch_size, tol, early_stop, learning_rate, reveal_every_epoch, init_param, threshold, reveal_loss_freq, train_output_data, output_model, warm_start_model) without return types