Skip to content

Instantly share code, notes, and snippets.

@freedom27
Last active June 8, 2016 18:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save freedom27/64d0762b796db54c44cecc232d627115 to your computer and use it in GitHub Desktop.
Save freedom27/64d0762b796db54c44cecc232d627115 to your computer and use it in GitHub Desktop.
//: Playground - noun: a place where people can play
import Foundation
protocol Neuron {
var weights: [Double] {get}
func feedforward(input: [Double]) -> Double
func activation(input: Double) -> Double
}
extension Neuron {
func feedforward(input: [Double]) -> Double {
return activation(zip(input, weights).reduce(0) { $0 + $1.0 * $1.1 })
}
}
protocol TrainableNeuron: Neuron {
var weights: [Double] {get set}
var learningConstant: Double { get }
mutating func train(input: [Double], desired: Double)
}
extension TrainableNeuron {
var learningConstant: Double { return 0.01 }
mutating func train(input: [Double], desired: Double) {
let result = feedforward(input)
let error = desired - result
weights = zip(weights, input).map{$0 + $1 * error * self.learningConstant}
}
}
class Perceptron: TrainableNeuron {
var weights: [Double]
init(inputsCount: Int) {
weights = (1...inputsCount).map{_ in Double(random() % 11)/10.0}
print(weights)
}
func activation(input: Double) -> Double {
return input > 0.0 ? 1.0 : -1.0
}
}
func f(x: Double) -> Double {
return 2.0*x + 1.0
}
func generatePoint() -> (Double, Double) {
let x = Double(random() % 640) * Double(random() % 2 == 0 ? 1 : -1)
let y = Double(random() % 480) * Double(random() % 2 == 0 ? 1 : -1)
return (x, y)
}
func generateTrainingSet(size: Int) -> [([Double], Double)] {
return (1...size).map{ _ in
let (x, y) = generatePoint()
let yLine = f(x)
return ([x, y, 1], y < yLine ? -1.0 : 1.0)
}
}
extension TrainableNeuron {
mutating func train(trainingSet: [([Double], Double)]) {
trainingSet.forEach{self.train($0.0, desired: $0.1)}
}
}
var n = Perceptron(inputsCount: 3)
let ts = generateTrainingSet(3000)
n.train(ts)
print(n.weights)
let points = (1...10).map{_ in generatePoint()}
for (x, y) in points {
let yLine = f(x)
let desired = y < yLine ? -1.0 : 1.0
let actual = n.feedforward([x, y, 1])
if desired == actual {
print("point(\(x), \(y)): success")
} else {
print("point(\(x), \(y)): fail")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment