'If you look closely, you can see the letters made out of 1's Private A1 As Integer() = New Integer() {0, 0, 1, 1, 0, 0, 0, _ 0, 0, 0, 1, 0, 0, 0, _ 0, 0, 0, 1, 0, 0, 0, _ 0, 0, 1, 0, 1, 0, 0, _ 0, 0, 1, 0, 1, 0, 0, _ 0, 1, 1, 1, 1, 1, 0, _ 0, 1, 0, 0, 0, 1, 0, _ 0, 1, 0, 0, 0, 1, 0, _ 1, 1, 1, 0, 1, 1, 1} Private B1 As Integer() = New Integer() {1, 1, 1, 1, 1, 1, 0, _ 0, 1, 0, 0, 0, 0, 1, _ 0, 1, 0, 0, 0, 0, 1, _ 0, 1, 0, 0, 0, 0, 1, _ 0, 1, 1, 1, 1, 1, 0, _ 0, 1, 0, 0, 0, 0, 1, _ 0, 1, 0, 0, 0, 0, 1, _ 0, 1, 0, 0, 0, 0, 1, _ 1, 1, 1, 1, 1, 1, 0} Private C1 As Integer() = New Integer() {0, 0, 1, 1, 1, 1, 1, _ 0, 1, 0, 0, 0, 0, 1, _ 1, 0, 0, 0, 0, 0, 0, _ 1, 0, 0, 0, 0, 0, 0, _ 1, 0, 0, 0, 0, 0, 0, _ 1, 0, 0, 0, 0, 0, 0, _ 1, 0, 0, 0, 0, 0, 0, _ 0, 1, 0, 0, 0, 0, 1, _ 0, 0, 1, 1, 1, 1, 0} Private D1 As Integer() = New Integer() {1, 1, 1, 1, 1, 0, 0, _ 0, 1, 0, 0, 0, 1, 0, _ 0, 1, 0, 0, 0, 0, 1, _ 0, 1, 0, 0, 0, 0, 1, _ 0, 1, 0, 0, 0, 0, 1, _ 0, 1, 0, 0, 0, 0, 1, _ 0, 1, 0, 0, 0, 0, 1, _ 0, 1, 0, 0, 0, 1, 0, _ 1, 1, 1, 1, 1, 0, 0} Private E1 As Integer() = New Integer() {1, 1, 1, 1, 1, 1, 1, _ 0, 1, 0, 0, 0, 0, 1, _ 0, 1, 0, 0, 0, 0, 0, _ 0, 1, 0, 1, 0, 0, 0, _ 0, 1, 1, 1, 0, 0, 0, _ 0, 1, 0, 1, 0, 0, 0, _ 0, 1, 0, 0, 0, 0, 0, _ 0, 1, 0, 0, 0, 0, 1, _ 1, 1, 1, 1, 1, 1, 1} Private J1 As Integer() = New Integer() {0, 0, 0, 1, 1, 1, 1, _ 0, 0, 0, 0, 0, 1, 0, _ 0, 0, 0, 0, 0, 1, 0, _ 0, 0, 0, 0, 0, 1, 0, _ 0, 0, 0, 0, 0, 1, 0, _ 0, 0, 0, 0, 0, 1, 0, _ 0, 1, 0, 0, 0, 1, 0, _ 0, 1, 0, 0, 0, 1, 0, _ 0, 0, 1, 1, 1, 0, 0} Private K1 As Integer() = New Integer() {1, 1, 1, 0, 0, 1, 1, _ 0, 1, 0, 0, 1, 0, 0, _ 0, 1, 0, 1, 0, 0, 0, _ 0, 1, 1, 0, 0, 0, 0, _ 0, 1, 1, 0, 0, 0, 0, _ 0, 1, 0, 1, 0, 0, 0, _ 0, 1, 0, 0, 1, 0, 0, _ 0, 1, 0, 0, 0, 1, 0, _ 1, 1, 1, 0, 0, 1, 1} Private A2 As Integer() = New Integer() {0, 0, 0, 1, 0, 0, 0, _ 0, 0, 0, 1, 0, 0, 0, _ 0, 0, 0, 1, 0, 0, 0, _ 0, 0, 1, 0, 1, 0, 0, _ 0, 0, 1, 0, 1, 0, 0, _ 0, 1, 0, 0, 0, 1, 0, _ 0, 1, 1, 1, 1, 1, 0, _ 0, 1, 0, 0, 0, 1, 0, _ 0, 1, 0, 0, 0, 1, 0} Private B2 As Integer() = New Integer() {1, 1, 1, 1, 1, 1, 0, _ 1, 0, 0, 0, 0, 0, 1, _ 1, 0, 0, 0, 0, 0, 1, _ 1, 0, 0, 0, 0, 0, 1, _ 1, 1, 1, 1, 1, 1, 0, _ 1, 0, 0, 0, 0, 0, 1, _ 1, 0, 0, 0, 0, 0, 1, _ 1, 0, 0, 0, 0, 0, 1, _ 1, 1, 1, 1, 1, 1, 0} Private C2 As Integer() = New Integer() {0, 0, 1, 1, 1, 0, 0, _ 0, 1, 0, 0, 0, 1, 0, _ 1, 0, 0, 0, 0, 0, 1, _ 1, 0, 0, 0, 0, 0, 0, _ 1, 0, 0, 0, 0, 0, 0, _ 1, 0, 0, 0, 0, 0, 0, _ 1, 0, 0, 0, 0, 0, 1, _ 0, 1, 0, 0, 0, 1, 0, _ 0, 0, 1, 1, 1, 0, 0} Private D2 As Integer() = New Integer() {1, 1, 1, 1, 1, 0, 0, _ 1, 0, 0, 0, 0, 1, 0, _ 1, 0, 0, 0, 0, 0, 1, _ 1, 0, 0, 0, 0, 0, 1, _ 1, 0, 0, 0, 0, 0, 1, _ 1, 0, 0, 0, 0, 0, 1, _ 1, 0, 0, 0, 0, 0, 1, _ 1, 0, 0, 0, 0, 1, 0, _ 1, 1, 1, 1, 1, 0, 0} Private E2 As Integer() = New Integer() {1, 1, 1, 1, 1, 1, 1, _ 1, 0, 0, 0, 0, 0, 0, _ 1, 0, 0, 0, 0, 0, 0, _ 1, 0, 0, 0, 0, 0, 0, _ 1, 1, 1, 1, 1, 0, 0, _ 1, 0, 0, 0, 0, 0, 0, _ 1, 0, 0, 0, 0, 0, 0, _ 1, 0, 0, 0, 0, 0, 0, _ 1, 1, 1, 1, 1, 1, 1} Private J2 As Integer() = New Integer() {0, 0, 0, 0, 0, 1, 0, _ 0, 0, 0, 0, 0, 1, 0, _ 0, 0, 0, 0, 0, 1, 0, _ 0, 0, 0, 0, 0, 1, 0, _ 0, 0, 0, 0, 0, 1, 0, _ 0, 0, 0, 0, 0, 1, 0, _ 0, 1, 0, 0, 0, 1, 0, _ 0, 1, 0, 0, 0, 1, 0, _ 0, 0, 1, 1, 1, 0, 0} Private K2 As Integer() = New Integer() {1, 0, 0, 0, 0, 1, 0, _ 1, 0, 0, 0, 1, 0, 0, _ 1, 0, 0, 1, 0, 0, 0, _ 1, 0, 1, 0, 0, 0, 0, _ 1, 1, 0, 0, 0, 0, 0, _ 1, 0, 1, 0, 0, 0, 0, _ 1, 0, 0, 1, 0, 0, 0, _ 1, 0, 0, 0, 1, 0, 0, _ 1, 0, 0, 0, 0, 1, 0} Private A3 As Integer() = New Integer() {0, 0, 0, 1, 0, 0, 0, _ 0, 0, 0, 1, 0, 0, 0, _ 0, 0, 1, 0, 1, 0, 0, _ 0, 0, 1, 0, 1, 0, 0, _ 0, 1, 0, 0, 0, 1, 0, _ 0, 1, 1, 1, 1, 1, 0, _ 1, 0, 0, 0, 0, 0, 1, _ 1, 0, 0, 0, 0, 0, 1, _ 1, 1, 0, 0, 0, 1, 1} Private B3 As Integer() = New Integer() {1, 1, 1, 1, 1, 1, 0, _ 0, 1, 0, 0, 0, 0, 1, _ 0, 1, 0, 0, 0, 0, 1, _ 0, 1, 1, 1, 1, 1, 0, _ 0, 1, 0, 0, 0, 0, 1, _ 0, 1, 0, 0, 0, 0, 1, _ 0, 1, 0, 0, 0, 0, 1, _ 0, 1, 0, 0, 0, 0, 1, _ 1, 1, 1, 1, 1, 1, 0} Private C3 As Integer() = New Integer() {0, 0, 1, 1, 1, 0, 1, _ 0, 1, 0, 0, 0, 1, 1, _ 1, 0, 0, 0, 0, 0, 1, _ 1, 0, 0, 0, 0, 0, 0, _ 1, 0, 0, 0, 0, 0, 0, _ 1, 0, 0, 0, 0, 0, 0, _ 1, 0, 0, 0, 0, 0, 1, _ 0, 1, 0, 0, 0, 1, 0, _ 0, 0, 1, 1, 1, 0, 0} Private D3 As Integer() = New Integer() {1, 1, 1, 1, 0, 0, 0, _ 0, 1, 0, 0, 1, 0, 0, _ 0, 1, 0, 0, 0, 1, 0, _ 0, 1, 0, 0, 0, 1, 0, _ 0, 1, 0, 0, 0, 1, 0, _ 0, 1, 0, 0, 0, 1, 0, _ 0, 1, 0, 0, 0, 1, 0, _ 0, 1, 0, 0, 1, 0, 0, _ 1, 1, 1, 1, 0, 0, 0} Private E3 As Integer() = New Integer() {1, 1, 1, 1, 1, 1, 1, _ 0, 1, 0, 0, 0, 0, 1, _ 0, 1, 0, 0, 1, 0, 0, _ 0, 1, 1, 1, 1, 0, 0, _ 0, 1, 0, 0, 1, 0, 0, _ 0, 1, 0, 0, 0, 0, 0, _ 0, 1, 0, 0, 0, 0, 0, _ 0, 1, 0, 0, 0, 0, 1, _ 1, 1, 1, 1, 1, 1, 1} Private J3 As Integer() = New Integer() {0, 0, 0, 0, 1, 1, 1, _ 0, 0, 0, 0, 0, 1, 0, _ 0, 0, 0, 0, 0, 1, 0, _ 0, 0, 0, 0, 0, 1, 0, _ 0, 0, 0, 0, 0, 1, 0, _ 0, 0, 0, 0, 0, 1, 0, _ 0, 0, 0, 0, 0, 1, 0, _ 0, 1, 0, 0, 0, 1, 0, _ 0, 0, 1, 1, 1, 0, 0} Private K3 As Integer() = New Integer() {1, 1, 1, 0, 0, 1, 1, _ 0, 1, 0, 0, 0, 1, 0, _ 0, 1, 0, 0, 1, 0, 0, _ 0, 1, 0, 1, 0, 0, 0, _ 0, 1, 1, 0, 0, 0, 0, _ 0, 1, 0, 1, 0, 0, 0, _ 0, 1, 0, 0, 1, 0, 0, _ 0, 1, 0, 0, 0, 1, 0, _ 1, 1, 1, 0, 0, 1, 1} Private Const MAX_CLUSTERS As Integer = 25 Private Const VEC_LEN As Integer = 63 Private Const VEC_XLEN As Integer = 5 Private Const VEC_YLEN As Integer = 5 Private Const DECAY_RATE As Double = 0.96 'About 100 iterations. Private Const MIN_ALPHA As Double = 0.01 Private Const RADIUS_REDUCTION_POINT As Double = 0.023 'Last 20% of iterations. Private Const CR As String = Chr(13) + Chr(10) Private Alpha As Double = 0.6 Private D(MAX_CLUSTERS) As Double 'Network nodes. 'Weight matrix with randomly chosen values between 0.0 and 1.0 Private w(MAX_CLUSTERS, VEC_LEN) As Double '25 x 63 Private Const IN_PATTERNS As Integer = 21 Private Pattern As Integer()() = New Integer(IN_PATTERNS)() {} Private Sub Initialize() Dim i, j As Integer 'Insert pattern arrays into Pattern() to make an array of arrays. Pattern(0) = A1 Pattern(1) = B1 Pattern(2) = C1 Pattern(3) = D1 Pattern(4) = E1 Pattern(5) = J1 Pattern(6) = K1 Pattern(7) = A2 Pattern(8) = B2 Pattern(9) = C2 Pattern(10) = D2 Pattern(11) = E2 Pattern(12) = J2 Pattern(13) = K2 Pattern(14) = A3 Pattern(15) = B3 Pattern(16) = C3 Pattern(17) = D3 Pattern(18) = E3 Pattern(19) = J3 Pattern(20) = K3 'Initialize wieghts to random values between 0.0 and 1.0 For i = 0 To MAX_CLUSTERS - 1 For j = 0 To VEC_LEN - 1 Randomize(Microsoft.VisualBasic.DateAndTime.Timer) w(i, j) = CDbl(Rnd()) Next j Next i End Sub Private Sub Training() Dim Iterations As Integer = 0 Dim ReductionFlag As Boolean = False Dim ReductionPoint As Integer = 0 Dim VecNum As Integer Dim DMin As Integer Do While Alpha > MIN_ALPHA Iterations += 1 For VecNum = 0 To IN_PATTERNS - 1 'Compute input for all nodes. ComputeInput(Pattern(VecNum)) 'See which is smaller? DMin = Minimum(D) 'Update the weights on the winning unit. UpdateWeights(Pattern(VecNum), DMin) Next VecNum 'Reduce the learning rate. Alpha = DECAY_RATE * Alpha 'Reduce radius at specified point. If Alpha < RADIUS_REDUCTION_POINT Then If ReductionFlag = False Then ReductionFlag = True ReductionPoint = Iterations End If End If Loop Text1.Text += "Iterations: " + CStr(Iterations) + CR Text1.Text += "Neighborhood radius reduced after " + _ CStr(ReductionPoint) + " iterations." + CR + CR End Sub Private Sub ComputeInput(ByRef VectorArray As Integer()) Dim i, j As Integer ClearArray(D) For i = 0 To MAX_CLUSTERS - 1 For j = 0 To VEC_LEN - 1 D(i) += (w(i, j) - VectorArray(j)) ^ 2 Next j Next i End Sub Private Sub UpdateWeights(ByRef wArray As Integer(), ByVal DMin As Integer) Dim i, y, DIndex, PointA, PointB As Integer Dim Done As Boolean = False For i = 0 To VEC_LEN - 1 'Only include neighbors before radius reduction point is reached. If Alpha > RADIUS_REDUCTION_POINT Then y = 1 Do Until Done If y = 1 Then 'Top row of 3. If DMin > VEC_XLEN - 1 Then PointA = DMin - VEC_XLEN - 1 PointB = DMin - VEC_XLEN + 1 Else y = 2 End If End If If y = 2 Then 'Middle row of 3. PointA = DMin - 1 'DMin is like an anchor position right between these two. PointB = DMin + 1 End If If y = 3 Then 'Bottom row of 3. If DMin < (VEC_XLEN * (VEC_YLEN - 1)) Then PointA = DMin + VEC_XLEN - 1 PointB = DMin + VEC_XLEN + 1 Else Done = True End If End If If Done = False Then For DIndex = PointA To PointB 'Check if anchor is at left side. If (DMin Mod VEC_XLEN = 0) Then 'Check if anchor is at top. If DIndex > PointA Then w(DIndex, i) = w(DIndex, i) + _ (Alpha * (wArray(i) - w(DIndex, i))) End If 'Check if anchor is at right side. ElseIf ((DMin + 1) Mod VEC_XLEN = 0) Then 'Check if anchor is at top. If DIndex < PointB Then w(DIndex, i) = w(DIndex, i) + _ (Alpha * (wArray(i) - w(DIndex, i))) End If 'Otherwise, anchor is not at either side. Else w(DIndex, i) = w(DIndex, i) + _ (Alpha * (wArray(i) - w(DIndex, i))) End If Next DIndex End If If y = 3 Then Done = True End If y += 1 'prepare to start the next row. Loop ElseIf Alpha <= RADIUS_REDUCTION_POINT Then 'Update only the winner. w(DMin, i) = w(DMin, i) + (Alpha * (wArray(i) - w(DMin, i))) End If Next i End Sub Private Sub PrintResults() Dim i, j As Integer Dim VecNum As Integer Dim DMin As Integer 'Print clusters created. Text1.Text += "Clusters for training input:" + CR For VecNum = 0 To IN_PATTERNS - 1 'Compute input. ComputeInput(Pattern(VecNum)) 'See which is smaller. DMin = Minimum(D) Text1.Text += CR + "Vector (" Text1.Text += "Pattern " + CStr(VecNum) + ", " Text1.Text += ") fits into category " + CStr(DMin) + CR Next VecNum 'The weight matrix is HUGE, and I'd found the output easier to read just by commenting out that part... 'Print weight matrix. 'Text1.Text += CR 'For i = 0 To MAX_CLUSTERS - 1 ' Text1.Text += "Weights for Node " + CStr(i) + " connections:" + CR ' For j = 0 To VEC_LEN - 1 ' Text1.Text += Microsoft.VisualBasic.Format(w(i, j), "#.000") + ", " ' Next ' Text1.Text += CR + CR 'Next End Sub Private Sub ClearArray(ByRef NodeArray As Double()) Dim i As Integer For i = 0 To MAX_CLUSTERS - 1 D(i) = 0.0 Next i End Sub Private Function Minimum(ByRef NodeArray As Double()) As Integer Dim i As Integer Dim Winner As Integer Dim FoundNewWinner As Boolean Dim Done As Boolean = False Winner = 0 Do Until Done FoundNewWinner = False For i = 0 To MAX_CLUSTERS - 1 If i <> Winner Then 'Avoid self-comparison. If NodeArray(i) < NodeArray(Winner) Then Winner = i FoundNewWinner = True End If End If Next i If FoundNewWinner = False Then Done = True End If Loop Minimum = Winner End Function Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) _ Handles Button1.Click Initialize() Training() PrintResults() End Sub