经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C++ » 查看文章
C++基于文件流和armadillo读取mnist
来源:cnblogs  作者:c艹用户  时间:2021/5/10 9:06:00  对本文有异议

发现网上大把都是用python读取mnist的,用C++大都是用opencv读取的,但我不怎么用opencv,因此自己摸索了个使用文件流读取mnist的方法,armadillo仅作为储存矩阵的一种方式。

1. mnist文件

首先避坑,这些文件要解压。
没有肾么描述
官网截图可知,文件头很简单,只有若干个32位整数,MSB,像素和标签均是无符号字节(即unsigned char)可以先读取文件头,再读取剩下的部分。

2. 读取文件头

我觉得没什么必要啊,直接跳过不行吗
文件头都是32位,那就整四个unsigned char呗。

  1. uchar a, b, c, d;
  2. File >> a >> b >> c >> d;

这样a、b、c、d就保存了一个整数。

  1. x = ((((a * 256) + b) * 256) + c) * 256 + d;

然后就得到了呗。
看每个文件有多少文件头,就操作几次(并可以顺便与官方的magic number进行对比),剩下的就是文件的内容了。

3. 读取内容

这部分可以依照之前的方法,一次读取一个字符,再保存至矩阵当中。例如:

  1. uchar a;
  2. mat image(28, 28, fill::zeros); // 这是个矩阵!
  3. for(int i = 0; i < 28; i++) //28行28列的图像懒得改了
  4. for(int j = 0; j < 28; j++)
  5. {
  6. File >> a;
  7. image(i, j) = double(a);
  8. }

这样就读取了一张图片。其余以此类推吧。

4. 完整代码

可以复制,可以修改,也可以用于商用和学术,但是请标注原作者(就是我)。
mnist.h

  1. #ifndef MNIST_H
  2. #define MNIST_H
  3. #include<iostream>
  4. #include<fstream>
  5. #include<armadillo>
  6. #define uchar unsigned char
  7. using namespace std;
  8. using namespace arma;
  9. //小端存储转换
  10. int reverseInt(uchar a, uchar b, uchar c, uchar d);
  11. //读取image数据集信息
  12. mat read_mnist_image(const string fileName);
  13. //读取label数据集信息
  14. mat read_mnist_label(const string fileName);
  15. #endif

mnist.cpp

  1. //mnist.cpp
  2. //作者:C艹
  3. #include "mnist.h"
  4. int reverseInt(uchar a, uchar b, uchar c, uchar d)
  5. {
  6. return ((((a * 256) + b) * 256) + c) * 256 + d;
  7. }
  8. mat read_mnist_image(const string fileName)
  9. {
  10. fstream File;
  11. mat image;
  12. File.open(fileName);
  13. if (!File.is_open()) // cannot open file
  14. {
  15. cout << "文件打不开啊" << endl;
  16. return mat(0, 0, fill::zeros);
  17. }
  18. uchar a, b, c, d;
  19. File >> a >> b >> c >> d;
  20. int magic = reverseInt(a, b, c, d);
  21. if (magic != 2051) //magic number wrong
  22. {
  23. cout << magic;
  24. return mat(0, 0, fill::zeros);
  25. }
  26. File >> a >> b >> c >> d;
  27. int num_img = reverseInt(a, b, c, d);
  28. File >> a >> b >> c >> d;
  29. int num_row = reverseInt(a, b, c, d);
  30. File >> a >> b >> c >> d;
  31. int num_col = reverseInt(a, b, c, d);
  32. // 文件头读取完毕
  33. image = mat(num_img, num_col * num_row, fill::zeros);
  34. for(int i = 0; i < num_img; i++)
  35. for (int j = 0; j < num_col * num_row; j++)
  36. {
  37. File >> a;
  38. image(i, j) = double(a);
  39. }
  40. return image;
  41. }
  42. mat read_mnist_label(const string fileName)
  43. {
  44. fstream File;
  45. mat label;
  46. File.open(fileName);
  47. if (!File.is_open()) // cannot open file
  48. {
  49. cout << "文件打不开啊" << endl;
  50. return mat(0, 0, fill::zeros);
  51. }
  52. uchar a, b, c, d;
  53. File >> a >> b >> c >> d;
  54. int magic = reverseInt(a, b, c, d);
  55. if (magic != 2049) //magic number wrong
  56. {
  57. cout << magic;
  58. return mat(0, 0, fill::zeros);
  59. }
  60. File >> a >> b >> c >> d;
  61. int num_lab = reverseInt(a, b, c, d);
  62. // 文件头读取完毕
  63. label = mat(num_lab, 10, fill::zeros);
  64. for (int i = 0; i < num_lab; i++)
  65. {
  66. File >> a;
  67. label(i, int(a)) = 1;
  68. }
  69. return label;
  70. }

原文链接:http://www.cnblogs.com/wyblikeswsf/p/14748103.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号