Private Inputs() As Integer = {-2, 1, 1} '(Change in cholesterol level, 'Change in weight, 'Family history) Private Const alpha As Single = 0.01 'Learning rate (alpha), which limits 'the size of a weight/bias adjustment 'step in a single training iteration. 'The smaller the value of alpha, the 'longer a network will take to train. Private Const mu As Single = 0.7 'Momentum value (mu). This enables the 'weight to change in response to the 'current gradient step and also to the 'previous one. It allows the network to 'find a reasonable solution in fewer 'training iterations. When both the 'current step and previous step are in 'agreement, it allows for a larger step size. Private Const n As Integer = 3 'The number neurons in the input 'layer equals the number of variables 'inherent to the problem. Private Const m As Integer = 3 Private Const NumCases As Integer = 8 Private Const TestCases As Integer = 3 Private Const CR As String = Chr(13) + Chr(10) Private hbias(m - 1) As Single ' 'h' refers to the hidden layer. Private hweight(n - 1, m - 1) As Single Private obias As Single ' 'o' refers to the output layer. Private oweight(m - 1) As Single Private hbias2(m - 1) As Single ' '2' refers to training copies. Private hweight2(n - 1, m - 1) As Single Private obias2 As Single Private oweight2(m - 1) As Single Private hin(m - 1) As Single Private hout(m - 1) As Single Private oin As Single Private oout As Single 'Since the physicians only want to know 'whether or not the individual is at 'risk for the disease, you'll only 'need a single output neuron. Private InputNeuron(n - 1) As Integer Private X1 As Single(,) = New Single(,) {{-3, -1, -3}, _ {-9, -1, 4}, _ {12, 1, 15}, _ {17, 1, 23}, _ {-16, -1, 2}, _ {26, -1, 16}, _ {3, -1, -12}, _ {-15, 1, -3}} Private X2 As Single(,) = New Single(,) {{-6, -1, 2}, _ {4, -1, 17}, _ {12, 1, -6}} Private targval As Single() = New Single() {-1, -1, 1, 1, -1, 1, -1, -1} Private targval2 As Single() = New Single() {-1, 1, 1} Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As _ System.EventArgs) _ Handles Button1.Click Dim TrainError As Single Dim I, J, K As Integer Dim TrainingCycles As Integer Dim TrainingComplete As Boolean = False Initialize(n, m) J = 0 Do Until J = 10001 TrainError = 0 For I = 0 To NumCases - 1 For K = 0 To n - 1 InputNeuron(K) = X1(I, K) Next hiddeninput(n, m) outputinput(m) oout = Sigmoid(oin) BackPropagate(I, m) If J > 999 Then If J Mod 1000 = 0 Then Text1.Text += CStr(J) & " " & CStr(I) & " " & CStr(targval(I)) _ & " " & CStr(oout) & CR End If End If TrainError = TrainError + (targval(I) - oout) ^ 2 Next I TrainError = System.Math.Sqrt(TrainError / NumCases) If J > 999 Then If J Mod 1000 = 0 Then Text1.Text += "Training Error: " + CStr(TrainError) + CR End If End If If TrainError < 0.01 Then If TrainingComplete = False Then TrainingCycles = J TrainingComplete = True End If End If J += 1 Loop Text1.Text += CR + "Training iterations needed: " + CStr(TrainingCycles) + CR ExaminePatient() ValidateNet() End Sub Private Sub Initialize(ByVal n As Integer, ByVal m As Integer) 'Since there's no way of knowing the appropriate weights and 'biases prior to training, randomly initialize each neuron 'with a weight between –0.5 and 0.5 Dim I, J As Integer Randomize(Microsoft.VisualBasic.Timer) For I = 0 To n - 1 For J = 0 To m - 1 hweight(I, J) = (Rnd() - 0.5) 'hidden layer connections. hweight2(I, J) = hweight(I, J) 'copies for training. Next J Next I For J = 0 To m - 1 hbias(J) = (Rnd() - 0.5) 'hidden layer biases. hbias2(J) = hbias(J) 'copies for training. oweight(J) = (Rnd() - 0.5) 'output layer connections. oweight2(J) = oweight(J) 'copies for training. Next J obias = (Rnd() = 0.5) 'output neuron bias obias2 = obias 'copy for training. End Sub Private Sub hiddeninput(ByVal n As Integer, ByVal m As Integer) 'This carries out the summation process for each neuron in the 'hidden layer of the neural network. 'The input value to a node is: 'the bias for that node 'added to the sum of each input interconnection, 'where the value of an interconnection is the input neuron's value 'multiplied by the weight of the connection. Dim I, J As Integer Dim sum As Single For J = 0 To m - 1 sum = 0 For I = 0 To n - 1 sum = sum + (InputNeuron(I) * hweight(I, J)) Next I hin(J) = hbias(J) + sum Next J 'Send each scaled input of the hidden layer through 'the bipolar sigmoid (trans) function. For J = 0 To m - 1 hout(J) = Sigmoid(hin(J)) Next J End Sub Private Sub outputinput(ByVal m As Integer) 'Pass hidden layer values through the weighted 'connections to the output layer. Dim J As Integer Dim sum As Single sum = 0 For J = 0 To m - 1 sum = sum + (hout(J) * oweight(J)) Next J oin = obias + sum End Sub Private Sub BackPropagate(ByVal I As Integer, ByVal m As Integer) 'Back-propagates the error to the interconnections between 'the output and hidden layer neurons. Dim J As Integer Dim odelta, dobias, doweight(m - 1) As Single odelta = SigmoidDerivative(oin) * (targval(I) - oout) For J = 0 To m - 1 doweight(J) = (alpha * odelta * hout(J)) + (mu * (oweight(J) - _ oweight2(J))) oweight2(J) = oweight(J) oweight(J) = oweight(J) + doweight(J) Next J dobias = (alpha * odelta) + (mu * (obias - obias2)) obias2 = obias obias = obias + dobias updatehidden(n, m, odelta) End Sub Private Sub updatehidden(ByVal n As Integer, ByVal m As Integer, ByVal d As Single) 'Since there can be multiple hidden layer neurons as well as multiple 'input neurons, some additional loops are utilized to ensure that every 'weight and bias is updated appropriately. Dim I, J, K As Integer Dim hdelta, dhbias(m - 1), dhweight(n - 1, m - 1) As Single For J = 0 To m - 1 hdelta = (d * oweight(J)) * SigmoidDerivative(hin(J)) For I = 0 To n - 1 dhweight(I, J) = (alpha * hdelta * InputNeuron(I)) + (mu * _ (hweight(I, J) - _ hweight2(I, J))) hweight2(I, J) = hweight(I, J) hweight(I, J) = hweight(I, J) + dhweight(I, J) Next I dhbias(J) = (alpha * hdelta) + (mu * (hbias(J) - hbias2(J))) hbias2(J) = hbias(J) hbias(J) = hbias(J) + dhbias(J) Next J End Sub Private Sub ExaminePatient() InputNeuron(0) = Inputs(0) 'Change in cholesterol. InputNeuron(1) = Inputs(1) 'Change in weight. InputNeuron(2) = Inputs(2) 'Family members with heart disease. hiddeninput(n, m) outputinput(m) oout = Sigmoid(oin) If oout < 0 Then Text1.Text += CR + "The patient is at a reduced risk for disease" + CR Else Text1.Text += CR + "The patient is at an increased risk for disease" + CR End If End Sub Private Sub ValidateNet() Dim I, J, K As Integer Dim Correct As Integer = 0 For I = 0 To TestCases - 1 For K = 0 To n - 1 InputNeuron(K) = X2(I, K) Next hiddeninput(n, m) outputinput(m) oout = Sigmoid(oin) If targval2(I) = System.Math.Round(oout) Then Correct = Correct + 1 End If Text1.Text += "Expected: " + CStr(targval2(I)) + " Actual: " + CStr(oout) + CR Next I If Correct >= 2 Then Text1.Text += CStr(Correct) & " out of " & CStr(TestCases) & _ " Match. Validation Successful." + CR Else Text1.Text += CStr(Correct) & " out of " & CStr(TestCases) & _ " Match. Validation Unsuccessful." + CR End If End Sub Private Function Sigmoid(ByVal Val As Single) As Single 'A.K.A. the activation function, it takes the sum of all the neurons' 'weighted inputs and uses the value to calculate the neurons' output. 'This output is also thought of as the "excitation" of the neuron. Dim f As Single f = (2 / (1 + (System.Math.Exp(-Val)))) - 1 'Output ranges from -1 to 1. Sigmoid = f End Function Private Function SigmoidDerivative(ByVal Val As Single) As Single 'Backpropagation: 'Calculate delta by multiplying the difference between: 'an output computed by the neural network for a given pattern, 'and a target value for a known outcome for the given pattern, 'by the derivative of the activation function (Sigmoid). Dim f As Single f = (1 / 2) * (1 + Sigmoid(Val)) * (1 - Sigmoid(Val)) SigmoidDerivative = f End Function