You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

ann.cpp 3.3 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. #include <iostream>
  2. #include <ctime>
  3. #include "../../root/include/vectmath.h"
  4. #include "../../root/include/node.h"
  5. typedef std::vector<Node> Vector;
  6. typedef std::vector<Vector> Matrix;
  7. Node random_number(){
  8. return rand()/(double)RAND_MAX;
  9. }
  10. Node tan_h(Node& x){
  11. return (1-exp(-2*x))/(1+exp(-2*x));
  12. }
  13. Node mean_square_error(Vector& y_true, Vector& y_pred){
  14. Node loss;
  15. for(size_t i=0 ; i<y_true.size() ; i++){
  16. loss += pow(y_true[i]-y_pred[i], 2);
  17. }
  18. return loss;
  19. }
  20. struct Layer {
  21. Matrix weights;
  22. Matrix bias;
  23. Node (*activation)(Node&);
  24. int input_shape;
  25. int output_shape;
  26. Layer(int input, int output, Node (*activation)(Node&)){
  27. this->activation = activation;
  28. this->input_shape = input;
  29. this->output_shape = output;
  30. weights.resize(input, Vector(output));
  31. bias.resize(1, Vector(output));
  32. random_number >> weights;
  33. random_number >> bias;
  34. }
  35. Matrix forward(Matrix& previous){
  36. Matrix output = dot(previous, weights) + bias;
  37. output = activation >> output;
  38. return output;
  39. }
  40. void backward(Node& loss, const float& learning_rate){
  41. weights -= learning_rate*loss.gradient(weights);
  42. bias -= learning_rate*loss.gradient(bias);
  43. }
  44. };
  45. struct Network {
  46. std::vector<Layer> layers;
  47. int input_shape;
  48. Graph* graph;
  49. Network(){
  50. graph = Graph::getInstance();
  51. }
  52. void input_layer(int input_shape){
  53. this->input_shape = input_shape;
  54. }
  55. void add(int output_shape, Node (*activation)(Node&)){
  56. int input = layers.empty()?input_shape:layers.back().output_shape;
  57. layers.push_back(Layer(input, output_shape, activation));
  58. }
  59. Matrix run(Matrix& input){
  60. Matrix output(input.size());
  61. for(size_t j=0 ; j<input.size() ; j++){
  62. Matrix out = {input[j]};
  63. for(auto& lay : layers){
  64. out = lay.forward(out);
  65. }
  66. output[j] = out[0];
  67. }
  68. return output;
  69. }
  70. void fit(Matrix& input, Matrix& output, Node (*loss_function)(Vector&, Vector&), int epochs, float learning_rate){
  71. int p=0;
  72. for(size_t i=0 ; i<epochs ; i++){
  73. std::cout << "\r" << i+1 << "/" << epochs;
  74. for(size_t j=0 ; j<input.size() ; j++){
  75. // compute input
  76. Matrix out = {input[j]};
  77. for(auto& lay : layers){
  78. out = lay.forward(out);
  79. }
  80. // compute loss
  81. Node loss = loss_function(output[j], out[0]);
  82. // update parameters
  83. for(auto& lay : layers){
  84. lay.backward(loss, learning_rate);
  85. }
  86. graph->new_recording();
  87. }
  88. }
  89. std::cout << std::endl;
  90. }
  91. };
  92. int main(int argc, char const *argv[]) {
  93. srand(time(NULL));
  94. Matrix input = {{0,0},{0,1},{1,0},{1,1}};
  95. Matrix output = {{0},{1},{1},{0}};
  96. Network network;
  97. network.input_layer(2);
  98. network.add(3, tan_h);
  99. network.add(1, tan_h);
  100. network.fit(input, output, mean_square_error, 500, 0.1);
  101. Matrix pred = network.run(input);
  102. std::cout << pred << std::endl;
  103. return 0;
  104. }

Edge : 一个开源的科学计算引擎

Contributors (1)