Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "Radial.h"
- Radial::Radial(point2 NeuronCenter, FILE* studyFile, FILE* gnuplot, double cs) {
- C = NeuronCenter;
- etaInput();
- gpipe = gnuplot;
- get_StudyData(studyFile);
- ClassValue = cs;
- }
- double Radial::TargetFunction(int p) {
- double y, d, tmp=0.;
- register int i;
- for(i=0; i<StudyMassSize; ++i) {
- y = ActivationFunction(StudyMass[i]);
- d = StudyMass[i].outValue;
- tmp += (y - d) * (y - d);
- }
- return 0.5 * tmp;
- }
- double Radial::GradientMethod() {
- }
- void Radial::get_StudyData(FILE *studyfile) {
- register int i=0;
- char str[255];
- StudyMassSize=0;
- while(fgets(str, 255, studyfile))
- StudyMassSize++;
- cout << "Read " << StudyMassSize << " lines from study file" << endl;
- StudyMass = new point2[StudyMassSize];
- fseek(studyfile, 0, SEEK_SET);
- while(fgets(str, 255, studyfile)) {
- sscanf(str, "%lf\t%lf\t%lf\n", &StudyMass[i].x, &StudyMass[i].y, &StudyMass[i].outValue);
- // Norm(&StudyMass[i]);
- i++;
- }
- fclose(studyfile);
- }
- void Radial::pltStudyMass() {
- register int i;
- fprintf(gpipe, "unset multiplot\nset multiplot\n");
- for(i=0; i<StudyMassSize; ++i) {
- if(StudyMass[i].outValue < 0.4) {
- fprintf(gpipe, "plot '-' u 1:2 w points ls 8\n");
- }
- if(StudyMass[i].outValue == 0.5) {
- fprintf(gpipe, "plot '-' u 1:2 w points ls 6\n");
- }
- if(StudyMass[i].outValue > 0.6) {
- fprintf(gpipe, "plot '-' u 1:2 w points ls 4\n");
- }
- fprintf(gpipe, "%lf\t%lf\n", StudyMass[i].x, StudyMass[i].y);
- fprintf(gpipe, "e\n");
- }
- fflush(gpipe);
- }
- void Radial::pltCenter() {
- fprintf(gpipe, "plot '-' u 1:2:3 with circles\n");
- fprintf(gpipe, "%f\t%f\t%lf\ne\n", C.x, C.y, 0.5);
- fprintf(gpipe, "plot '-' u 1:2 w points lt rgb \"black\"\n");
- fprintf(gpipe, "%f\t%f\ne\n", C.x, C.y);
- }
- void Radial::Norm(point2 *p) {
- double AuxNorm;
- if(p->x != 0 && p->y != 0) {
- AuxNorm = sqrt(p->x * p->x + p->y * p->y);
- p->x /= AuxNorm;
- p->y /= AuxNorm;
- }
- }
- void Radial::set_eta(double newValue) {
- this->eta = newValue;
- }
- void Radial::set_sigma(double newValue) {
- this->sigma = newValue;
- }
- void Radial::etaInput() {
- double eta;
- cout << "Введите число в интервале (0, 1)." << endl;
- cout << "Оно будет использовано как коэф-т обучения:" << endl;
- cin >> eta;
- if(eta <= 0 || eta >= 1) {
- cout << "Вы глупец." << endl;
- exit(-2);
- }
- set_eta(eta);
- }
- void Radial::StudyNeuron() {
- register int i, k=0, n;
- pltStudyMass();
- for(n=0; n < 5; ++n) {
- for(i=0; i<StudyMassSize; i++) {
- if(StudyMass[i].outValue == ClassValue) {
- // cout << StudyMass[i].outValue << endl;
- // cout << StudyMass[i].x << " " << StudyMass[i].y << endl;
- C.moveCenter(StudyMass[i], eta);
- // fprintf(gpipe, "unset multiplot\n");
- // fprintf(gpipe, "pause %lf \n", 1);
- }
- // C.printPoint();
- // PlotGreenPoint(i);
- }
- pltCenter();
- // fprintf(gpipe, "pause 1\n");
- }
- fflush(gpipe);
- }
- void Radial::PlotGreenPoint(int PointNum) {
- register int i;
- // fprintf(gpipe, "set multiplot\n");
- for(i=0; i<PointNum; ++i) {
- if(StudyMass[i].outValue < 0.4) {
- fprintf(gpipe, "plot '-' u 1:2 w points ls 8\n");
- }
- if(StudyMass[i].outValue == 0.5) {
- fprintf(gpipe, "plot '-' u 1:2 w points ls 6\n");
- }
- if(StudyMass[i].outValue > 0.6) {
- fprintf(gpipe, "plot '-' u 1:2 w points ls 4\n");
- }
- fprintf(gpipe, "%f\t%f\n", StudyMass[i].x, StudyMass[i].y);
- fprintf(gpipe, "e\n");
- }
- fprintf(gpipe, "plot '-' u 1:2:3 with circles\n");
- fprintf(gpipe, "%f\t%f\t%lf\nend\n", C.x, C.y, 0.5);
- fprintf(gpipe, "plot '-' u 1:2 w points lt rgb \"black\"\n");
- fprintf(gpipe, "%f\t%f\nend\n", C.x, C.y);
- }
- double Radial::ActivationFunction(point2 X_k) {
- double nom, den;
- nom = pow(EuclideanDistance(X_k, C), 2);
- den = 2 * pow(sigma, 2);
- return exp(-nom / den);
- }
- double Radial::ActivationFunctionWithSigma(point2 X_k, double newSigma) {
- double nom, den;
- nom = pow(EuclideanDistance(X_k, C), 2);
- den = 2 * pow(newSigma, 2);
- return exp(-nom / den);
- }
- int Radial::Test() {
- double outvalue;
- cout << "x = "; cin >> testPoint.x;
- cout << "y = "; cin >> testPoint.y;
- if(testPoint.x == 0. && testPoint.y == 0.)
- return 0;
- outvalue = ActivationFunction(testPoint);
- if (outvalue >= 0.5) {
- cout << ">= 0.5" << endl;
- fprintf(gpipe, "plot '-' u 1:2 w points lt rgb \"blue\"\n");
- }
- else {
- cout << "< 0.5" << endl;
- fprintf(gpipe, "plot '-' u 1:2 w points lt rgb \"red\"\n");
- }
- fprintf(gpipe, "%lf\t%lf\n", testPoint.x, testPoint.y);
- fprintf(gpipe, "end\n");
- return 1;
- }
- void Radial::StudySigmaOffline() {
- double etta = 0.1;
- int goodIterCount = 0;
- register int i;
- bool flag = true;
- fprintf(gpipe, "unset multiplot\nset multiplot\n");
- pltStudyMass();
- fprintf(gpipe, "set parametric\n");
- 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);
- fprintf(gpipe, "unset parametric\n");
- fprintf(gpipe, "plot '-' w p lc 'red' pt %d lw 3\n", 4);
- fprintf(gpipe, "%lf %lf\n", C.x, C.y);
- fprintf(gpipe, "e\n");
- fprintf(gpipe, "pause 0.5\n");
- fflush(gpipe);
- do {
- double gradE = 0.;
- for(i=0; i<StudyMassSize; ++i) {
- // if(StudyMass[i].outValue == ClassValue) {
- double f = ActivationFunction(StudyMass[i]);
- gradE += (f - StudyMass[i].outValue) * f * pow(EuclideanDistance(StudyMass[i], C), 2) / pow(sigma, 3);
- // }
- }
- double newSigma = sigma - etta * gradE;
- double oldE = 0.;
- for(int j=0; j<StudyMassSize; ++j) {
- // if(StudyMass[j].outValue == ClassValue) {
- double f = ActivationFunction(StudyMass[j]);
- oldE += pow((f - StudyMass[j].outValue), 2);
- // }
- }
- oldE /= 2.;
- double newE = 0.;
- for(int j=0; j<StudyMassSize; ++j) {
- // if(StudyMass[j].outValue == ClassValue) {
- double f = ActivationFunctionWithSigma(StudyMass[j], newSigma);
- newE += pow((f - StudyMass[j].outValue), 2);
- // }
- }
- newE /= 2.;
- double deltaE = oldE - newE;
- if(deltaE < 0) {
- etta /= 2.;
- goodIterCount = 0;
- }
- else {
- goodIterCount++;
- set_sigma(newSigma);
- if(deltaE < 1e-3)
- flag = false;
- if(goodIterCount == 4) {
- etta *= 2;
- goodIterCount = 0;
- }
- fprintf(gpipe, "unset multiplot\nset multiplot\n");
- pltStudyMass();
- fprintf(gpipe, "set parametric\n");
- 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);
- fprintf(gpipe, "unset parametric\n");
- fprintf(gpipe, "plot '-' w p lc 'red' pt %d lw 3\n", 4);
- fprintf(gpipe, "%lf %lf\n", C.x, C.y);
- fprintf(gpipe, "e\n");
- fprintf(gpipe, "pause 1\n");
- fflush(gpipe);
- }
- } while(flag);
- cout << "Sigma study finnished, Sigma = " << sigma << endl;
- }
- double Radial::getR(double val) {
- return sigma * sqrt(-2.0 * log(val));
- }
- int main(int argc, char* argv[]) {
- point2 NeuronCenter(0., 0.);
- if(argc != 2) {
- HelpMessage();
- return -1;
- }
- FILE *studyFile = fopen(argv[1], "r");
- if(studyFile == NULL) {
- cout << "Can't read file " << argv[1] << endl;
- return -2;
- }
- FILE *gpipe = popen("gnuplot -persist -geometry 700x700", "w");
- if(!gpipe) {
- cout << "Can't open gnuplot" << endl;
- return -3;
- }
- gnuplotInit(gpipe);
- double cv1 = 0., cv2 = 0.;
- Radial MyRadial1(NeuronCenter, studyFile, gpipe, cv1);
- MyRadial1.StudyNeuron();
- MyRadial1.StudySigmaOffline();
- // MyRadial1.StudySigmaOffline();
- // Radial MyRadial2(NeuronCenter, studyFile, gpipe, cv2);
- // MyRadial2.StudyNeuron();
- // cout << "Выполнено обучение нейрона на выборке из входного файла" << endl;
- // char ch;
- // cout << "Начать тестирование? (y/n)" << endl;
- // cin >> ch;
- // if(ch != 'y' && ch != 'Y')
- // return 0;
- // cout << "Начало тестирования" << endl;
- // do
- // fflush(gpipe);
- // while(MyRadial1.Test());
- fprintf(gpipe, "exit\n");
- fflush(gpipe);
- pclose(gpipe);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement