code: def forward(
      model: Model[InT, OutT], X: InT, is_train: bool
  ) -> Tuple[OutT, Callable]:
      normalize = model.attrs["softmax_normalize"] or is_train
  
      temperature = model.attrs["softmax_temperature"]
      validate_temperature(temperature)
  
      W = cast(Floats2d, model.get_param("W"))
      b = cast(Floats1d, model.get_param("b"))
      Y = model.ops.affine(X, W, b)
  
      if normalize:
          Y = model.ops.softmax(Y, temperature=temperature)
  
      array_info = ArrayInfo.from_array(Y)
  
      def backprop(dY: InT) -> OutT:
          array_info.check_consistency(dY)
          if temperature != 1.0:
              dY = dY / temperature
  
          model.inc_grad("b", dY.sum(axis=0))
          model.inc_grad("W", model.ops.gemm(dY, X, trans1=True))
          return model.ops.gemm(dY, W)
  
      def backprop_unnormalized(dY: InT):
          msg = "backprop is not supported for an unnormalized Softmax layer"
          raise ValueError(msg)
  
      if normalize:
          return Y, backprop
      else:
          return Y, backprop_unnormalized
  
file_path: thinc/thinc/layers/softmax.py
imports: from typing import Callable, Optional, Tuple, cast
  from ..config import registry
  from ..initializers import zero_init
  from ..model import Model
  from ..types import Floats1d, Floats2d
  from ..util import ArrayInfo, get_width, partial
label_desc: Use image node_id 3 for calling a global function with example usage: forward(model, X, is_train) and returns: model, Y,  backprop, Y,  backprop_unnormalized