@@ -23,30 +23,6 @@ import Foundation
23
23
24
24
// MARK: Randomization & Statistical Helpers
25
25
26
- struct Random {
27
- private static var seeded = false
28
-
29
- // a random Double between *from* and *to*, assumes *from* < *to*
30
- static func double( from: Double , to: Double ) -> Double {
31
- if !Random. seeded {
32
- srand48 ( time ( nil ) )
33
- Random . seeded = true
34
- }
35
-
36
- return ( drand48 ( ) * ( to - from) ) + from
37
- }
38
- }
39
-
40
- /// Create *number* of random Doubles between 0.0 and 1.0
41
- func randomWeights( number: Int ) -> [ Double ] {
42
- return ( 0 ..< number) . map { _ in Random . double ( from: 0.0 , to: 1.0 ) }
43
- }
44
-
45
- /// Create *number* of random Doubles between 0.0 and *limit*
46
- func randomNums( number: Int , limit: Double ) -> [ Double ] {
47
- return ( 0 ..< number) . map { _ in Random . double ( from: 0.0 , to: limit) }
48
- }
49
-
50
26
// A derivative of the Fisher-Yates algorithm to shuffle an array
51
27
extension Array {
52
28
public func shuffled( ) -> Array < Element > {
@@ -62,19 +38,25 @@ extension Array {
62
38
}
63
39
}
64
40
65
- /// assumes all rows are of equal length
66
- /// and divide each column by its max throughout the data set
67
- /// for that column
68
- func normalizeByColumnMax( dataset: inout [ [ Double ] ] ) {
69
- for colNum in 0 ..< dataset [ 0 ] . count {
70
- let column = dataset. map { 0ドル [ colNum] }
71
- let maximum = column. max ( ) !
72
- for rowNum in 0 ..< dataset. count {
73
- dataset [ rowNum] [ colNum] = dataset [ rowNum] [ colNum] / maximum
41
+ struct Random {
42
+ private static var seeded = false
43
+
44
+ // a random Double between *from* and *to*, assumes *from* < *to*
45
+ static func double( from: Double , to: Double ) -> Double {
46
+ if !Random. seeded {
47
+ srand48 ( time ( nil ) )
48
+ Random . seeded = true
74
49
}
50
+
51
+ return ( drand48 ( ) * ( to - from) ) + from
75
52
}
76
53
}
77
54
55
+ /// Create *number* of random Doubles between 0.0 and 1.0
56
+ func randomWeights( number: Int ) -> [ Double ] {
57
+ return ( 0 ..< number) . map { _ in Random . double ( from: 0.0 , to: 1.0 ) }
58
+ }
59
+
78
60
// MARK: Activation Functions and Their Derivatives
79
61
80
62
/// the classic sigmoid activation function
@@ -128,8 +110,6 @@ public func sum(x: [Double]) -> Double {
128
110
return result
129
111
}
130
112
131
-
132
-
133
113
/// An individual node in a layer
134
114
class Neuron {
135
115
var weights : [ Double ]
@@ -289,63 +269,22 @@ class Network {
289
269
}
290
270
}
291
271
292
- /// Wine Test
272
+ /// MARK: Normalization
293
273
294
- //var network: Network = Network(layerStructure: [13,7,3], learningRate: 7.0)
295
- //// for training
296
- //var wineParameters: [[Double]] = [[Double]]()
297
- //var wineClassifications: [[Double]] = [[Double]]()
298
- //// for testing/validation
299
- //var wineSamples: [[Double]] = [[Double]]()
300
- //var wineCultivars: [Int] = [Int]()
301
- //
302
- //func parseWineCSV() {
303
- // let myBundle = Bundle.main
304
- // let urlpath = myBundle.path(forResource: "wine", ofType: "csv")
305
- // let url = URL(fileURLWithPath: urlpath!)
306
- // let csv = try! String.init(contentsOf: url)
307
- // let lines = csv.components(separatedBy: "\n")
308
- //
309
- // let shuffledLines = lines.shuffled()
310
- // for line in shuffledLines {
311
- // if line == "" { continue }
312
- // let items = line.components(separatedBy: ",")
313
- // let parameters = items[1...13].map{ Double(0ドル)! }
314
- // wineParameters.append(parameters)
315
- // let species = Int(items[0])!
316
- // if species == 1 {
317
- // wineClassifications.append([1.0, 0.0, 0.0])
318
- // } else if species == 2 {
319
- // wineClassifications.append([0.0, 1.0, 0.0])
320
- // } else {
321
- // wineClassifications.append([0.0, 0.0, 1.0])
322
- // }
323
- // wineCultivars.append(species)
324
- // }
325
- // normalizeByColumnMax(dataset: &wineParameters)
326
- // wineSamples = Array(wineParameters.dropFirst(150))
327
- // wineCultivars = Array(wineCultivars.dropFirst(150))
328
- // wineParameters = Array(wineParameters.dropLast(28))
329
- //}
330
- //
331
- //func interpretOutput(output: [Double]) -> Int {
332
- // if output.max()! == output[0] {
333
- // return 1
334
- // } else if output.max()! == output[1] {
335
- // return 2
336
- // } else {
337
- // return 3
338
- // }
339
- //}
340
- //
341
- //parseWineCSV()
342
- //// train over entire data set 5 times
343
- //for _ in 0..<5 {
344
- // network.train(inputs: wineParameters, expecteds: wineClassifications, printError: false)
345
- //}
346
- //
347
- //let results = network.validate(inputs: wineSamples, expecteds: wineCultivars, interpretOutput: interpretOutput)
348
- //print("\(results.correct) correct of \(results.total) = \(results.percentage * 100)%")
274
+ /// assumes all rows are of equal length
275
+ /// and divide each column by its max throughout the data set
276
+ /// for that column
277
+ func normalizeByColumnMax( dataset: inout [ [ Double ] ] ) {
278
+ for colNum in 0 ..< dataset [ 0 ] . count {
279
+ let column = dataset. map { 0ドル [ colNum] }
280
+ let maximum = column. max ( ) !
281
+ for rowNum in 0 ..< dataset. count {
282
+ dataset [ rowNum] [ colNum] = dataset [ rowNum] [ colNum] / maximum
283
+ }
284
+ }
285
+ }
286
+
287
+ // MARK: Iris Test
349
288
350
289
var network : Network = Network ( layerStructure: [ 4 , 5 , 3 ] , learningRate: 0.3 )
351
290
var irisParameters : [ [ Double ] ] = [ [ Double] ] ( )
@@ -403,5 +342,63 @@ let testersCorrects = Array(irisSpecies[140..<150])
403
342
let results = network. validate ( inputs: testers, expecteds: testersCorrects, interpretOutput: interpretOutput)
404
343
print ( " \( results. correct) correct of \( results. total) = \( results. percentage * 100 ) % " )
405
344
345
+ /// Wine Test
346
+
347
+ //var network: Network = Network(layerStructure: [13,7,3], learningRate: 7.0)
348
+ //// for training
349
+ //var wineParameters: [[Double]] = [[Double]]()
350
+ //var wineClassifications: [[Double]] = [[Double]]()
351
+ //// for testing/validation
352
+ //var wineSamples: [[Double]] = [[Double]]()
353
+ //var wineCultivars: [Int] = [Int]()
354
+ //
355
+ //func parseWineCSV() {
356
+ // let myBundle = Bundle.main
357
+ // let urlpath = myBundle.path(forResource: "wine", ofType: "csv")
358
+ // let url = URL(fileURLWithPath: urlpath!)
359
+ // let csv = try! String.init(contentsOf: url)
360
+ // let lines = csv.components(separatedBy: "\n")
361
+ //
362
+ // let shuffledLines = lines.shuffled()
363
+ // for line in shuffledLines {
364
+ // if line == "" { continue }
365
+ // let items = line.components(separatedBy: ",")
366
+ // let parameters = items[1...13].map{ Double(0ドル)! }
367
+ // wineParameters.append(parameters)
368
+ // let species = Int(items[0])!
369
+ // if species == 1 {
370
+ // wineClassifications.append([1.0, 0.0, 0.0])
371
+ // } else if species == 2 {
372
+ // wineClassifications.append([0.0, 1.0, 0.0])
373
+ // } else {
374
+ // wineClassifications.append([0.0, 0.0, 1.0])
375
+ // }
376
+ // wineCultivars.append(species)
377
+ // }
378
+ // normalizeByColumnMax(dataset: &wineParameters)
379
+ // wineSamples = Array(wineParameters.dropFirst(150))
380
+ // wineCultivars = Array(wineCultivars.dropFirst(150))
381
+ // wineParameters = Array(wineParameters.dropLast(28))
382
+ //}
383
+ //
384
+ //func interpretOutput(output: [Double]) -> Int {
385
+ // if output.max()! == output[0] {
386
+ // return 1
387
+ // } else if output.max()! == output[1] {
388
+ // return 2
389
+ // } else {
390
+ // return 3
391
+ // }
392
+ //}
393
+ //
394
+ //parseWineCSV()
395
+ //// train over entire data set 5 times
396
+ //for _ in 0..<5 {
397
+ // network.train(inputs: wineParameters, expecteds: wineClassifications, printError: false)
398
+ //}
399
+ //
400
+ //let results = network.validate(inputs: wineSamples, expecteds: wineCultivars, interpretOutput: interpretOutput)
401
+ //print("\(results.correct) correct of \(results.total) = \(results.percentage * 100)%")
402
+
406
403
//: [Next](@next)
407
404
0 commit comments