code: def softmax_loss_and_grad(W, X, y, reg):
      N, D = X.shape
      K = W.shape[1]
  
      y_obs = mt.zeros(shape=(N, K))
      for i in range(N):
          y_obs[i] = mt.eye(K)[y[i]]
  
      loss = -1 / N * mt.sum(
          y_obs
          * mt.log(
              mt.exp(X @ W)
              / mt.sum(mt.exp(X @ W), axis=1).reshape(-1, 1)
          )
      ) + 0.5 * reg * mt.sum(mt.square(W))
  
      dW = mt.zeros(shape=(D, K))
  
      # Matrix approach
      dW = (
          -1
          / N
          * X.T
          @ (
              y_obs
              - (
                  mt.exp(X @ W)
                  / mt.sum(mt.exp(X @ W), axis=1).reshape(-1, 1)
              )
          )
          + reg * W
      )
  
      execute(loss, dW)
  
      return loss, dW
  
imports: import math
  import numpy
  from ...None import execute
  from ...None import tensor
  from ...tensor.datasource import tensor
label_desc: Use image node_id 1 for calling a global function with example usage: softmax_loss_and_grad(W, X, y, reg) and returns: loss,  dW