docstr: following code is copied from pytorch quick start
  link: https://pytorch.org/tutorials/beginner/basics/quickstart_tutorial.html
docstr_tok: ["following","code","is","copied","from","pytorch","quick","start","link",":","https",":","\/\/pytorch.org\/tutorials\/beginner\/basics\/quickstart_tutorial.html"]
code: def test_mnist(self) -> None:
      """
      following code is copied from pytorch quick start
      link: https://pytorch.org/tutorials/beginner/basics/quickstart_tutorial.html
      """
  
      training_data = datasets.FashionMNIST(
          root="data",
          train=True,
          download=True,
          transform=ToTensor(),
      )
  
      # Download test data from open datasets.
      test_data = datasets.FashionMNIST(
          root="data",
          train=False,
          download=True,
          transform=ToTensor(),
      )
      batch_size = 64
  
      # Create data loaders.
      train_dataloader = DataLoader(
          training_data, batch_size=batch_size
      )
      test_dataloader = DataLoader(test_data, batch_size=batch_size)
  
      for X, y in test_dataloader:
          print(f"Shape of X [N, C, H, W]: {X.shape}")
          print(f"Shape of y: {y.shape} {y.dtype}")
          break
  
      model = NeuralNetwork()
      set_one_like_parameter(model)
      loss_fn = nn.CrossEntropyLoss()
      optimizer = torch.optim.SGD(model.parameters(), lr=1e-3)
  
      # list for result validation
      pytorch_loss_list = []
  
      def train(dataloader, model, loss_fn, optimizer):
          size = len(dataloader.dataset)
          model.train()
          for batch, (X, y) in enumerate(dataloader):
              # Compute prediction error
              pred = model(X)
              loss = loss_fn(pred, y)
  
              # Backpropagation
              optimizer.zero_grad()
              loss.backward()
              optimizer.step()
  
              if batch % 100 == 0:
                  loss, current = loss.item(), batch * len(X)
                  pytorch_loss_list.append(np.array(loss))
                  print(f"loss: {loss:>7f}  [{current:>5d}/{size:>5d}]")
  
      train(train_dataloader, model, loss_fn, optimizer)
      init_fl_context(1, self.target)
      vfl_model_1 = NeuralNetworkPart1()
      set_one_like_parameter(vfl_model_1)
      vfl_model_2 = NeuralNetworkPart2()
      set_one_like_parameter(vfl_model_2)
      vfl_client_ppl = Estimator.from_torch(
          client_model=vfl_model_1,
          loss_fn=loss_fn,
          optimizer_cls=torch.optim.SGD,
          optimizer_args={"lr": 1e-3},
          server_model=vfl_model_2,
      )
      vfl_client_ppl.fit(train_dataloader)
      assert np.allclose(
          pytorch_loss_list, vfl_client_ppl.loss_history
      ), "Validation failed, correctness of PPML and native Pytorch not the same"
  
imports: from multiprocessing import Process
  from typing import List
  import unittest
  import numpy
  import pandas
  import os
  from bigdl.ppml.fl import *
  from bigdl.ppml.fl.nn.fl_server import FLServer
  from bigdl.ppml.fl.nn.fl_client import FLClient
  from bigdl.ppml.fl.nn.pytorch.utils import set_one_like_parameter
  from bigdl.ppml.fl.nn.fl_context import init_fl_context
  from bigdl.ppml.fl.estimator import Estimator
  from torch import Tensor, nn
  import torch
  from torch.utils.data import DataLoader
  from torchvision import datasets
  from torchvision.transforms import ToTensor
  from bigdl.ppml.fl.utils import FLTest
label_desc: Use image node_id 3 for calling the TestMnist obj's underlying member method code with example usage: obj.test_mnist() without return types