Reconocimiento de una serie temporal en una imagen basada en una red neuronal

Buen día, lugareños.





Hace tiempo que quería publicar algo adecuado en Habr, pero no tenía ni idea.





Y luego me acordé de uno de mis proyectos, que se hundió en el olvido junto con el repositorio en el que estaba grabado. Este es un modelo simplificado de mi trabajo final, cuando lo hice, el conocimiento estaba en mi cabeza. Y ahora tienes que recordar y hacer todo de nuevo.





En general, este proyecto tendrá dos imágenes diferentes que el programa reconocerá. Ambas imágenes se generan mediante programación utilizando el marco qt y c ++.





En total, unas 300 líneas de código.





Aquí están los datos de la imagen:





Y segundo:





Tienen un tamaño de 400 por 300 píxeles.





, , , , , 2 , , .





?





-, "y" - , "x" (400 ). , " " , .





2 :





w (t + 1) = w (t) -k * | x ​​[i] -w (t) |

k - , x[i] - "y" , w(t)- ,w(t+1) - . 2 , , ( x->f(x)->x).





:





.





:





k = 0,75 2- :









, , .





k , 10^-6 .





:





sum1 sum2 - "y" - ( )





v-v - V-, v 2533.56, w-v 39032.4 . : w w . .





10 :





, .





Pero si se dibuja una línea recta en el centro horizontalmente, entonces reconoce ambas clases mejor que las neuronas con errores del primer tipo:





El siguiente es el código del programa main.cpp:





#include <iostream>
#include <QtWidgets/QApplication>
#include "MainWindow.h"


int main(int argc,char*argv[])
{
    QApplication a(argc, argv);
    QWidget qw;
    MainWindow mw(&qw);
    mw.show();
    mw.CreateImage("");
    mw.CreateImage2("");
    mw.OpenImage("");
    mw.OpenImage2("");
    return a.exec();
}

      
      



Neuron.h:





#pragma once
#include <ctime>
#include <iostream>
#include <vector>
class Neuron
{
public:
	std::vector<double> x,  y, x0;
	double error;
	Neuron(std::vector<double> x, int length, int level);
	int level, length, min_, max_;
	std::vector<double>  Send();
	void Lerning(int steps);
	double Thinking(std::vector<double> xx);

	std::vector<double> SendW();

};
      
      



Neuron.cpp:





#include "Neuron.h"

Neuron::Neuron(std::vector<double> x,int length,int level)
{
	this->x = x;
	this->length = length;
	if (level == 2)
	{
		srand(time(NULL));
		min_ = 0;
		max_ = 300;
		for (size_t i = 0; i < length; i++)
		{
			x0.push_back(min_ + rand() % (max_ - min_ + 1)); 
			y.push_back(x0[i]);
			//std::cout << x0[i] << std::endl;
		}
	}
	this->level = level;
	this->error = 0.0;
}

std::vector<double> Neuron::Send()
{
	if (level == 1)
		return this->x;
	else
		return this->y;
}
std::vector<double> Neuron::SendW()
{
		return this->x0;
}
void Neuron::Lerning(int steps)
{
	float k = 0.75;
	for (size_t j = 0; j < steps; j++)
	{
		for (size_t i = 0; i < length; i++)
		{
			x0[i] = x0[i] + k* (x[i]-x0[i]);
		}
	}
}
double Neuron::Thinking(std::vector<double> xx)
{
	error = 0.0;
	for (size_t i = 0; i < length; i++)
	{
		y[i] = abs(xx[i] - x0[i]);
		error += y[i];
	}
	return error;
}

      
      



NeuralNet.h





#pragma once
#include "Neuron.h"
//#include <vector>
class NeuralNet
{
public:
	std::vector<Neuron*> l1,l2;
	void InitNeurons(std::vector<double> x, int length);
	void LearnNeurons(int steps, int i);
	double TestNeurons(int i, std::vector<double> xx);
};

      
      



NeuralNet.cpp





#include "NeuralNet.h"

void NeuralNet::InitNeurons(std::vector<double> x,int length)
{
	l1.push_back(new Neuron(x,length,1));
}
void NeuralNet::LearnNeurons(int steps,int i)
{
		l2.push_back(new Neuron(l1[i]->Send(), l1[i]->length, 2));
		l2[i]->Lerning(steps);
}
double NeuralNet::TestNeurons(int i, std::vector<double> xx)
{
	double res = 0.0 ;
	res = l2[i]->Thinking(xx);
	return res;
}

      
      



MainWindow.h





#pragma once
#include <QtWidgets/qmainwindow.h>
#include <QtGui/qpicture.h>
#include <QtGui/qimage.h>
#include <QtGui/qpainter.h>
#include <QtCore/qdebug.h> 
#include <vector>
#include <iostream>
#include <fstream> //   
#include <iomanip> 
#include "NeuralNet.h"
#pragma comment(lib,"Qt5Core.lib")
#pragma comment(lib,"Qt5Widgets.lib")
#pragma comment(lib,"Qt5Gui.lib")

