anchor.diff:               '(1 2 2))
               (~ 0 9))))
       (train (make-network output)
  +           (list
  +            (α 'coerce
  +               (α (lambda (n i) (if (= n i) 1.0 0.0))
  +                  (reshape *train-labels* (τ (i) (i 0)))
  +                  #(0 1 2 3 4 5 6 7 8 9))
  +               'single-float))
              :learning-rate 0.02
  -           input (α #'/ *train-images* 255.0)
  -           output (α 'coerce
  -                     (α (lambda (n i) (if (= n i) 1.0 0.0))
  -                        (reshape *train-labels* (τ (i) (i 0)))
  -                        #(0 1 2 3 4 5 6 7 8 9))
  -                     'single-float))))
  +           input (α #'/ *train-images* 255.0))))
  
positive.code: ;;;
  ;;; Training
  
  (defun train (network &rest training-data-plist &key learning-rate &allow-other-keys)
    (let* ((outputs (network-outputs network))
           (parameters (network-parameters network))
           (trainable-parameters (remove-if-not #'trainable-parameter-p parameters))
           (gradient (differentiator outputs trainable-parameters))
           (training-network
             (apply #'make-network
                    (loop for trainable-parameter in trainable-parameters
  
negative.code:                            (α #'* learning-rate (funcall gradient trainable-parameter))))))
           (n nil))
      ;; Determine the training data size.
      (dolist (data output-training-data)
        (if (null n)
            (setf n (range-size (first (shape-ranges (shape data)))))
            (assert (= n (range-size (first (shape-ranges (shape data))))))))
      (alexandria:doplist (parameter data training-data-plist) ()
        (unless (symbolp parameter)
          (assert (= n (range-size (first (shape-ranges (shape data))))))))
      ;; Iterate over the training data.
      (loop for index below n do
        ;; Assemble the arguments.
        (let ((args '()))
          ;; Inputs.
          (alexandria:doplist (parameter data training-data-plist)
              (unless (symbolp parameter)
                (push parameter args)
                (push (nth-datum index data) args)))
          ;; Outputs.
          (loop for data in output-training-data
                for output-parameter in output-parameters do
                  (push output-parameter args)
                  (push (nth-datum index data) args))
          ;; Trainable parameters.
          (dolist (trainable-parameter trainable-parameters)
            (push trainable-parameter args)
            (push (trainable-parameter-value trainable-parameter) args))
          ;; Update all trainable parameters.
          (loop for trainable-parameter in trainable-parameters
                for value in (multiple-value-list
                              (apply #'call-network training-network (reverse args)))
                do (setf (trainable-parameter-value trainable-parameter)
                         value))))))
  
  (defun nth-datum (index data)
    (reshape
     data
     (make-shape
      (list*
       (range index)
       (rest (shape-ranges (shape data)))))
     (make-transformation
      :input-mask (list* index (make-list (1- (rank data))))
      :output-mask (alexandria:iota (1- (rank data)) :start 1))))
  
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  ;;;
  