forked from swiftlang/swift
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsimple_model.swift
More file actions
57 lines (46 loc) · 1.41 KB
/
Copy pathsimple_model.swift
File metadata and controls
57 lines (46 loc) · 1.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
// RUN: %target-run-simple-swift
// REQUIRES: executable_test
import StdlibUnittest
var SimpleModelTests = TestSuite("SimpleModel")
struct DenseLayer : Equatable {
let w: Float
let b: Float
}
extension DenseLayer {
func prediction(for input: Float) -> Float {
return input * w + b
}
}
struct Model : Equatable {
let l1: DenseLayer
let l2: DenseLayer
let l3: DenseLayer
}
extension Model {
func prediction(for input: Float) -> Float {
// This "model" is silly because it doesn't have nonlinearities. But it's
// simple and good enough for testing purposes.
let activation1 = l1.prediction(for: input)
let activation2 = l2.prediction(for: activation1)
return l3.prediction(for: activation2)
}
func loss(for input: Float, withLabel label: Float) -> Float {
let p = prediction(for: input)
return (p - label) * (p - label)
}
}
SimpleModelTests.test("gradient") {
let layer = DenseLayer(w: 1.0, b: 0.0)
let model = Model(l1: layer, l2: layer, l3: layer)
let input: Float = 1
let label: Float = 3
func loss(_ m: Model, _ i: Float, _ l: Float) -> Float {
return m.loss(for: i, withLabel: l)
}
let grad = #gradient(loss, wrt: .0)(model, input, label)
let expectedGrad = Model(l1: DenseLayer(w: -4, b: -4),
l2: DenseLayer(w: -4, b: -4),
l3: DenseLayer(w: -4, b: -4))
expectEqual(expectedGrad, grad)
}
runAllTests()