Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
- Removed output layer L2 Penalty parameter from MLP Learners
- Remove Network interface
- RBX Serializer only tracks major library version number
- Convert NeuralNet classes to use NDArray instead of Matrix
- Turn back Network interface
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changelog entry "Turn back Network interface" is grammatically unclear. Consider rephrasing to something like "Restore Network interface" / "Bring back Network interface" so readers understand what changed.

Suggested change
- Turn back Network interface
- Restore Network interface

Copilot uses AI. Check for mistakes.

- 2.5.0
- Added Vantage Point Spatial tree
Expand Down
3 changes: 2 additions & 1 deletion src/Classifiers/LogisticRegression.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Rubix\ML\Classifiers;

use Rubix\ML\NeuralNet\FeedForward;
use Rubix\ML\Online;
use Rubix\ML\Learner;
use Rubix\ML\Verbose;
Expand Down Expand Up @@ -289,7 +290,7 @@

$classes = $dataset->possibleOutcomes();

$this->network = new Network(
$this->network = new FeedForward(
new Placeholder1D($dataset->numFeatures()),
[new Dense(1, $this->l2Penalty, true, new Xavier1())],
new Binary($classes, $this->costFn),
Expand Down Expand Up @@ -321,7 +322,7 @@
new DatasetIsNotEmpty($dataset),
new SamplesAreCompatibleWithEstimator($dataset, $this),
new LabelsAreCompatibleWithLearner($dataset, $this),
new DatasetHasDimensionality($dataset, $this->network->input()->width()),

Check failure on line 325 in src/Classifiers/LogisticRegression.php

View workflow job for this annotation

GitHub Actions / PHP 8.4 on ubuntu-latest

Call to an undefined method Rubix\ML\NeuralNet\Network::input().
])->check();

if ($this->logger) {
Expand Down
3 changes: 2 additions & 1 deletion src/Classifiers/MultilayerPerceptron.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Rubix\ML\Classifiers;

use Rubix\ML\NeuralNet\FeedForward;
use Rubix\ML\Online;
use Rubix\ML\Learner;
use Rubix\ML\Verbose;
Expand Down Expand Up @@ -370,7 +371,7 @@ public function train(Dataset $dataset) : void

$hiddenLayers[] = new Dense(count($classes), 0.0, true, new Xavier1());

$this->network = new Network(
$this->network = new FeedForward(
new Placeholder1D($dataset->numFeatures()),
$hiddenLayers,
new Multiclass($classes, $this->costFn),
Expand Down
3 changes: 2 additions & 1 deletion src/Classifiers/SoftmaxClassifier.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Rubix\ML\Classifiers;

use Rubix\ML\NeuralNet\FeedForward;
use Rubix\ML\Online;
use Rubix\ML\Learner;
use Rubix\ML\Verbose;
Expand Down Expand Up @@ -285,7 +286,7 @@ public function train(Dataset $dataset) : void

$classes = $dataset->possibleOutcomes();

$this->network = new Network(
$this->network = new FeedForward(
new Placeholder1D($dataset->numFeatures()),
[new Dense(count($classes), $this->l2Penalty, true, new Xavier1())],
new Multiclass($classes, $this->costFn),
Expand Down
188 changes: 188 additions & 0 deletions src/Datasets/Generators/SwissRoll/SwissRoll.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
<?php

namespace Rubix\ML\Datasets\Generators\SwissRoll;

use NDArray;
use NumPower;
use Rubix\ML\Datasets\Generators\Generator;
use Rubix\ML\Datasets\Labeled;
use Rubix\ML\Exceptions\InvalidArgumentException;

use function cos;
use function sin;
use function log;
use function sqrt;
use function mt_rand;

use const Rubix\ML\HALF_PI;

/**
* Swiss Roll
*
* Generate a 3-dimensional swiss roll dataset with continuous valued labels.
* The labels are the inputs to the swiss roll transformation and are suitable
* for non-linear regression problems.
*
* References:
* [1] S. Marsland. (2009). Machine Learning: An Algorithmic Perspective,
* Chapter 10.
*
* @category Machine Learning
* @package Rubix/ML
* @author Andrew DalPino
* @author Samuel Akopyan <leumas.a@gmail.com>
*/
class SwissRoll implements Generator
{
/**
* The center vector of the swiss roll.
*
* @var list<float>
*/
protected array $center;

/**
* The scaling factor of the swiss roll.
*
* @var float
*/
protected float $scale;

/**
* The depth of the swiss roll i.e the scale of the y dimension.
*
* @var float
*/
protected float $depth;

/**
* The standard deviation of the gaussian noise.
*
* @var float
*/
protected float $noise;

/**
* @param float $x
* @param float $y
* @param float $z
* @param float $scale
* @param float $depth
* @param float $noise
* @throws InvalidArgumentException
*/
public function __construct(
float $x = 0.0,
float $y = 0.0,
float $z = 0.0,
float $scale = 1.0,
float $depth = 21.0,
float $noise = 0.1
) {
if ($scale < 0.0) {
throw new InvalidArgumentException('Scale must be'
. " greater than 0, $scale given.");
}

if ($depth < 0) {
throw new InvalidArgumentException('Depth must be'
. " greater than 0, $depth given.");
}

if ($noise < 0.0) {
throw new InvalidArgumentException('Noise factor cannot be less'
. " than 0, $noise given.");
}

$this->center = [$x, $y, $z];
$this->scale = $scale;
$this->depth = $depth;
$this->noise = $noise;
}

/**
* Return the dimensionality of the data this generates.
*
* @internal
*
* @return int<0,max>
*/
public function dimensions() : int
{
return 3;
}

/**
* Generate n data points.
*
* @param int<0,max> $n
* @return Labeled
*/
public function generate(int $n) : Labeled
{
$range = M_PI + HALF_PI;

$t = [];
$y = [];
$coords = [];

for ($i = 0; $i < $n; ++$i) {
$u = mt_rand() / mt_getrandmax();
$ti = (($u * 2.0) + 1.0) * $range;
$t[] = $ti;

$uy = mt_rand() / mt_getrandmax();
$y[] = $uy * $this->depth;

$coords[] = [
$ti * cos($ti),
$y[$i],
$ti * sin($ti),
];
}

$noise = [];

if ($this->noise > 0.0) {
for ($i = 0; $i < $n; ++$i) {
$row = [];

for ($j = 0; $j < 3; ++$j) {
$u1 = mt_rand() / mt_getrandmax();
$u2 = mt_rand() / mt_getrandmax();
$u1 = $u1 > 0.0 ? $u1 : 1e-12;

$z0 = sqrt(-2.0 * log($u1)) * cos(2.0 * M_PI * $u2);

$row[] = $z0 * $this->noise;
}

$noise[] = $row;
}
} else {
for ($i = 0; $i < $n; ++$i) {
$noise[] = [0.0, 0.0, 0.0];
}
}

$center = [];

for ($i = 0; $i < $n; ++$i) {
$center[] = $this->center;
}

$coords = NumPower::array($coords);
$noise = NumPower::array($noise);
$center = NumPower::array($center);

$samples = NumPower::add(
NumPower::add(
NumPower::multiply($coords, $this->scale),
$center
),
$noise
);

return Labeled::quick($samples->toArray(), $t);
}
}
2 changes: 1 addition & 1 deletion src/NeuralNet/FeedForward.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
* @package Rubix/ML
* @author Andrew DalPino
*/
class FeedForward extends Network
class FeedForward implements Network
{
/**
* The input layer to the network.
Expand Down
Loading
Loading