$valueA) { $c[] = static::maximum($valueA, $b[$i])->asArray(); } return Matrix::quick($c); } $bHat = $b->asArray(); $c = []; foreach ($a as $i => $valueA) { $c[] = (float) max($valueA, $bHat[$i]); } return Vector::quick($c); } /** * @param float $rate * @param float $momentumDecay * @param float $normDecay */ public function __construct(float $rate = 0.001, float $momentumDecay = 0.1, float $normDecay = 0.001) { if (ExtensionIsLoaded::with('tensor')->passes()) { ExtensionMinimumVersion::with('tensor', '3.0.0-beta')->check(); } parent::__construct($rate, $momentumDecay, $normDecay); } /** * Calculate a gradient descent step for a given parameter. * * @internal * * @param Parameter $param * @param Tensor $gradient * @return Tensor */ public function step(Parameter $param, Tensor $gradient) : Tensor { [$velocity, $norm] = $this->cache[$param->id()]; $vHat = $gradient->subtract($velocity) ->multiply($this->momentumDecay); $velocity = $velocity->add($vHat); $norm = $norm->multiply(1.0 - $this->normDecay); $norm = static::maximum($norm, $gradient->abs()); $this->cache[$param->id()] = [$velocity, $norm]; $norm = $norm->clipLower(EPSILON); return $velocity->divide($norm)->multiply($this->rate); } /** * Return the string representation of the object. * * @internal * * @return string */ public function __toString() : string { return "AdaMax (rate: {$this->rate}, momentum_decay: {$this->momentumDecay}," . " norm_decay: {$this->normDecay})"; } }