Advertisement
ktv6

Radial.cpp

Dec 25th, 2019
350
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.19 KB | None | 0 0
  1. #include "Radial.h"
  2.  
  3.  
  4. Radial::Radial(point2 NeuronCenter, FILE* studyFile, FILE* gnuplot, double cs) {
  5.     C = NeuronCenter;
  6.     etaInput();
  7.     gpipe = gnuplot;
  8.     get_StudyData(studyFile);
  9.     ClassValue = cs;
  10. }
  11.  
  12. double Radial::TargetFunction(int p) {
  13.     double y, d, tmp=0.;
  14.     register int i;
  15.     for(i=0; i<StudyMassSize; ++i) {
  16.         y = ActivationFunction(StudyMass[i]);
  17.         d = StudyMass[i].outValue;
  18.         tmp += (y - d) * (y - d);
  19.     }
  20.     return 0.5 * tmp;
  21. }
  22.  
  23. double Radial::GradientMethod() {
  24.  
  25. }
  26.  
  27. void Radial::get_StudyData(FILE *studyfile) {
  28.     register int i=0;
  29.     char str[255];
  30.     StudyMassSize=0;
  31.    
  32.     while(fgets(str, 255, studyfile))
  33.         StudyMassSize++;
  34.    
  35.     cout << "Read " << StudyMassSize << " lines from study file" << endl;
  36.  
  37.     StudyMass = new point2[StudyMassSize];
  38.  
  39.     fseek(studyfile, 0, SEEK_SET);
  40.  
  41.     while(fgets(str, 255, studyfile)) {
  42.         sscanf(str, "%lf\t%lf\t%lf\n", &StudyMass[i].x, &StudyMass[i].y, &StudyMass[i].outValue);
  43.         // Norm(&StudyMass[i]);
  44.         i++;
  45.     }
  46.     fclose(studyfile);
  47. }
  48.  
  49. void Radial::pltStudyMass() {
  50.     register int i;
  51.  
  52.     fprintf(gpipe, "unset multiplot\nset multiplot\n");
  53.     for(i=0; i<StudyMassSize; ++i) {
  54.         if(StudyMass[i].outValue < 0.4) {
  55.             fprintf(gpipe, "plot '-' u 1:2 w points ls 8\n");
  56.         }
  57.         if(StudyMass[i].outValue == 0.5) {
  58.             fprintf(gpipe, "plot '-' u 1:2 w points ls 6\n");
  59.         }
  60.         if(StudyMass[i].outValue > 0.6) {
  61.             fprintf(gpipe, "plot '-' u 1:2 w points ls 4\n");
  62.         }
  63.         fprintf(gpipe, "%lf\t%lf\n", StudyMass[i].x, StudyMass[i].y);
  64.        
  65.         fprintf(gpipe, "e\n");    
  66.     }
  67.     fflush(gpipe);
  68. }
  69.  
  70. void Radial::pltCenter() {
  71.     fprintf(gpipe, "plot '-' u 1:2:3 with circles\n");
  72.     fprintf(gpipe, "%f\t%f\t%lf\ne\n", C.x, C.y, 0.5);
  73.  
  74.     fprintf(gpipe, "plot '-' u 1:2 w points lt rgb \"black\"\n");
  75.     fprintf(gpipe, "%f\t%f\ne\n", C.x, C.y);
  76. }
  77.  
  78. void Radial::Norm(point2 *p) {
  79.     double AuxNorm;
  80.     if(p->x != 0 && p->y != 0) {
  81.         AuxNorm = sqrt(p->x * p->x + p->y * p->y);
  82.         p->x /= AuxNorm;
  83.         p->y /= AuxNorm;
  84.     }
  85. }
  86.  
  87. void Radial::set_eta(double newValue) {
  88.     this->eta = newValue;
  89. }
  90.  
  91. void Radial::set_sigma(double newValue) {
  92.     this->sigma = newValue;
  93. }
  94.  
  95.  
  96. void Radial::etaInput() {
  97.     double eta;
  98.     cout << "Введите число в интервале (0, 1)." << endl;
  99.     cout << "Оно будет использовано как коэф-т обучения:" << endl;
  100.     cin >> eta;
  101.     if(eta <= 0 || eta >= 1) {
  102.         cout << "Вы глупец." << endl;
  103.         exit(-2);
  104.     }
  105.     set_eta(eta);
  106. }
  107.  
  108. void Radial::StudyNeuron() {
  109.     register int i, k=0, n;
  110.  
  111.     pltStudyMass();
  112.  
  113.     for(n=0; n < 5; ++n) {
  114.         for(i=0; i<StudyMassSize; i++) {
  115.             if(StudyMass[i].outValue == ClassValue) {
  116.                 // cout << StudyMass[i].outValue << endl;
  117.                 // cout << StudyMass[i].x << " " << StudyMass[i].y << endl;
  118.                 C.moveCenter(StudyMass[i], eta);
  119.                 // fprintf(gpipe, "unset multiplot\n");
  120.                 // fprintf(gpipe, "pause %lf \n", 1);
  121.             }
  122.             // C.printPoint();
  123.             // PlotGreenPoint(i);
  124.         }
  125.         pltCenter();
  126.         // fprintf(gpipe, "pause 1\n");
  127.     }
  128.     fflush(gpipe);
  129. }
  130.  
  131. void Radial::PlotGreenPoint(int PointNum) {
  132.     register int i;
  133.     // fprintf(gpipe, "set multiplot\n");
  134.    
  135.     for(i=0; i<PointNum; ++i) {
  136.         if(StudyMass[i].outValue < 0.4) {
  137.             fprintf(gpipe, "plot '-' u 1:2 w points ls 8\n");
  138.         }
  139.         if(StudyMass[i].outValue == 0.5) {
  140.             fprintf(gpipe, "plot '-' u 1:2 w points ls 6\n");
  141.         }
  142.         if(StudyMass[i].outValue > 0.6) {
  143.             fprintf(gpipe, "plot '-' u 1:2 w points ls 4\n");
  144.         }
  145.         fprintf(gpipe, "%f\t%f\n", StudyMass[i].x, StudyMass[i].y);
  146.        
  147.         fprintf(gpipe, "e\n");
  148.     }
  149.    
  150.     fprintf(gpipe, "plot '-' u 1:2:3 with circles\n");
  151.     fprintf(gpipe, "%f\t%f\t%lf\nend\n", C.x, C.y, 0.5);
  152.  
  153.     fprintf(gpipe, "plot '-' u 1:2 w points lt rgb \"black\"\n");
  154.     fprintf(gpipe, "%f\t%f\nend\n", C.x, C.y);
  155. }
  156.  
  157. double Radial::ActivationFunction(point2 X_k) {
  158.     double nom, den;
  159.     nom = pow(EuclideanDistance(X_k, C), 2);
  160.     den = 2 * pow(sigma, 2);
  161.     return exp(-nom / den);
  162. }
  163.  
  164. double Radial::ActivationFunctionWithSigma(point2 X_k, double newSigma) {
  165.     double nom, den;
  166.     nom = pow(EuclideanDistance(X_k, C), 2);
  167.     den = 2 * pow(newSigma, 2);
  168.     return exp(-nom / den);
  169. }
  170.  
  171. int Radial::Test() {
  172.     double outvalue;
  173.     cout << "x = "; cin >> testPoint.x;
  174.     cout << "y = "; cin >> testPoint.y;
  175.     if(testPoint.x == 0. && testPoint.y == 0.)
  176.         return 0;
  177.     outvalue = ActivationFunction(testPoint);
  178.     if (outvalue >= 0.5) {
  179.         cout << ">= 0.5" << endl;
  180.         fprintf(gpipe, "plot '-' u 1:2 w points lt rgb \"blue\"\n");
  181.     }
  182.     else {
  183.         cout << "< 0.5" << endl;
  184.         fprintf(gpipe, "plot '-' u 1:2 w points lt rgb \"red\"\n");
  185.     }
  186.     fprintf(gpipe, "%lf\t%lf\n", testPoint.x, testPoint.y);
  187.     fprintf(gpipe, "end\n");
  188.     return 1;
  189. }
  190.  
  191. void Radial::StudySigmaOffline() {
  192.     double etta = 0.1;
  193.     int goodIterCount = 0;
  194.     register int i;
  195.     bool flag = true;
  196.  
  197.     fprintf(gpipe, "unset multiplot\nset multiplot\n");
  198.     pltStudyMass();
  199.     fprintf(gpipe, "set parametric\n");
  200.     fprintf(gpipe, "plot [0:2*pi] %lf*sin(t)+%lf,%lf*cos(t)+%lf lw 4 notitle\n", getR(0.55), C.x, getR(0.55), C.y);
  201.     fprintf(gpipe, "unset parametric\n");
  202.     fprintf(gpipe, "plot '-' w p lc 'red' pt %d lw 3\n", 4);
  203.     fprintf(gpipe, "%lf %lf\n", C.x, C.y);
  204.     fprintf(gpipe, "e\n");
  205.     fprintf(gpipe, "pause 0.5\n");
  206.     fflush(gpipe);
  207.  
  208.     do {
  209.         double gradE = 0.;
  210.         for(i=0; i<StudyMassSize; ++i) {
  211.             // if(StudyMass[i].outValue == ClassValue) {
  212.             double f = ActivationFunction(StudyMass[i]);            
  213.             gradE += (f - StudyMass[i].outValue) * f * pow(EuclideanDistance(StudyMass[i], C), 2) / pow(sigma, 3);
  214.             // }
  215.         }
  216.         double newSigma = sigma - etta * gradE;
  217.  
  218.         double oldE = 0.;
  219.         for(int j=0; j<StudyMassSize; ++j) {
  220.             // if(StudyMass[j].outValue == ClassValue) {
  221.             double f = ActivationFunction(StudyMass[j]);
  222.             oldE += pow((f - StudyMass[j].outValue), 2);
  223.             // }
  224.         }
  225.         oldE /= 2.;
  226.  
  227.         double newE = 0.;
  228.         for(int j=0; j<StudyMassSize; ++j) {
  229.             // if(StudyMass[j].outValue == ClassValue) {
  230.             double f = ActivationFunctionWithSigma(StudyMass[j], newSigma);
  231.             newE += pow((f - StudyMass[j].outValue), 2);
  232.             // }
  233.         }      
  234.         newE /= 2.;
  235.  
  236.         double deltaE = oldE - newE;
  237.         if(deltaE < 0) {
  238.             etta /= 2.;
  239.             goodIterCount = 0;
  240.         }
  241.         else {
  242.             goodIterCount++;
  243.             set_sigma(newSigma);
  244.             if(deltaE < 1e-3)
  245.                 flag = false;
  246.             if(goodIterCount == 4) {
  247.                 etta *= 2;
  248.                 goodIterCount = 0;
  249.             }
  250.  
  251.             fprintf(gpipe, "unset multiplot\nset multiplot\n");
  252.             pltStudyMass();
  253.             fprintf(gpipe, "set parametric\n");
  254.             fprintf(gpipe, "plot [0:2*pi] %lf*sin(t)+%lf,%lf*cos(t)+%lf lw 4 notitle\n", getR(0.55), C.x, getR(0.55), C.y);
  255.             fprintf(gpipe, "unset parametric\n");
  256.             fprintf(gpipe, "plot '-' w p lc 'red' pt %d lw 3\n", 4);
  257.             fprintf(gpipe, "%lf %lf\n", C.x, C.y);
  258.             fprintf(gpipe, "e\n");
  259.             fprintf(gpipe, "pause 1\n");
  260.             fflush(gpipe);
  261.         }
  262.     } while(flag);
  263.     cout << "Sigma study finnished, Sigma = " << sigma << endl;
  264. }
  265.  
  266. double Radial::getR(double val) {
  267.     return sigma * sqrt(-2.0 * log(val));
  268. }
  269.  
  270. int main(int argc, char* argv[]) {
  271.     point2 NeuronCenter(0., 0.);
  272.     if(argc != 2) {
  273.         HelpMessage();
  274.         return -1;
  275.     }
  276.     FILE *studyFile = fopen(argv[1], "r");
  277.     if(studyFile == NULL) {
  278.         cout << "Can't read file " << argv[1] << endl;
  279.         return -2;
  280.     }
  281.    
  282.     FILE *gpipe = popen("gnuplot -persist -geometry 700x700", "w");
  283.     if(!gpipe) {
  284.         cout << "Can't open gnuplot" << endl;
  285.         return -3;
  286.     }
  287.  
  288.     gnuplotInit(gpipe);
  289.  
  290.     double cv1 = 0., cv2 = 0.;
  291.  
  292.     Radial MyRadial1(NeuronCenter, studyFile, gpipe, cv1);
  293.     MyRadial1.StudyNeuron();
  294.     MyRadial1.StudySigmaOffline();
  295.  
  296.     // MyRadial1.StudySigmaOffline();
  297.  
  298.     // Radial MyRadial2(NeuronCenter, studyFile, gpipe, cv2);
  299.     // MyRadial2.StudyNeuron();
  300.  
  301.     // cout << "Выполнено обучение нейрона на выборке из входного файла" << endl;
  302.    
  303.     // char ch;
  304.     // cout << "Начать тестирование? (y/n)" << endl;
  305.     // cin >> ch;
  306.  
  307.     // if(ch != 'y' && ch != 'Y')
  308.     //     return 0;
  309.    
  310.     // cout << "Начало тестирования" << endl;
  311.  
  312.     // do
  313.     //     fflush(gpipe);
  314.     // while(MyRadial1.Test());
  315.     fprintf(gpipe, "exit\n");
  316.     fflush(gpipe);
  317.     pclose(gpipe);
  318.     return 0;
  319. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement