Skip to content

Instantly share code, notes, and snippets.

@koen-dejonghe
Created January 10, 2017 13:19
Show Gist options
  • Save koen-dejonghe/fb20a48ab42b826f8e4e1560c4254feb to your computer and use it in GitHub Desktop.
Save koen-dejonghe/fb20a48ab42b826f8e4e1560c4254feb to your computer and use it in GitHub Desktop.
package botkop.nn.lecture3
import scala.language.postfixOps
import scala.util.Random
object SigmoidIterativeLearning extends App {
case class LabeledData(numFish: Double, numChips: Double, numKetchup: Double, price: Double = 0.0)
case class Weights(fish: Double, chips: Double, ketchup: Double)
val trueWeights = Weights(0.150, 0.050, 0.100)
val initialWeights = Weights(0.05, 0.05, 0.05)
val trainingSet = generateData(100)
val learningRate = 0.3
val testSet = generateData(3)
val trainedWeights = train(trainingSet, initialWeights, 1000)
println(trueWeights)
println(trainedWeights)
evaluate(trainedWeights, testSet)
def generateData(size: Int): List[LabeledData] = {
for {
_ <- 1 to size
numFish = Random.nextDouble()
numChips = Random.nextDouble()
numKetchup = Random.nextDouble()
price = numFish * trueWeights.fish + numChips * trueWeights.chips + numKetchup * trueWeights.ketchup
} yield {
LabeledData(numFish, numChips, numKetchup, price)
}
} toList
def calculatePrice(data: LabeledData, weights: Weights): Double = {
data.numFish * weights.fish + data.numChips * weights.chips + data.numKetchup * weights.ketchup
}
def sigmoid(d: Double): Double = 1.0 / (1.0 + Math.exp(d))
def sigmoidDeltaWeights(currentWeights: Weights, trainingCase: LabeledData): Weights = {
val t = sigmoid(trainingCase.price)
val z = calculatePrice(trainingCase, currentWeights)
val y = sigmoid(z)
val slope = y * (1.0 - y)
val deltaFish = learningRate * trainingCase.numFish * slope * (t - y)
val deltaChips = learningRate * trainingCase.numChips * slope * (t - y)
val deltaKetchup = learningRate * trainingCase.numKetchup * slope * (t - y)
Weights(deltaFish, deltaChips, deltaKetchup)
}
def train(trainingSet: List[LabeledData],
currentWeights: Weights,
numIterations: Int): Weights = numIterations match {
case 0 => currentWeights
case _ =>
val listOfDeltas = for (trainingCase <- trainingSet)
yield sigmoidDeltaWeights(currentWeights, trainingCase)
val batchDelta = listOfDeltas.foldLeft(Weights(0.0, 0.0, 0.0)){ (sumDelta, delta) =>
Weights(sumDelta.fish + delta.fish, sumDelta.chips + delta.chips, sumDelta.ketchup + delta.ketchup)
}
val newWeights = Weights(currentWeights.fish - batchDelta.fish,
currentWeights.chips - batchDelta.chips,
currentWeights.ketchup - batchDelta.ketchup)
train(trainingSet, newWeights, numIterations - 1)
}
def evaluate(weights: Weights, testSet: List[LabeledData]): Unit = {
for (testCase <- testSet) {
val y = calculatePrice(testCase, weights)
val t = testCase.price
println(s"truth: $t predicted: $y")
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment