/*
@作者:CHH
@版本V1.0
@邮箱:chh_is_dog@163.com
@编写时间:2019-7-29
@功能:使用反向传播神经网络识别手写字体
@使用方法:
1.生成的文件会自动到同一目录下寻找MNIST的四个手写字体库
2.字体库下载地址:http://yann.lecun.com/exdb/mnist/
3.DEBUG模式下只会使用少量训练样本
4.输出流为stdout
@模型结构:
1.激活函数:sigmod
2.损失函数:交叉熵损失函数
3.迭代方式:反向传播+最速梯度下降
4.学习率=0.5
5.三层神经元,连接方式: 全连接
a.输入层:28*28个
b.隐藏层:20个
c.输出层:10个
@程序结构:分为4个模块,面向过程化
1.实现矩阵类以及矩阵的基本操作
2.读入MNIST的数据并进行清洗
3.实现FP->BP->GD
4.模型评估
*/
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cmath>
#include <fstream>
#include <cstdlib>
#include <ctime>
#include <cstring>
using namespace std;
#define DEBUG
const int IMAGE_SIZE = 28 * 28;
const int LABEL_SIZE = 1;
const int OUT_SIZE = 10;
const double INF = 1.7e308;
const double EPS = 1e-6;
const double E = 2.718281828459;
#ifdef DEBUG
const int NUM_TRAIN = 100;
const int NUM_TEST = 10;
#else
const int NUM_TRAIN = 60000;
const int NUM_TEST = 10000;
#endif
//矩阵
typedef vector<vector<double>> Matrix;
//矩阵构造
void construct(Matrix &mat, int row, int col)
{
mat.resize(row);
for (int i = 0; i < row; i++)
mat[i].resize(col);
}
void construct(Matrix &mat, int row, int col, double val)
{
mat.resize(row);
for (int i = 0; i < row; i++)
mat[i].resize(col, val);
}
//矩阵加法
inline const Matrix addition(const Matrix &a, const Matrix &b)
{
if (a.size() != b.size() || a[0].size() != b[0].size())
throw "ERROR: Matrix addition format wrong";
Matrix res;
res.resize(a.size());
for (int i = 0; i < a.size(); i++)
res[i].resize(a[0].size());
for (int i = 0; i < a.size(); i++)
for (int j = 0; j < a[i].size(); j++)
res[i][j] = a[i][j] + b[i][j];
return res;
}
//矩阵减法
inline const Matrix subtract(const Matrix &a, const Matrix &b)
{
if (a.size() != b.size() || a[0].size() != b[0].size())
throw "ERROR: Matrix subtract format wrong";
Matrix res;
res.resize(a.size());
for (int i = 0; i < a.size(); i++)
res[i].resize(a[0].size());
for (int i = 0; i < a.size(); i++)
for (int j = 0; j < a[i].size(); j++)
res[i][j] = a[i][j] - b[i][j];
return res;
}
//矩阵乘法
inline const Matrix multiply(const Matrix &a, const Matrix &b)
{
if (a[0].size() != b.size())
throw "ERROR: Matrix multiply format wrong";
Matrix res;
res.resize(a.size());
for (int i = 0; i < a.size(); i++)
res[i].resize(b[0].size(), 0);
for (int i = 0; i < res.size(); i++)
for (int j = 0; j < res[0].size(); j++)
for (int k = 0; k < a[0].size(); k++)
res[i][j] += a
C++实现手写数字识别
最新推荐文章于 2023-08-30 16:54:17 发布