public function back(Deferred $prevGradient, Optimizer $optimizer) : Deferred
    {
        if (!$this->beta or !$this->gamma) {
            throw new RuntimeException('Layer has not been initilaized.');
        }

        if (!$this->stdInv or !$this->xHat) {
            throw new RuntimeException('Must perform forward pass before'
                . ' backpropagating.');
        }

        $dOut = $prevGradient->result();

        $dBeta = $dOut->sum();
        $dGamma = $dOut->multiply($this->xHat)->sum();

        $gamma = $this->gamma->w();

        $optimizer->step($this->beta, $dBeta);
        $optimizer->step($this->gamma, $dGamma);

        $stdInv = $this->stdInv;
        $xHat = $this->xHat;

        unset($this->stdInv, $this->xHat);

        return new Deferred(function () use ($dOut, $gamma, $stdInv, $xHat) {
            $dXHat = $dOut->multiply($gamma);

            $xHatSigma = $dXHat->multiply($xHat)->sum();

            $dXHatSigma = $dXHat->sum();

            return $dXHat->multiply($dOut->m())
                ->subtract($dXHatSigma)
                ->subtract($xHat->multiply($xHatSigma))
                ->multiply($stdInv->divide($dOut->m()));
        });
    }