
neuroflow.playground.Sinusoidal.scala Maven / Gradle / Ivy
package neuroflow.playground
import neuroflow.application.plugin.Extensions._
import neuroflow.core.Activators.Double._
import neuroflow.core._
import neuroflow.dsl._
import neuroflow.nets.cpu.DenseNetwork._
import scala.annotation.tailrec
/**
* @author bogdanski
* @since 22.01.16
*/
object Sinusoidal {
/*
Here the goal is to predict the shape of sin(10*x).
The net will be trained with the exact function values drawn from the interval [0.0 : 0.8],
and the task is to continue (or predict) the next values from the interval ]0.8 : 4.0]
based solely on learned history. This is achieved through a time window and self-feeding traversal.
Feel free to read this article for the full story:
http://znctr.com/blog/time-series-prediction
*/
implicit val weights = WeightBreeder[Double].random(-0.2, 0.2)
def apply = {
val fn = Tanh
val group = 4
val sets = Settings[Double](learningRate = { case (_, _) => 1E-1 }, precision = 1E-9, iterations = 1000)
val net = Network(Vector(3) :: Dense(5, fn) :: Dense(3, fn) :: Dense(1, fn) :: SquaredError(), sets)
val sinusoidal = Range.Double(0.0, 0.8, 0.05).grouped(group).toVector.map(i => i.toVector.map(k => (k, Math.sin(10 * k))))
val xsys = sinusoidal.map(s => (s.dropRight(1).map(_._2), s.takeRight(1).map(_._2)))
val xs = xsys.map(_._1.denseVec)
val ys = xsys.map(_._2.denseVec)
net.train(xs, ys)
val initial = Range.Double(0.0, 0.15, 0.05).zipWithIndex.map(p => (p._1, xs.head(p._2))).toVector
val result = predict(net, xs.head.scalaVec, 0.15, initial)
result.foreach(r => println(s"${r._1}, ${r._2}"))
}
@tailrec def predict[T <: FFN[Double]](net: T, last: scala.Vector[Double], i: Double,
results: scala.Vector[(Double, Double)]): scala.Vector[(Double, Double)] = {
if (i < 4.0) {
val score = net(last.denseVec)(0)
predict(net, last.drop(1) :+ score, i + 0.05, results :+ (i, score))
} else results
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy