class_docstr: Multi-layer Perceptron.
  
  The `_forward` method propagates input forward through the network and stores the outputs
  of each layer along the way. The `_backward` method then goes through each layer in reverse
  order and updates the weights within each layer.
docstr: Train the network.
  
  Parameters
  ----------
  X
      A DataFrame of shape (batch_size, n_features).
  y
      A DataFrame of shape (batch_size, n_targets).
docstr_tok: ["Train","the","network",".","Parameters","--","--","--","--","--","X","A","DataFrame","of","shape","(","batch_size",",","n_features",")",".","y","A","DataFrame","of","shape","(","batch_size",",","n_targets",")","."]
code: def learn_many(self, X: pd.DataFrame, y: pd.DataFrame):
      """Train the network.
  
      Parameters
      ----------
      X
          A DataFrame of shape (batch_size, n_features).
      y
          A DataFrame of shape (batch_size, n_targets).
  
      """
  
      # We expect y to be 2D, even if there is only one target to predict
      if isinstance(y, pd.Series):
          y = y.to_frame()
  
      # The weights need initializing during the first call to partial_fit
      if not hasattr(self, "w"):
          self.w, self.b = xavier_init(
              dims=(X.shape[1], *self.hidden_dims, y.shape[1]),
              seed=self.seed,
          )
          self.features = X.columns.to_numpy()
          self.features.sort()
          self.targets = y.columns.to_numpy()
  
      z, a = self._forward(X)
      self._backward(z, a, y)
  
imports: from __future__ import annotations
  import collections
  import copy
  import functools
  import numpy
  import pandas
  from river import base, optim
label_desc: Use image node_id 5 for calling the MLP obj's underlying member method code with example usage: obj.learn_many(X, y) without return types