Guten Tag, Einheimische.
Ich wollte schon lange etwas Passendes auf Habr posten, aber es gab keine Ahnung.
Und dann erinnerte ich mich an eines meiner Projekte, das zusammen mit dem Repository, in dem es aufgenommen wurde, in Vergessenheit geriet. Dies ist ein vereinfachtes Modell meiner Hausarbeit. Als ich es tat, war das Wissen in meinem Kopf. Und jetzt muss man sich erinnern und alles neu machen.
Im Allgemeinen enthält dieses Projekt zwei verschiedene Bilder, die das Programm erkennt. Beide Bilder werden programmgesteuert mit dem qt- und c ++ - Framework generiert.
Insgesamt ca. 300 Codezeilen.
Hier sind die Bilddaten:
Und zweitens:
Sie sind 400 x 300 Pixel groß.
, , , , , 2 , , .
?
-, "y" - , "x" (400 ). , " " , .
2 :
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 :
, .
Wenn jedoch eine gerade Linie horizontal in der Mitte gezeichnet wird, erkennt sie beide Klassen besser als Neuronen mit Fehlern der ersten Art:
Als nächstes folgt der Programmcode 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");
}
Vielen Dank für Ihre Aufmerksamkeit!