public void multiply <Type>(Type n) { if (n is NNMatrix) { for (int i = 0; i < this.rows; i++) { for (int j = 0; j < this.cols; j++) { NNMatrix mat = (NNMatrix)(object)n; this.data[i][j] *= mat.data[i][j]; } } } else { for (int i = 0; i < this.rows; i++) { for (int j = 0; j < this.cols; j++) { float val = (float)(object)n; this.data[i][j] *= val; } } } }
public static NNMatrix multiply(NNMatrix a, NNMatrix b) { if (a.cols != b.rows) { Debug.Log("Columns of A must match rows of B."); return(null); } NNMatrix result = new NNMatrix(a.rows, b.cols); for (int i = 0; i < result.rows; i++) { for (int j = 0; j < result.cols; j++) { float sum = 0f; for (int k = 0; k < a.cols; k++) { sum += a.data[i][k] * b.data[k][j]; } result.data[i][j] = sum; } } return(result); }
public void train(List <float> input_list, List <float> target_list) { NNMatrix inputs = NNMatrix.fromList(input_list); NNMatrix hidden = NNMatrix.multiply(this.weights_ih, inputs); hidden.add(this.bias_h); // activate function hidden.map(activate); NNMatrix outputs = NNMatrix.multiply(this.weights_ho, hidden); outputs.add(this.bias_o); outputs.map(activate); NNMatrix targets = NNMatrix.fromList(target_list); // calculate the error // ERROR = TARGETS(answer) - OUTPUTS(actual outputs) NNMatrix output_errors = NNMatrix.subtract(targets, outputs); //var gradients = outputs * (1-outputs); // calculate gradient NNMatrix gradients = NNMatrix.map(outputs, dactivate); gradients.multiply(output_errors); gradients.multiply(this.learning_rate); // calculate deltas NNMatrix hidden_T = NNMatrix.transpose(hidden); NNMatrix weights_ho_deltas = NNMatrix.multiply(gradients, hidden_T); // Adjust the weights by deltas this.weights_ho.add(weights_ho_deltas); // Adjust bias by its delta (which is just the gradients) this.bias_o.add(gradients); // calculate the hidden layer errors NNMatrix who_t = NNMatrix.transpose(this.weights_ho); NNMatrix hidden_errors = NNMatrix.multiply(who_t, output_errors); // calculate hidden gradients NNMatrix hidden_gradient = NNMatrix.map(hidden, dactivate); hidden_gradient.multiply(hidden_errors); hidden_gradient.multiply(this.learning_rate); // calculate input->hidden deltas NNMatrix input_T = NNMatrix.transpose(inputs); NNMatrix weight_ih_deltas = NNMatrix.multiply(hidden_gradient, input_T); this.weights_ih.add(weight_ih_deltas); // Adjust bias by its delta (which is just the hiddent gradients) this.bias_h.add(hidden_gradient); }
public static NNMatrix fromList(List <float> list) { NNMatrix m = new NNMatrix(list.Count, 1); for (int i = 0; i < list.Count; i++) { m.data[i][0] = list[i]; } return(m); }
public static NNMatrix subtract(NNMatrix a, NNMatrix b) { NNMatrix result = new NNMatrix(a.rows, a.cols); for (int i = 0; i < result.rows; i++) { for (int j = 0; j < result.cols; j++) { result.data[i][j] = a.data[i][j] - b.data[i][j]; } } return(result); }
public static NNMatrix transpose(NNMatrix matrix) { NNMatrix result = new NNMatrix(matrix.cols, matrix.rows); for (int i = 0; i < matrix.rows; i++) { for (int j = 0; j < matrix.cols; j++) { result.data[j][i] = matrix.data[i][j]; } } return(result); }
public static NNMatrix map(NNMatrix matrix, System.Func <float, float> func) { NNMatrix result = new NNMatrix(matrix.rows, matrix.cols); for (int i = 0; i < matrix.rows; i++) { for (int j = 0; j < matrix.cols; j++) { float val = matrix.data[i][j]; result.data[i][j] = func(val); } } return(result); }
public NeuralNetwork(int _input_nodes, int _hidden_nodes, int _output_nodes) { this.input_nodes = _input_nodes; this.hidden_nodes = _hidden_nodes; this.output_nodes = _output_nodes; // weight between input and hidden this.weights_ih = new NNMatrix(this.hidden_nodes, this.input_nodes); this.weights_ih.randomize(); // weight between hidden and output this.weights_ho = new NNMatrix(this.output_nodes, this.hidden_nodes); this.weights_ho.randomize(); this.bias_h = new NNMatrix(this.hidden_nodes, 1); this.bias_o = new NNMatrix(this.output_nodes, 1); }
// feedforward public List <float> predict(List <float> input_list) { NNMatrix inputs = NNMatrix.fromList(input_list); NNMatrix hidden = NNMatrix.multiply(this.weights_ih, inputs); hidden.add(this.bias_h); // activate function hidden.map(activate); NNMatrix output = NNMatrix.multiply(this.weights_ho, hidden); output.add(this.bias_o); output.map(activate); return(output.toList()); }
public NeuralNetwork copy() { int _input_nodes = this.input_nodes; int _hidden_nodes = this.hidden_nodes; int _output_nodes = this.output_nodes; NNMatrix wih = this.weights_ih; NNMatrix who = this.weights_ho; float lr = this.learning_rate; NNMatrix bh = this.bias_h; NNMatrix oh = this.bias_o; NeuralNetwork nn = new NeuralNetwork(_input_nodes, _hidden_nodes, _output_nodes); nn.weights_ih = wih; nn.weights_ho = who; nn.learning_rate = lr; nn.bias_h = bh; nn.bias_o = oh; return(nn); }
public void mutate() { this.weights_ih = NNMatrix.map(this.weights_ih, NNUtils.mutate); this.weights_ho = NNMatrix.map(this.weights_ho, NNUtils.mutate); }