namespace Ui {
    class MainWindow;
}
//Q_OBJECT
class MainWindow : public QMainWindow
{
    //Q_OBJECT
public:
    explicit MainWindow(QWidget* parent = 0);
    void CreateImage(QString path);
    void CreateImage2(QString path);
    void OpenImage(QString path);
    void OpenImage2(QString path);
    std::vector<double> x1, x2, zeros1, zeros2;
    QImage* image_t1, * image_t2 ;
    NeuralNet net;
    // ~MainWindow();
protected:
    void paintEvent(QPaintEvent*); //   
    
private:
    Ui::MainWindow* ui;
    
};
      
      



MainWindow.cpp





#include "MainWindow.h"
MainWindow::MainWindow(QWidget* parent)
    : QMainWindow(parent)
{
    setWindowTitle(tr("Neural"));
    setGeometry(0, 0, 1000, 700);
}
void MainWindow::paintEvent(QPaintEvent*)
{
    QImage img("testImage.png"); //  
    QPainter painter(this); //   painter,   
    painter.drawImage(0, 0, img.scaled(this->size())); //     0,0     
}

void MainWindow::CreateImage(QString path)
{
    QImage image(QSize(400, 300), QImage::Format_RGB32);
    QPainter painter(&image);
    painter.fillRect(QRectF(0, 0, 400, 300), Qt::white);
    painter.setPen(QPen(Qt::black));
    painter.drawLine(0, 0, image.width() / 2, image.height());
    painter.drawLine(image.width() / 2, image.height(), image.width(), 0);

    image.save("testImage.png");
}
void MainWindow::CreateImage2(QString path)
{
    QImage image(QSize(400, 300), QImage::Format_RGB32);
    QPainter painter(&image);
    painter.fillRect(QRectF(0, 0, 400, 300), Qt::white);
    painter.setPen(QPen(Qt::black));
    painter.drawLine(0, 0, image.width() / 4, image.height());
    painter.drawLine(image.width() / 4, image.height() , image.width() / 2, 0);
    painter.drawLine(image.width() / 2, 0, 3 * image.width() / 4, image.height());
    painter.drawLine(3*image.width() / 4, image.height(), image.width() , 0);

    image.save("testImage2.png");
}

void MainWindow::OpenImage(QString path)
{
    image_t1 = new QImage("testImage.png");
    QPoint qp;
    std::ofstream fout("data.txt", std::ios_base::out | std::ios_base::trunc);

    for (int i = 0; i < image_t1->width(); i++)
    {
        for (int j = 0; j < image_t1->height(); j++)
        {
            qp.setX(i);
            qp.setY(j);
            if (image_t1->pixel(qp) != 4294967295/* 4278190080*/)
            {
                x1.push_back(j);
                zeros1.push_back(abs(150-j));
                //qDebug() << j << " ";
                fout << j<< std::endl;
                break;
            }
        }

    }
    qDebug() <<"size:"<< x1.size() << " ";
    int sum = 0;
    for (int j = 0; j < zeros1.size(); j++)
    {
        sum += zeros1[j];
    }
    qDebug() << "sum1=" << sum << " ";
    fout.close();
    
    net.InitNeurons(x1, x1.size());
    net.LearnNeurons(10,0);
    //net.TestNeurons(0);
    for (size_t i = 0; i < net.l2[0]->SendW().size(); i++)
    {
        qp.setX(i);
        qp.setY(int(net.l2[0]->SendW()[i]));
        image_t1->setPixel(qp, Qt::red);
    }
    image_t1->save("testImage1-1-1-1-000000.png");
    
}
void MainWindow::OpenImage2(QString path)
{
    image_t2 = new QImage("testImage2.png");
    QPoint qp;
    std::ofstream fout("data.txt", std::ios_base::out | std::ios_base::trunc);

    for (int i = 0; i < image_t2->width(); i++)
    {
        for (int j = 0; j < image_t2->height(); j++)
        {
            qp.setX(i);
            qp.setY(j);
            if (image_t2->pixel(qp) != 4294967295/* 4278190080*/)
            {
                x2.push_back(j);
                fout << j << std::endl;
                zeros2.push_back(abs(150 - j));
                //qDebug() << j << " ";
                break;
            }
        }

    }
    qDebug() << "size:" << x2.size() << " ";
    int sum = 0;
    for (int j = 0; j < zeros2.size(); j++)
    {
        sum += zeros2[j];
    }
    qDebug()<<"sum2=" << sum << " ";
    fout.close();
    
    net.InitNeurons(x2, x2.size());
    net.LearnNeurons(10,1);
    qDebug() <<"v - v"<< net.TestNeurons(0, x1);
    qDebug() <<"v - w"<< net.TestNeurons(0, x2);
    qDebug() <<"w - v"<< net.TestNeurons(1, x1);
    qDebug() <<"w - w"<< net.TestNeurons(1, x2);
    for (size_t i = 0; i < net.l2[1]->SendW().size(); i++)
    {
        qp.setX(i);
        qp.setY(int(net.l2[1]->SendW()[i]));
        //qDebug() << int(net.l2[1]->SendW()[i]) << " ";// std::endl;
        image_t2->setPixel(qp, Qt::red);
    }
    image_t2->save("testImage2-2-2-2-000000.png");
    
}

      
      



¡Gracias por la atención!








All Articles