Created
January 7, 2012 17:46
-
-
Save jkdeveyra/1575440 to your computer and use it in GitHub Desktop.
Extreme Learning Machine Draft Implementation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import scala.Array.canBuildFrom | |
import scala.collection.mutable.ListBuffer | |
import scala.math.random | |
import scalala.library.LinearAlgebra.pinv | |
import scalala.tensor.dense.DenseMatrix | |
import scalala.tensor.dense.DenseVector | |
import scalala.tensor.mutable.Matrix | |
import scalala.tensor.mutable.Vector | |
import scalala.tensor.:: | |
class ELM(samples: Samples, hiddenNodes: Int, param: Param = new Param) { | |
val X = samples.inputMatrix | |
val N = samples.size | |
val L = hiddenNodes | |
val H = Matrix.zeros[Double](N, L) | |
val w = inputWeight | |
val T = samples.labelVector | |
var beta: DenseVector[Double] = null | |
// Step 1: Randomly assign input weight w and bias b | |
private var b: DenseVector[Float] = Vector((for (i <- 0 until L) yield (random.toFloat * 2 - 1)): _*) | |
def train() { | |
// Step 2: Calculate the hidden layer output matrix H | |
for (i <- 0 until N) | |
for (j <- 0 until L) | |
H(i, j) = param.activationFunc(w(j, ::) * X(i, ::).t + b(j)) // w.x + b | |
// Step 3: Calculate the output weight beta | |
beta = pinv(H) * T | |
} | |
def inputWeight: DenseMatrix[Double] = Matrix.rand(L, X.numCols) | |
def test(sample: Sample): Long = { | |
val node = for (i <- 0 until L) yield (beta(i) * param.activationFunc(w(i, ::) * sample.inputVector + b(i))) | |
node.sum.round | |
} | |
def bias = b | |
} | |
object ELM { | |
def Sigmoid(x: Double): Double = 1 / (1 + math.pow(math.E, -x)) | |
def transpose(matrix: Array[Array[Float]]): Array[Array[Float]] = | |
(for (i <- 0 until matrix(0).length) yield ((for (row <- matrix) yield row(i)).toArray)).toArray | |
} | |
class Param { | |
var activationFunc: Double => Double = ELM.Sigmoid | |
} | |
class Sample(len: Int) { | |
private var _attributes = new Array[Double](len) | |
private var _label: Int = 0 | |
def this(label: Label = Label(), attribs: List[Double]) = { | |
this(attribs.length) | |
_attributes = attribs.toArray | |
_label = label.i | |
} | |
def attributes = _attributes | |
def label = _label | |
def length = attributes.length | |
def inputVector = Vector(_attributes: _*) | |
} | |
object Sample { | |
def apply(attrib: Double*) = new Sample(Label(), attrib.toList) | |
def apply(label: Label, attrib: Double*) = new Sample(label, attrib.toList) | |
} | |
case class Label(i: Int = 0) | |
class Samples(samples: List[Sample]) { | |
private var _samples = new ListBuffer[Sample] | |
_samples ++= samples | |
def +=(sample: Sample) = _samples += sample | |
def size = _samples.size | |
def labelVector = Vector((for (sample <- _samples) yield sample.label.toDouble): _*) | |
def inputMatrix: DenseMatrix[Double] = { | |
val m = Matrix.zeros[Double](size, _samples(0).length) | |
for (i <- 0 until size) | |
m(i, ::) := Vector(_samples(i).attributes: _*) | |
m | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment