1-
21import scala .util .chaining .*
32
43import io .github .quafadas .plots .SetupVegaBrowser .{* , given }
@@ -35,12 +34,14 @@ import scala.annotation.targetName
3534 val imageHeight = 28
3635
3736 val labels : Array [Int ] = traindata.col(0 ) // y data, the labels are in the first column
38- val pixelData : Matrix [Float ] = traindata(:: ,1 until traindata.cols).deepCopy / 255.0f
37+ val pixelData : Matrix [Float ] = traindata(:: , 1 until traindata.cols).deepCopy / 255.0f
3938
4039 if samplePlot then
41- VegaPlot .fromResource(" hist.vg.json" ).plot(
42- _.data._0.values := labels.map(label => (u = label)).asJson
43- )
40+ VegaPlot
41+ .fromResource(" hist.vg.json" )
42+ .plot(
43+ _.data._0.values := labels.map(label => (u = label)).asJson
44+ )
4445 end if
4546
4647 val one_hot_Y = oneHotEncode[Float ](labels)
@@ -52,15 +53,20 @@ import scala.annotation.targetName
5253 val data = pixelData.row(idx)
5354 val pixelSize = 10
5455 val d = dataToCoords(data, pixelSize)
55- VegaPlot .fromResource(" pixelPlot.vg.json" ).plot(
56- _.data.values := d.asJson,
57- _.mark.width := pixelSize,
58- _.mark.height := pixelSize,
59- _.width := imageWidth * pixelSize,
60- _.height := imageHeight * pixelSize,
61- _.title := s " Sample: $idx - Label ${labels(idx)}"
62- )
63- one_hot_Y.row(idx).mkString(" , " ).tap(str => println(s " One hot encoding for sample $idx:, label ${labels(idx)}: $str" ))
56+ VegaPlot
57+ .fromResource(" pixelPlot.vg.json" )
58+ .plot(
59+ _.data.values := d.asJson,
60+ _.mark.width := pixelSize,
61+ _.mark.height := pixelSize,
62+ _.width := imageWidth * pixelSize,
63+ _.height := imageHeight * pixelSize,
64+ _.title := s " Sample: $idx - Label ${labels(idx)}"
65+ )
66+ one_hot_Y
67+ .row(idx)
68+ .mkString(" , " )
69+ .tap(str => println(s " One hot encoding for sample $idx:, label ${labels(idx)}: $str" ))
6470 }
6571
6672 end if
@@ -77,7 +83,9 @@ import scala.annotation.targetName
7783 val bias2 = Array .fill(l3Size)(startBias)
7884
7985 if shapeDiagnostic then
80- println(s " pixelData shape: ${pixelData.shape}, pixelData rows: ${pixelData.rows}, pixelData cols: ${pixelData.cols}, pixelData rowStride: ${pixelData.rowStride}, pixelData colStride: ${pixelData.colStride} pixelData offset: ${pixelData.offset}" )
86+ println(
87+ s " pixelData shape: ${pixelData.shape}, pixelData rows: ${pixelData.rows}, pixelData cols: ${pixelData.cols}, pixelData rowStride: ${pixelData.rowStride}, pixelData colStride: ${pixelData.colStride} pixelData offset: ${pixelData.offset}"
88+ )
8189
8290 println(s " x layout ${pixelData.layout}" )
8391
@@ -114,7 +122,6 @@ import scala.annotation.targetName
114122 b2 = bias2
115123 )
116124
117-
118125end mnist
119126
120127// Helper methods.
@@ -178,46 +185,44 @@ end foward_prop
178185
179186// Float version
180187def foward_prop (w1 : Matrix [Float ], b1 : Array [Float ], w2 : Matrix [Float ], b2 : Array [Float ], x : Matrix [Float ]) =
181- val z1 = (x @@ w1)
182- z1.mapRowsInPlace(r => r.tap(_ += b1))
183- val a1 = reluM(z1) // get rid of negative values
184- val z2 = (a1 @@ w2)
185- z2.mapRowsInPlace(r => r.tap(_ += b2)) // results [(rows, 10) @ (10, 10)] = (rows, 10)
186- val a2 = softmaxRows(z2)
187- (z1 = z1, a1 = a1, z2 = z2, a2 = a2)
188+ val z1 = (x @@ w1)
189+ z1.mapRowsInPlace(r => r.tap(_ += b1))
190+ val a1 = reluM(z1) // get rid of negative values
191+ val z2 = (a1 @@ w2)
192+ z2.mapRowsInPlace(r => r.tap(_ += b2)) // results [(rows, 10) @ (10, 10)] = (rows, 10)
193+ val a2 = softmaxRows(z2)
194+ (z1 = z1, a1 = a1, z2 = z2, a2 = a2)
188195end foward_prop
189196
190-
191197def back_prop (
192- w1 : Matrix [Float ],
193- b1 : Array [Float ],
194- w2 : Matrix [Float ],
195- b2 : Array [Float ],
196- z1 : Matrix [Float ],
197- a1 : Matrix [Float ],
198- z2 : Matrix [Float ],
199- a2 : Matrix [Float ],
200- X : Matrix [Float ],
201- Y : Matrix [Float ]
198+ w1 : Matrix [Float ],
199+ b1 : Array [Float ],
200+ w2 : Matrix [Float ],
201+ b2 : Array [Float ],
202+ z1 : Matrix [Float ],
203+ a1 : Matrix [Float ],
204+ z2 : Matrix [Float ],
205+ a2 : Matrix [Float ],
206+ X : Matrix [Float ],
207+ Y : Matrix [Float ]
202208) =
203- val m = Y .rows
204- val m_inv = 1.0f / m
205- val dz2 = a2 - Y
206- val dw2 = m_inv * (a1.transpose @@ dz2)
209+ val m = Y .rows
210+ val m_inv = 1.0f / m
211+ val dz2 = a2 - Y
212+ val dw2 = m_inv * (a1.transpose @@ dz2)
207213
208- val db2 = dz2.mapColsToScalar(_.sum).raw
209- val dz1Check = (z1 > 0 )
210- val dz1 = (dz2 @@ w2.transpose)
211- dz1 *:*= dz1Check
214+ val db2 = dz2.mapColsToScalar(_.sum).raw
215+ val dz1Check = (z1 > 0 )
216+ val dz1 = (dz2 @@ w2.transpose)
217+ dz1 *:*= dz1Check
212218
213- val dw1 = m_inv * (X .transpose @@ dz1)
219+ val dw1 = m_inv * (X .transpose @@ dz1)
214220
215- val db1 = dz1.mapColsToScalar(r => r.sumSIMD * m_inv).raw
216- // println("back propagation (Float) done ----")
217- (dw1 = dw1, db1 = db1, dw2 = dw2, db2 = db2)
221+ val db1 = dz1.mapColsToScalar(r => r.sumSIMD * m_inv).raw
222+ // println("back propagation (Float) done ----")
223+ (dw1 = dw1, db1 = db1, dw2 = dw2, db2 = db2)
218224end back_prop
219225
220-
221226def back_prop (
222227 w1 : Matrix [Double ],
223228 b1 : Array [Double ],
@@ -295,17 +300,17 @@ def loss(predicted: Array[Int], actual: Array[Int]) =
295300 (predicted =:= actual).trues.toDouble / predicted.length
296301
297302def gradient_descentf (
298- x : Matrix [Float ],
299- y : Matrix [Float ],
300- labels : Array [Int ],
301- iterations : Int ,
302- batchSize : Int ,
303- alpha : Float ,
304- decayRate : Float ,
305- w1 : Matrix [Float ],
306- b1 : Array [Float ],
307- w2 : Matrix [Float ],
308- b2 : Array [Float ]
303+ x : Matrix [Float ],
304+ y : Matrix [Float ],
305+ labels : Array [Int ],
306+ iterations : Int ,
307+ batchSize : Int ,
308+ alpha : Float ,
309+ decayRate : Float ,
310+ w1 : Matrix [Float ],
311+ b1 : Array [Float ],
312+ w2 : Matrix [Float ],
313+ b2 : Array [Float ]
309314) =
310315 import BoundsCheck .DoBoundsCheck .yes
311316 println(" Starting gradient descent..." )
@@ -356,7 +361,6 @@ def gradient_descentf(
356361 end if
357362 end for
358363
359-
360364 val (_, _, _, a2) = foward_prop(w1_, b1_, w2_, b2_, x)
361365 println(s " iterations: $iterations, alpha: $alpha_, samples: ${x.rows}, classes: ${w2_.cols}" )
362366 // println(s"w1_ shape: ${w1_.shape}, w1_ rows: ${w1_.rows}, w1_ cols: ${w1_.cols}, ${w1.raw.take(10).printArr}")
0 commit comments