41 |
Structure of the code
42 |
43 | We are going to create a neural network to train a neural network that will be able to perform the XOR logic gate. The result can be found here.
44 |
45 |
46 | First we are going to import the neural network module and create a main function.
47 | Then we create the neural network that we are going to train.
48 | The 0 is the seed for the random weights and biases to be able to get the same neural network at each run.
49 |
50 |
51 | import neural_networks as nn
52 |
53 | fn main() {
54 | mut model := nn.NeuralNetwork.new(0)
55 | }
56 |
57 |
58 | Then we add the layers that we want our network to have.
59 | We need our network to have 2 inputs and 1 output to match the XOR gate.
60 | So we will first add a Dense layer with 2 inputs and 3 outputs, 3 is arbitrary but works well.
61 | The two numbers after the number of inputs/outputs is the range for the initialisation of random weights and biases.
62 |
63 |
64 | Then an Activation layer, the Dense and Activation layers are complementary so we will add one Activation per Dense layer.
65 | The Activation function that we will use for this layer is leaky relu, as it is convenient.
66 | We add a second Dense layer with 3 input and 1 output and the Activation layer that goes with it.
67 |
68 |
69 | model.add_layer(nn.Dense.new(2, 3, 0.7, 0.65))
70 | model.add_layer(nn.Activation.new(.leaky_relu))
71 | model.add_layer(nn.Dense.new(3, 1, 0.6, 0.65))
72 | model.add_layer(nn.Activation.new(.leaky_relu))
73 |
74 |
75 | Then we need to create the parametters for the training.
76 | The learning rate, momentum, number of epochs are found by trial and error and these work well.
77 | The Cost function that we will use is the Mean Squared Error (MSE).
78 |
79 |
80 | We then add the dataset that the network will use for it's training.
81 | And same for the testing, in a real example the test data is unseen during the training to be able to see how well the networks does in an unseen situation
82 | but as we have only 4 different possible inputs we can not show unseen data to the network so we will use the same data.
83 |
84 |
85 | The neural newtork will print it's performance every print_interval epochs.
86 | For the test parameters, every training_interval epochs it will run the test dataset and print the results from the print_startth element of the test dataset to the print_endth one.
87 |
88 |
89 | training_parameters := nn.BackpropTrainingParams{
90 | learning_rate: 0.37
91 | momentum: 0.9
92 | nb_epochs: 300
93 | print_interval: 25
94 | cost_function: .mse // mean squared error
95 | training: nn.Dataset {
96 | inputs: [[0.0, 0.0], [0.0, 1.0], [1.0, 0.0], [1.0, 1.0]]
97 | expected_outputs: [[0.0], [1.0], [1.0], [0.0]]
98 | }
99 | test: nn.Dataset {
100 | inputs: [[0.0, 0.0], [0.0, 1.0], [1.0, 0.0], [1.0, 1.0]]
101 | expected_outputs: [[0.0], [1.0], [1.0], [0.0]]
102 | }
103 | test_params: nn.TestParams{
104 | print_start: 0
105 | print_end: 3
106 | training_interval: 100
107 | }
108 | }
109 |
110 |
111 | Now it's the time to train the network!
112 |
113 |
114 | model.train(training_parameters)
115 |
116 |
117 | We can also save the model by adding that to the end of the program:
118 |
119 |
120 | model.save_model('saveXOR')
121 |
122 |
123 | And to load a model (to use it or to train it further) you just need to create an empty model like we did at the start and then do:
124 |
125 |
126 | model.load_model('saveXOR')
127 |
128 |
129 | There it is, we can just run the program and it will train!
130 |
131 |