Skip to content

Instantly share code, notes, and snippets.

@regexident
Created May 31, 2018 14:38
Show Gist options
  • Save regexident/ab315d066bf6091fbda14a5d40d86fd6 to your computer and use it in GitHub Desktop.
Save regexident/ab315d066bf6091fbda14a5d40d86fd6 to your computer and use it in GitHub Desktop.

Revisions

  1. regexident created this gist May 31, 2018.
    101 changes: 101 additions & 0 deletions Perceptron.swift
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,101 @@
    //: Playground - noun: a place where people can play

    import Cocoa

    struct Vector {
    let x: Float
    let y: Float
    let z: Float

    static func *(lhs: Vector, rhs: Float) -> Vector {
    return Vector(x: lhs.x * rhs, y: lhs.y * rhs, z: lhs.z * rhs)
    }

    static func +(lhs: Vector, rhs: Vector) -> Vector {
    return Vector(x: lhs.x + rhs.x, y: lhs.y + rhs.y, z: lhs.z + rhs.z)
    }

    static func -(lhs: Vector, rhs: Vector) -> Vector {
    return Vector(x: lhs.x - rhs.x, y: lhs.y - rhs.y, z: lhs.z - rhs.z)
    }

    func dot(_ other: Vector) -> Float {
    return (self.x * other.x) + (self.y * other.y) + (self.z * other.z)
    }
    }

    struct Perceptron {

    var weights: Vector = Vector(x: 1.0, y: 1.0, z: 1.0)
    var bias: Float = 1.0

    func activation(_ example: Vector) -> Float {
    return weights.dot(example) - bias
    }

    func predict(_ example: Vector) -> Float {
    let activation = self.activation(example)
    return (activation >= 0) ? 1.0 : 0.0
    }

    mutating func error(example: Vector, expected: Float) -> Float {
    let predicted: Float = self.predict(example)
    return (expected - predicted)
    }

    mutating func learn(example: Vector, expected: Float, learningRate: Float) {
    let error: Float = self.error(example: example, expected: expected)
    let scaleFactor: Float = error * learningRate
    self.weights = weights + (example * scaleFactor)
    self.bias = bias + (bias * scaleFactor)
    }
    }

    let magenta = Vector(x: 1.0, y: 0.0, z: 1.0)
    let red = Vector(x: 1.0, y: 0.0, z: 0.0)
    let green = Vector(x: 0.0, y: 1.0, z: 0.0)
    let blue = Vector(x: 0.0, y: 0.0, z: 1.0)
    let yellow = Vector(x: 1.0, y: 1.0, z: 0.0)
    let cyan = Vector(x: 0.0, y: 1.0, z: 1.0)

    var perceptron = Perceptron()

    let examples: [(Vector, Bool)] = [
    (magenta, true),
    (red, false),
    (magenta, true),
    (green, false),
    (magenta, true),
    (blue, false),
    (magenta, true),
    (yellow, false),
    (magenta, true),
    (cyan, false),
    ]

    let maxLearningRate: Float = 0.1

    print()
    print("Before training:")
    dump(perceptron)

    let maxEpochs = 10_000
    for epoch in 0..<maxEpochs {
    let learningRate = maxLearningRate * (Float(maxEpochs - epoch) / Float(maxEpochs))
    for (example, isPositive) in examples {
    let expected: Float = (isPositive) ? 1.0 : 0.0
    perceptron.learn(example: example, expected: expected, learningRate: learningRate)
    }
    }

    print()
    print("After training:")
    dump(perceptron)

    print()
    print("Magenta is magenta:", perceptron.predict(magenta))
    print("Red is magenta:", perceptron.predict(red))
    print("Green is magenta:", perceptron.predict(green))
    print("Blue is magenta:", perceptron.predict(blue))
    print("Yellow is magenta:", perceptron.predict(yellow))
    print("Cyan is magenta:", perceptron.predict(cyan))