Skip to content

Instantly share code, notes, and snippets.

@jaume-ferrarons
Created October 1, 2021 12:28
Show Gist options
  • Save jaume-ferrarons/7d5c67575cad164b1d25ed9fc45ab8b2 to your computer and use it in GitHub Desktop.
Save jaume-ferrarons/7d5c67575cad164b1d25ed9fc45ab8b2 to your computer and use it in GitHub Desktop.
Extreme Learning Machine implementation
import numpy as np
import math
from pathlib import Path
import shutil
import json
class ELM:
def __init__(self, n_hidden_units: int) -> None:
self._n_hidden_units = n_hidden_units
self._weights_hidden = None
self._weights_output = None
self._batch_size = 50000
def fit(self, X, y):
self._weights_hidden = np.random.normal(size=[X.shape[1], self._n_hidden_units])
activations = self._activations(X)
activations_t = np.transpose(activations)
dot = np.dot(activations_t, activations)
try:
inv = np.linalg.inv(dot)
except np.linalg.LinAlgError as err:
if 'Singular matrix' in str(err):
inv = np.linalg.pinv(dot) # Approximate if exact does not exists
else:
raise
self._weights_output = np.dot(inv, np.dot(activations_t, y))
def predict(self, X):
res = np.zeros(len(X))
n_groups = math.ceil(len(X) / self._batch_size)
groups = np.array_split(range(len(X)), n_groups)
for indices in groups:
activations = self._activations(X.iloc[indices])
res[indices] += np.dot(activations, self._weights_output)
return res
def _activations(self, X):
a = np.dot(X, self._weights_hidden)
a = np.maximum(a, 0, a) # ReLU
return a
def save(self, path: str):
path = Path(path)
if path.exists():
shutil.rmtree(path)
path.mkdir()
with (path / "arrays.npy").open("wb") as f:
np.savez_compressed(f, hidden=self._weights_hidden, output=self._weights_output)
with (path / "info.json").open("w") as f:
json.dump(
{
"n_hidden_units": self._n_hidden_units
},
f,
indent=2,
)
@classmethod
def load(cls, path: str):
path = Path(path)
with (path / "info.json").open("r") as f:
data = json.load(f)
matrices = np.load(path / "arrays.npy")
res = ELM(data['n_hidden_units'])
res._weights_hidden = matrices['hidden']
res._weights_output = matrices['output']
return res
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment