Reconnaissance d'une série temporelle dans une image basée sur un réseau de neurones

Bonne journée, les habitants.





J'ai longtemps voulu publier quelque chose de convenable sur Habr, mais je n'avais aucune idée.





Et puis je me suis souvenu d'un de mes projets, qui est tombé dans l'oubli avec le référentiel sur lequel il était enregistré. Ceci est un modèle simplifié de mon mémoire, quand je l'ai fait, la connaissance était dans ma tête. Et maintenant, vous devez vous souvenir et tout recommencer.





En général, ce projet aura deux images différentes que le programme reconnaîtra. Les deux images sont générées par programme à l'aide du framework qt et c ++.





Au total, environ 300 lignes de code.





Voici les données d'image:





Et deuxieme:





Ils ont une taille de 400 par 300 pixels.





, , , , , 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 :





, .





Mais si une ligne droite est tracée au centre horizontalement, alors elle reconnaît mieux les deux classes que les neurones avec des erreurs du 1er type:





Vient ensuite le code du programme 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");
    
}

      
      



Merci pour l'attention!








All Articles