code: def vision_learner(
      dls,
      arch,
      normalize=True,
      n_out=None,
      pretrained=True,
      weights=None,
      # learner args
      loss_func=None,
      opt_func=Adam,
      lr=defaults.lr,
      splitter=None,
      cbs=None,
      metrics=None,
      path=None,
      model_dir="models",
      wd=None,
      wd_bn_bias=False,
      train_bn=True,
      moms=(0.95, 0.85, 0.95),
      # model & head args
      cut=None,
      init=nn.init.kaiming_normal_,
      custom_head=None,
      concat_pool=True,
      pool=True,
      lin_ftrs=None,
      ps=0.5,
      first_bn=True,
      bn_final=False,
      lin_first=False,
      y_range=None,
      **kwargs,
  ):
      "Build a vision learner from `dls` and `arch`"
      if n_out is None:
          n_out = get_c(dls)
      assert (
          n_out
      ), "`n_out` is not defined, and could not be inferred from data, set `dls.c` or pass `n_out`"
      meta = model_meta.get(arch, _default_meta)
      model_args = dict(
          init=init,
          custom_head=custom_head,
          concat_pool=concat_pool,
          pool=pool,
          lin_ftrs=lin_ftrs,
          ps=ps,
          first_bn=first_bn,
          bn_final=bn_final,
          lin_first=lin_first,
          y_range=y_range,
          **kwargs,
      )
      n_in = kwargs["n_in"] if "n_in" in kwargs else 3
      if isinstance(arch, str):
          model, cfg = create_timm_model(
              arch, n_out, default_split, pretrained, **model_args
          )
          if normalize:
              _timm_norm(dls, cfg, pretrained, n_in)
      else:
          if normalize:
              _add_norm(dls, meta, pretrained, n_in)
          model = create_vision_model(
              arch,
              n_out,
              pretrained=pretrained,
              weights=weights,
              **model_args,
          )
  
      splitter = ifnone(splitter, meta["split"])
      learn = Learner(
          dls=dls,
          model=model,
          loss_func=loss_func,
          opt_func=opt_func,
          lr=lr,
          splitter=splitter,
          cbs=cbs,
          metrics=metrics,
          path=path,
          model_dir=model_dir,
          wd=wd,
          wd_bn_bias=wd_bn_bias,
          train_bn=train_bn,
          moms=moms,
      )
      if pretrained:
          learn.freeze()
      # keep track of args for loggers
      store_attr(
          "arch,normalize,n_out,pretrained", self=learn, **kwargs
      )
      return learn
  
imports: from __future__ import annotations
  from packaging.version import parse
  from ..basics import *
  from .core import *
  from .data import *
  from .augment import *
  from .None import models
  import torchvision
  from ..callback.hook import num_features_model
label_desc: Use image node_id 21 for calling a global function with example usage: vision_learner(dls, arch, normalize, n_out, pretrained, weights, loss_func, opt_func, lr, splitter, cbs, metrics, path, model_dir, wd, wd_bn_bias, train_bn, moms, cut, init, custom_head, concat_pool, pool, lin_ftrs, ps, first_bn, bn_final, lin_first, y_range) and returns: learn