#include <iostream>
#include <fstream>
#include <random>
using namespace std;
#include <Windows.h>
#include <windowsx.h>
double LEARNING_RATE;
#include "Neuron.h"
#include "Layer.h"
#include "Connections.h"
struct Instance
{
unsigned char image[28 * 28];
unsigned char label;
void display()const
{
for (unsigned i = 0; i < 28; ++i)
{
for (unsigned j = 0; j < 28; ++j)
if (image[28 * i + j] > 0b10000000ui8)
cout << "▇";
else
cout << ' ';
cout << '\n';
}
cout << (int)label << endl;
}
}trainingSet[60000], testSet[10000];
void readFile(const char* const& imagePath, const char* const& labelPath, Instance* const& instances, const unsigned& n)
{
ifstream imageFile(imagePath, ios::in | ios::binary);
ifstream lableFile(labelPath, ios::in | ios::binary);
imageFile.seekg(16);
lableFile.seekg(8);
for (unsigned i = 0; i < n; ++i)
{
imageFile.read((char*)instances[i].image, 28 * 28);
lableFile.get((char&)instances[i].label);
}
}
struct functions
{
static inline double 激活函数(double const& x)
{
return tanh(x);
}
static inline double 激活函数的导数(double const& x)
{
register double y = tanh(x);
return 1 - y * y;
}
};
unsigned number;
Layer* pLayer;
Connections* pConnections;
void menu(unsigned& n)
{
system("cls");
cout << "================================================================\n";
cout << " 1 - 学习 2 - 测试\n";
cout << " 3 - 手写识别 0 - 结束\n";
cin >> n;
}
void 学习()
{
unsigned begin, end, batch;
cout << "起始序号(e.g.0): ";
cin >> begin;
cout << "终止序号(e.g.60000): ";
cin >> end;
cout << "每组个数(e.g.1): ";
cin >> batch;
cout << "学习速率(e.g.0.01): ";
cin >> LEARNING_RATE;
cout << " ]\r[";
unsigned i = 0;
unsigned progress = 0;
unsigned const step = (end - begin) / 33 + 1;
for (; begin < end; ++begin)
{
if (++progress == step)
{
progress = 0;
cout << '#';
}
pLayer[0].setOutput(trainingSet[begin].image);
for (unsigned j = 0; j < number; ++j)
{
pConnections[j].transmit();
pLayer[j + 1].calculate<functions>();
}
pLayer[number].expectedOutput(trainingSet[begin].label);
for (unsigned j = number - 1; j > 0; --j)
{
pLayer[j + 1].adjust<functions>();
pConnections[j].adjust();
pLayer[j].clearOutput();
pConnections[j].pass();
}
pLayer[1].adjust<functions>();
pConnections[0].adjust();
for (unsigned j = 1; j < number + 1; ++j)
pLayer[j].clearInput();
if (++i == batch)
{
i = 0;
for (unsigned j = 0; j < number; ++j)
{
pConnections[j].learn(batch, LEARNING_RATE);
pLayer[j + 1].learn(batch, LEARNING_RATE);
}
}
}
}
void 测试()
{
cout << " ]\r[";
unsigned sum = 0;
unsigned progress = 0;
unsigned const step = 10000 / 33 + 1;
for (unsigned i = 0; i < 10000; ++i)
{
if (++progress == step)
{
progress = 0;
cout << '#';
}
pLayer[0].setOutput(testSet[i].image);
for (unsigned j = 0; j < number; ++j)
{
pConnections[j].transmit();
pLayer[j + 1].calculate<functions>();
}
unsigned iMax;
double max = -1;
unsigned j = 0;
for (Neuron const& a : pLayer[number])
{
if (a.output() > max)
{
max = a.output();
iMax = j;
}
++j;
}
if (iMax == testSet[i].label)
++sum;
for (unsigned j = 1; j < number + 1; ++j)
pLayer[j].clearInput();
}
cout << "\n正确率" << sum << "/10000\n";
}
LRESULT CALLBACK WndProc(HWND hWindow, UINT message, WPARAM wParam, LPARAM lParam)
{
static HPEN hPen;
static HBRUSH hBrush[17];
static unsigned char pixels[28 * 28];
bool (*changeColor)(int const& x, int const& y, int const& X, int const& Y) =
[](int const& x, int const& y, int const& X, int const& Y)->bool
{
float const dx = (X * 20 + 10 - x) / 20.f;
float const dy = (Y * 20 + 10 - y) / 20.f;
float const distance = dx * dx + dy * dy;
if (distance >= 2.25f)
return false;
unsigned char const color = distance <= 1 ? 0xffui8 : unsigned(-0xff * 0.8f * (distance - 2.25f));
if (pixels[Y * 28 + X] < color)
{
pixels[Y * 28 + X] = color;
return true;
}
return false;
};
void (*paintColor)(unsigned const& X, unsigned const& Y, HWND const& hWindow) =
[](unsigned const& X, unsigned const& Y, HWND const& hWindow)
{
HDC hdc = GetDC(hWindow);
SelectObject(hdc, hPen);
SelectObject(hdc, hBrush[16 - (pixels[Y * 28 + X] + 8) / 16]);
Rectangle(hdc, X * 20, Y * 20, (X + 1) * 20, (Y + 1) * 20);
ReleaseDC(hWindow, hdc);
};
switch (message)
{
case WM_CREATE:
hPen = CreatePen(PS_SOLID, 0, 0x00FFFFFFui32);
for (unsigned i = 0; i < 16; ++i)
hBrush[i] = CreateSolidBrush(0x00101010ui32 * i);
hBrush[16] = CreateSolidBrush(0x00FFFFFFui32);
memset(pixels, 0, 28 * 28);
return 0;
case WM_DESTROY:
DeleteObject(hPen);
for (unsigned i = 0; i < 17; ++i)
DeleteObject(hBrush[i]);
PostQuitMessage(0);
return 0;
case WM_LBUTTONDOWN:
{
HDC hdc = GetDC(hWindow);
SelectObject(hdc, hPen);
for (int Y = 0; Y < 28; ++Y)
for (int X = 0; X < 28; ++X)
{
SelectObject(hdc, hBrush[16 - (pixels[Y * 28 + X] + 8) / 16]);
Rectangle(hdc, X * 20, Y * 20, (X + 1) * 20, (Y + 1) * 20);
}
ReleaseDC(hWindow, hdc);
}
case WM_MOUSEMOVE:
if (wParam & MK_LBUTTON)
{
int const x = GET_X_LPARAM(lParam), y = GET_Y_LPARAM(lParam);
int const X = x / 20, Y = y / 20;
if (changeColor(x, y, X, Y))
paintColor(X, Y, hWindow);
if (X > 0)
if (changeColor(x, y, X - 1, Y))
paintColor(X - 1, Y, hWindow);
if (Y > 0)
if (changeColor(x, y, X, Y - 1))
paintColor(X, Y - 1, hWindow);
if (X < 27)
if (changeColor(x, y, X + 1, Y))
paintColor(X + 1, Y, hWindow);
if (Y < 27)
if (changeColor(x, y, X, Y + 1))
paintColor(X, Y + 1, hWindow);
if (X > 0 && Y > 0)
if (changeColor(x, y, X - 1, Y - 1))
paintColor(X - 1, Y - 1, hWindow);
if (X > 0 && Y < 27)
if (changeColor(x, y, X - 1, Y + 1))
paintColor(X - 1, Y + 1, hWindow);
if (X < 27 && Y > 0)
if (changeColor(x, y, X + 1, Y - 1))
paintColor(X + 1, Y - 1, hWindow);
if (X < 27 && Y < 27)
if (changeColor(x, y, X + 1, Y + 1))
paintColor(X + 1, Y + 1, hWindow);
}
return 0;
case WM_LBUTTONUP:
{
pLayer[0].setOutput(pixels);
for (unsigned i = 0; i < number; ++i)
{
pConnections[i].transmit();
pLayer[i + 1].calculate<functions>();
}
double sum = 10;
for (Neuron const& a : pLayer[number])
sum += a.output();
unsigned values[10];
unsigned i = 0;
for (Neuron const& a : pLayer[number])
values[i++] = (a.output() + 1) / sum * 100;
HDC hdc = GetDC(hWindow);
SelectObject(hdc, hPen);
SelectObject(hdc, hBrush[16]);
Rectangle(hdc, 0, 0, 90, 160);
WCHAR w[256];
wsprintf(w, L"0的概率%hu%%\n1的概率%hu%%\n2的概率%hu%%\n3的概率%hu%%\n4的概率%hu%%\n\
5的概率%hu%%\n6的概率%hu%%\n7的概率%hu%%\n8的概率%hu%%\n9的概率%hu%%\n",
values[0], values[1], values[2], values[3], values[4], values[5], values[6], values[7], values[8], values[9]);
RECT rect = { 0,0,560,560 };
DrawText(hdc, w, -1, &rect, DT_LEFT | DT_NOCLIP | DT_NOPREFIX);
ReleaseDC(hWindow, hdc);
for (i = 1; i < number + 1; ++i)
pLayer[i].clearInput();
return 0;
}
}
return DefWindowProc(hWindow, message, wParam, lParam);
}
void 手写识别()
{
HINSTANCE hInstance = GetModuleHandle(nullptr);
WNDCLASSEX window =
{
sizeof(WNDCLASSEX),
CS_HREDRAW | CS_VREDRAW,
WndProc,0,0,hInstance,
LoadIcon(nullptr, IDI_APPLICATION),
LoadCursor(nullptr, IDC_ARROW),
(HBRUSH)(COLOR_WINDOW + 1),
nullptr,L"ClassName",
LoadIcon(nullptr, IDI_APPLICATION)
};
RegisterClassEx(&window);
RECT rectangle = { 0,0,560,560 };
AdjustWindowRect(&rectangle, WS_OVERLAPPEDWINDOW, false);
HWND handleWindow = CreateWindow(window.lpszClassName, L"左键滑动",
WS_CAPTION | WS_SYSMENU, CW_USEDEFAULT, 0,
rectangle.right - rectangle.left, rectangle.bottom - rectangle.top,
nullptr, nullptr, hInstance, nullptr);
UpdateWindow(handleWindow);
ShowWind
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
1、资源内容:基于C++利用神经网络实现mnist手写数据集识别(源码+数据).rar 2、适用人群:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业或毕业设计,作为“参考资料”使用。 3、更多仿真源码和数据集下载列表(自行寻找自己需要的):https://blog.csdn.net/m0_62143653?type=download 4、免责声明:本资源作为“参考资料”而不是“定制需求”不一定能够满足所有人的需求,需要有一定的基础能够看懂代码,能够自行调试,能够自行添加功能修改代码。由于作者大厂工作较忙,不提供答疑服务,如不存在资源缺失问题概不负责,谢谢理解。
资源推荐
资源详情
资源评论
收起资源包目录
基于C++利用神经网络实现mnist手写数据集识别(源码+数据).rar (12个子文件)
基于C++利用神经网络实现mnist手写数据集识别(源码+数据)
数字识别3.sln 1KB
说明文档.md 618B
数字识别3
数字识别3.vcxproj 7KB
Neuron.h 863B
mnist数据集
train-images.idx3-ubyte 44.86MB
t10k-images.idx3-ubyte 7.48MB
train-labels.idx1-ubyte 59KB
t10k-labels.idx1-ubyte 10KB
Connections.h 1KB
数字识别3.vcxproj.filters 1KB
Layer.h 1KB
源.cpp 9KB
共 12 条
- 1
资源评论
Matlab仿真实验室
- 粉丝: 2w+
- 资源: 2181
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功