input: Write a function to implement a logistic regression classifier in Python to classify handwritten digits from the MNIST dataset. The function should take in the training data, target labels, the maximum number of iterations for training, and the learning rate as inputs, and return the trained weights. It should also calculate and print the accuracy on the training, validation, and test sets.
  
  
  def LogisticRegression(X_train, y_train, max_iter, alpha, X_valid, y_valid, X_test, y_test):
      m, n = X_train.shape
      weights = np.zeros(n)
      
      for _ in range(max_iter):
          weights = weights - alpha * (1/m) * (X_train.T @ (sigmoid(X_train @ weights) - y_train))
  
      # accuracy on training set
      predictions = np.round(sigmoid(X_train @ weights))
      train_accuracy = np.mean(predictions == y_train)
      
      # accuracy on validation set
      predictions = np.round(sigmoid(X_valid @ weights))
      valid_accuracy = np.mean(predictions == y_valid)
      
      # accuracy on test set
      predictions = np.round(sigmoid(X_test @ weights))
      test_accuracy = np.mean(predictions == y_test)
      
      print('Train accuracy = ', train_accuracy)
      print('Validation accuracy = ', valid_accuracy)
      print('Test accuracy = ', test_accuracy)
      
      return weights
  
  # Example usage
  with gzip.open('./mnist_dataset/mnist.pkl.gz', 'rb') as f:
      train_data,valid_data,test_data  = pickle.load(f, encoding='latin1')
  
  X_train, y_train = train_data[0], train_data[1]
  X_valid, y_valid = valid_data[0], valid_data[1]
  X_test, y_test = test_data[0], test_data[1]
  
  X_train = np.hstack([np.ones([X_train.shape[0],1]), X_train])
  X_valid = np.hstack([np.ones([X_valid.shape[0],1]), X_valid])
  X_test = np.hstack([np.ones([X_test.shape[0],1]), X_test])
  
  weights = LogisticRegression(X_train, y_train, 1000, 0.001, X_valid, y_valid, X_test, y_test)
  
  
  assert LogisticRegression(X_train, y_train, 1000, 0.001, X_valid, y_valid, X_test, y_test) is not None
  assert 0.8 <= train_accuracy <= 1.0
  assert 0.8 <= valid_accuracy <= 1.0
  assert 0.8 <= test_accuracy <= 1.0
output: def LogisticRegression(X_train, y_train, max_iter, alpha, X_valid, y_valid, X_test, y_test):
      m, n = X_train.shape
      weights = np.zeros(n)
      
      for _ in range(max_iter):
          weights = weights - alpha * (1/m) * (X_train.T @ (sigmoid(X_train @ weights) - y_train))
  
      # accuracy on training set
      predictions = np.round(sigmoid(X_train @ weights))
      train_accuracy = np.mean(predictions == y_train)
      
      # accuracy on validation set
      predictions = np.round(sigmoid(X_valid @ weights))
      valid_accuracy = np.mean(predictions == y_valid)
      
      # accuracy on test set
      predictions = np.round(sigmoid(X_test @ weights))
      test_accuracy = np.mean(predictions == y_test)
      
      print('Train accuracy = ', train_accuracy)
      print('Validation accuracy = ', valid_accuracy)
      print('Test accuracy = ', test_accuracy)
      
      return weights