Примеры кода на Scala — различия между версиями
(→Примеры кода) |
(→Классификация при помощи RNN) |
||
| Строка 101: | Строка 101: | ||
val mlpModel = mlp(x, y, Array(2, 10, 2), ErrorFunction.LEAST_MEAN_SQUARES, ActivationFunction.LOGISTIC_SIGMOID) | val mlpModel = mlp(x, y, Array(2, 10, 2), ErrorFunction.LEAST_MEAN_SQUARES, ActivationFunction.LOGISTIC_SIGMOID) | ||
plot(x, y, mlpModel) | plot(x, y, mlpModel) | ||
| − | === | + | ===Рекуррентная нейронная сеть=== |
| + | Пример кода, с использованием билиотеки DeepLearning.scala | ||
| + | // Задание слоёв | ||
| + | def tanh(x: INDArrayLayer): INDArrayLayer = { | ||
| + | val exp_x = hyperparameters.exp(x) | ||
| + | val exp_nx = hyperparameters.exp(-x) | ||
| + | (exp_x - exp_nx) / (exp_x + exp_nx) | ||
| + | } | ||
| + | def charRNN(x: INDArray, y: INDArray, hprev: INDArrayLayer): (DoubleLayer, INDArrayLayer, INDArrayLayer) = { | ||
| + | val hnext = tanh(wxh.dot(x) + whh.dot(hprev) + bh) | ||
| + | val yraw = why.dot(hnext) + by | ||
| + | val yraw_exp = hyperparameters.exp(yraw) | ||
| + | val prob = yraw_exp / yraw_exp.sum | ||
| + | val loss = -hyperparameters.log((prob * y).sum) | ||
| + | (loss, prob, hnext) | ||
| + | } | ||
| + | |||
| + | // Определение структуры | ||
| + | val batches = data.zip(data.tail).grouped(seqLength).toVector | ||
| + | type WithHiddenLayer[A] = (A, INDArrayLayer) | ||
| + | type Batch = IndexedSeq[(Char, Char)] | ||
| + | type Losses = Vector[Double] | ||
| + | def singleBatch(batch: WithHiddenLayer[Batch]): WithHiddenLayer[DoubleLayer] = { | ||
| + | batch match { | ||
| + | case (batchseq, hprev) => batchseq.foldLeft((DoubleLayer(0.0.forward), hprev)) { | ||
| + | (bstate: WithHiddenLayer[DoubleLayer], xy: (Char, Char)) => | ||
| + | (bstate, xy) match { | ||
| + | case ((tot, localhprev), (x, y)) => { | ||
| + | charRNN(oneOfK(x), oneOfK(y), localhprev) match { | ||
| + | case (localloss, _, localhnext) => { | ||
| + | (tot + localloss, localhnext) | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | |||
| + | // Определение одного шага обучения | ||
| + | def initH = INDArrayLayer(Nd4j.zeros(hiddenSize, 1).forward) | ||
| + | def singleRound(initprevloss: Losses): Future[Losses] = | ||
| + | (batches.foldLeftM((initprevloss, initH)) { | ||
| + | (bstate: WithHiddenLayer[Losses], batch: Batch) => | ||
| + | bstate match { | ||
| + | case (prevloss, hprev) => singleBatch(batch, hprev) match { | ||
| + | case (bloss, hnext) => bloss.train.map { | ||
| + | (blossval: Double) => { | ||
| + | val nloss = prevloss.last * 0.999 + blossval * 0.001 | ||
| + | val loss_seq = prevloss :+ prevloss.last * 0.999 + blossval * 0.001 | ||
| + | (loss_seq, hnext) | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | }).map { | ||
| + | (fstate: WithHiddenLayer[Losses]) => | ||
| + | fstate match { | ||
| + | case (floss, _) => floss | ||
| + | } | ||
| + | } | ||
| + | def allRounds: Future[Losses] = (0 until 2048).foldLeftM(Vector(-math.log(1.0 / vocabSize) * seqLength)) { | ||
| + | (ploss: Losses, round: Int) => { | ||
| + | singleRound(ploss) | ||
| + | } | ||
| + | } | ||
| + | |||
| + | // Обучение сети | ||
| + | def unsafePerformFuture[A](f: Future[A]): A = Await.result(f.toScalaFuture, Duration.Inf) | ||
| + | val losses = unsafePerformFuture(allRounds) | ||
== Примечания == | == Примечания == | ||
<references/> | <references/> | ||
Версия 20:51, 17 января 2019
Содержание
Популярные библиотеки
- Breeze[1] — библиотека, которая копирует реализует идеи строения структур данных из MATLAB[2] и NumPy[3]. Breeze позволяет быстро манипулировть данными и позволяет реализовавать матричные и веторные операции, решать задачи оптимизации, обрабатывать сигналы устройств.
- Epic[4] — часть ScalaNLP, позволяющая парсить и обрабатывать текст, поддерживающая использование GPU. Так же имеет фрэймворк для предсказаний текста.
- Smpile[5] — развивающийся проект, похожий на scikit-learn[6], разработанный на Java и имеющий API для Scala. Имеет большой набор алгоритмов для решения задач классификации, регрессии, выбора фичей и другого.
- Apache Spark MLlib[7] — построенная на Spark[8] имеет большой набор алгоритмов, написанный на Scala.
- DeepLearning.scala [9] — набор инструментов для глубокого обучения[10]. Позволяет создавать динамические нейронные сети, давая возможность параллельных вычеслений.
Примеры кода
KNN
SBT зависимость:
libraryDependencies += "com.github.haifengl" %% "smile-scala" % "1.5.2"
Пример классификации датасета и вычисления F1 меры[11] используя smile.classification.knn[12]:
import smile.classification._ import smile.data._ import smile.plot._ import smile.read import smile.validation.FMeasure
val toy: AttributeDataset = read.table("iris.csv", delimiter = ",", response = Some((new NumericAttribute("class"), 2)))
val x: Array[Array[Double]] = toy.x()
val y: Array[Int] = toy.y().map(_.toInt)
val KNN: KNN[Array[Double]] = knn(x, y, 3)
val predictions: Array[Int] = x.map(KNN.predict)
val f1Score = new FMeasure().measure(predictions, y)
plot(x, y, KNN)
Линейная регрессия
Sbt зависимость:
libraryDependencies += "org.apache.spark" %% "spark-core" % "2.4.0" libraryDependencies += "org.apache.spark" %% "spark-mllib" % "2.4.0" % "runtime"
Пример линейной регрессии c применением org.apache.spark.ml.regression.LinearRegression[13]:
val training = spark.read.format("libsvm")
.load("linear_regression.txt")
val lr = new LinearRegression()
.setMaxIter(10)
.setRegParam(0.3)
.setElasticNetParam(0.8)
val lrModel = lr.fit(training)
Вывод итоговых параметров модели:
println(lrModel.coefficients)
println(lrModel.intercept)
val trainingSummary = lrModel.summary
println(trainingSummary.totalIterations)
println(trainingSummary.objectiveHistory.mkString(","))
trainingSummary.residuals.show()
println(trainingSummary.rootMeanSquaredError)
println(trainingSummary.r2)
Вариации регрессии
Sbt зависимость:
libraryDependencies += "com.github.haifengl" %% "smile-scala" % "1.5.2"
Пример ридж и лассо регрессии c применением smile.regression[14]:
import smile.data.{AttributeDataset, NumericAttribute}
import smile.read
import smile.regression.{LASSO, RidgeRegression, lasso, ridge}
val data: AttributeDataset = read.table("regression.txt", delimiter = " ", response = Some((new NumericAttribute("class"), 0)))
val x: Array[Array[Double]] = data.x()
val y: Array[Double] = data.y()
val ridgeRegression: RidgeRegression = ridge(x, y, 0.0057)
val lassoRegression: LASSO = lasso(x, y, 10)
println(ridgeRegression)
println(lassoRegression)
Логистическая регрессия
Sbt зависимость:
libraryDependencies += "org.apache.spark" %% "spark-core" % "2.4.0" libraryDependencies += "org.apache.spark" %% "spark-mllib" % "2.4.0" % "runtime"
Пример логистической регрессии c применением spark.mllib.classification[15]:
import org.apache.spark.mllib.classification.{LogisticRegressionModel, LogisticRegressionWithLBFGS}
import org.apache.spark.mllib.evaluation.MulticlassMetrics
import org.apache.spark.mllib.regression.LabeledPoint
import org.apache.spark.mllib.util.MLUtils
val data = MLUtils.loadLibSVMFile(sc, "logisticRegresion.txt") val splits = data.randomSplit(Array(0.6, 0.4), seed = 11L) val training = splits(0).cache() val test = splits(1) val model = new LogisticRegressionWithLBFGS() .setNumClasses(10) .run(training)
val predictionAndLabels = test.map { case LabeledPoint(label, features) =>
val prediction = model.predict(features)
(prediction, label)
}
val metrics = new MulticlassMetrics(predictionAndLabels)
val accuracy = metrics.accuracy
println(accuracy)
Классификация при помощи MLP
Sbt зависимость:
libraryDependencies += "com.github.haifengl" %% "smile-scala" % "1.5.2"
Пример классификации c применением smile.classification.mlp[16]:
import smile.classification.NeuralNetwork.{ActivationFunction, ErrorFunction}
import smile.data.{AttributeDataset, NumericAttribute}
import smile.read
import smile.classification.mlp
import smile.plot.plot
val data: AttributeDataset = read.table("iris.csv", delimiter = ",", response = Some((new NumericAttribute("class"), 2)))
val x: Array[Array[Double]] = data.x()
val y: Array[Int] = data.y().map(_.toInt)
val mlpModel = mlp(x, y, Array(2, 10, 2), ErrorFunction.LEAST_MEAN_SQUARES, ActivationFunction.LOGISTIC_SIGMOID)
plot(x, y, mlpModel)
Рекуррентная нейронная сеть
Пример кода, с использованием билиотеки DeepLearning.scala
// Задание слоёв
def tanh(x: INDArrayLayer): INDArrayLayer = {
val exp_x = hyperparameters.exp(x)
val exp_nx = hyperparameters.exp(-x)
(exp_x - exp_nx) / (exp_x + exp_nx)
}
def charRNN(x: INDArray, y: INDArray, hprev: INDArrayLayer): (DoubleLayer, INDArrayLayer, INDArrayLayer) = {
val hnext = tanh(wxh.dot(x) + whh.dot(hprev) + bh)
val yraw = why.dot(hnext) + by
val yraw_exp = hyperparameters.exp(yraw)
val prob = yraw_exp / yraw_exp.sum
val loss = -hyperparameters.log((prob * y).sum)
(loss, prob, hnext)
}
// Определение структуры
val batches = data.zip(data.tail).grouped(seqLength).toVector
type WithHiddenLayer[A] = (A, INDArrayLayer)
type Batch = IndexedSeq[(Char, Char)]
type Losses = Vector[Double]
def singleBatch(batch: WithHiddenLayer[Batch]): WithHiddenLayer[DoubleLayer] = {
batch match {
case (batchseq, hprev) => batchseq.foldLeft((DoubleLayer(0.0.forward), hprev)) {
(bstate: WithHiddenLayer[DoubleLayer], xy: (Char, Char)) =>
(bstate, xy) match {
case ((tot, localhprev), (x, y)) => {
charRNN(oneOfK(x), oneOfK(y), localhprev) match {
case (localloss, _, localhnext) => {
(tot + localloss, localhnext)
}
}
}
}
}
}
}
// Определение одного шага обучения
def initH = INDArrayLayer(Nd4j.zeros(hiddenSize, 1).forward)
def singleRound(initprevloss: Losses): Future[Losses] =
(batches.foldLeftM((initprevloss, initH)) {
(bstate: WithHiddenLayer[Losses], batch: Batch) =>
bstate match {
case (prevloss, hprev) => singleBatch(batch, hprev) match {
case (bloss, hnext) => bloss.train.map {
(blossval: Double) => {
val nloss = prevloss.last * 0.999 + blossval * 0.001
val loss_seq = prevloss :+ prevloss.last * 0.999 + blossval * 0.001
(loss_seq, hnext)
}
}
}
}
}).map {
(fstate: WithHiddenLayer[Losses]) =>
fstate match {
case (floss, _) => floss
}
}
def allRounds: Future[Losses] = (0 until 2048).foldLeftM(Vector(-math.log(1.0 / vocabSize) * seqLength)) {
(ploss: Losses, round: Int) => {
singleRound(ploss)
}
}
// Обучение сети def unsafePerformFuture[A](f: Future[A]): A = Await.result(f.toScalaFuture, Duration.Inf) val losses = unsafePerformFuture(allRounds)
Примечания
- ↑ Breeze
- ↑ MATLAB, structures
- ↑ NumPy wiki
- ↑ ScalaNLP, Epic
- ↑ Smile, Statistical Machine Intelligence and Learning Engine
- ↑ scikit-learn
- ↑ Apache Spark MLlib
- ↑ Apache Spark
- ↑ DeppLearning.scala
- ↑ Глубокое обучение
- ↑ F1 мера
- ↑ Smile, KNN
- ↑ Spark, LinearRegression
- ↑ Smile, Regression
- ↑ Spark, Logistic Regression
- ↑ Smile, MLP