2017-03-27 21:46:53 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
|
|
|
namespace Phpml\Helper\Optimizer;
|
|
|
|
|
2017-11-22 21:16:10 +00:00
|
|
|
use Closure;
|
|
|
|
use Exception;
|
|
|
|
|
2017-03-27 21:46:53 +00:00
|
|
|
abstract class Optimizer
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* Unknown variables to be found
|
|
|
|
*
|
|
|
|
* @var array
|
|
|
|
*/
|
2017-11-22 21:16:10 +00:00
|
|
|
protected $theta = [];
|
2017-03-27 21:46:53 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Number of dimensions
|
|
|
|
*
|
|
|
|
* @var int
|
|
|
|
*/
|
|
|
|
protected $dimensions;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Inits a new instance of Optimizer for the given number of dimensions
|
|
|
|
*/
|
|
|
|
public function __construct(int $dimensions)
|
|
|
|
{
|
|
|
|
$this->dimensions = $dimensions;
|
|
|
|
|
|
|
|
// Inits the weights randomly
|
|
|
|
$this->theta = [];
|
2017-05-17 07:03:25 +00:00
|
|
|
for ($i = 0; $i < $this->dimensions; ++$i) {
|
2017-11-22 21:16:10 +00:00
|
|
|
$this->theta[] = random_int(0, getrandmax()) / (float) getrandmax();
|
2017-03-27 21:46:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets the weights manually
|
|
|
|
*
|
2017-05-17 07:03:25 +00:00
|
|
|
* @return $this
|
|
|
|
*
|
|
|
|
* @throws \Exception
|
2017-03-27 21:46:53 +00:00
|
|
|
*/
|
|
|
|
public function setInitialTheta(array $theta)
|
|
|
|
{
|
|
|
|
if (count($theta) != $this->dimensions) {
|
2017-11-22 21:16:10 +00:00
|
|
|
throw new Exception("Number of values in the weights array should be $this->dimensions");
|
2017-03-27 21:46:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
$this->theta = $theta;
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Executes the optimization with the given samples & targets
|
|
|
|
* and returns the weights
|
|
|
|
*/
|
2017-11-22 21:16:10 +00:00
|
|
|
abstract public function runOptimization(array $samples, array $targets, Closure $gradientCb);
|
2017-03-27 21:46:53 +00:00
|
|
|
}
|