深度学习开源库tiny-dnn的使用(MNIST)
tiny-dnn是一个基于DNN的深度学习开源库,它的License是BSD 3-Clause。之前名字是tiny-cnn是基于CNN的,tiny-dnn与tiny-cnn相关又增加了些新层。此开源库很活跃,几乎每天都有新的提交,因此下面详细介绍下tiny-dnn在windows7 64bit vs2013的编译及使用。
1. 从https://github.com/tiny-dnn/tiny-dnn 下载源码:
$ git clone https://github.com/tiny-dnn/tiny-dnn.git 版本号为6281c1b,更新日期2016.12.03
2. 源文件中已经包含了vs2013工程,vc/vc12/tiny-dnn.sln,默认是win32的,这里新建一个x64的控制台工程tiny-dnn;
3. 仿照源工程,将相应.h文件加入到新控制台工程中,新加一个test_tiny-dnn.cpp文件;
4. 仿照examples/mnist中test.cpp和train.cpp文件中的代码添加测试代码;
#include "funset.hpp"
#include <string>
#include <algorithm>
#include "tiny_dnn/tiny_dnn.h"
static void construct_net(tiny_dnn::network<tiny_dnn::sequential>& nn)
{
// connection table [Y.Lecun, 1998 Table.1]
#define O true
#define X false
static const bool tbl[] = {
O, X, X, X, O, O, O, X, X, O, O, O, O, X, O, O,
O, O, X, X, X, O, O, O, X, X, O, O, O, O, X, O,
O, O, O, X, X, X, O, O, O, X, X, O, X, O, O, O,
X, O, O, O, X, X, O, O, O, O, X, X, O, X, O, O,
X, X, O, O, O, X, X, O, O, O, O, X, O, O, X, O,
X, X, X, O, O, O, X, X, O, O, O, O, X, O, O, O
};
#undef O
#undef X
// by default will use backend_t::tiny_dnn unless you compiled
// with -DUSE_AVX=ON and your device supports AVX intrinsics
tiny_dnn::core::backend_t backend_type = tiny_dnn::core::default_engine();
// construct nets: C: convolution; S: sub-sampling; F: fully connected
nn << tiny_dnn::convolutional_layer<tiny_dnn::activation::tan_h>(32, 32, 5, 1, 6, // C1, 1@32x32-in, 6@28x28-out
tiny_dnn::padding::valid, true, 1, 1, backend_type)
<< tiny_dnn::average_pooling_layer<tiny_dnn::activation::tan_h>(28, 28, 6, 2) // S2, 6@28x28-in, 6@14x14-out
<< tiny_dnn::convolutional_layer<tiny_dnn::activation::tan_h>(14, 14, 5, 6, 16, // C3, 6@14x14-in, 16@10x10-out
connection_table(tbl, 6, 16),
tiny_dnn::padding::valid, true, 1, 1, backend_type)
<< tiny_dnn::average_pooling_layer<tiny_dnn::activation::tan_h>(10, 10, 16, 2) // S4, 16@10x10-in, 16@5x5-out
<< tiny_dnn::convolutional_layer<tiny_dnn::activation::tan_h>(5, 5, 5, 16, 120, // C5, 16@5x5-in, 120@1x1-out
tiny_dnn::padding::valid, true, 1, 1, backend_type)
<< tiny_dnn::fully_connected_layer<tiny_dnn::activation::tan_h>(120, 10, // F6, 120-in, 10-out
true, backend_type);
}
static void train_lenet(const std::string& data_dir_path)
{
// specify loss-function and learning strategy
tiny_dnn::network<tiny_dnn::sequential> nn;
tiny_dnn::adagrad optimizer;
construct_net(nn);
std::cout << "load models..." << std::endl;
// load MNIST dataset
std::vector<tiny_dnn::label_t> train_labels, test_labels;
std::vector<tiny_dnn::vec_t> train_images, test_images;
tiny_dnn::parse_mnist_labels(data_dir_path + "/train-labels.idx1-ubyte", &train_labels);
tiny_dnn::parse_mnist_images(data_dir_path + "/train-images.idx3-ubyte", &train_images, -1.0, 1.0, 2, 2);
tiny_dnn::parse_mnist_labels(data_dir_path + "/t10k-labels.idx1-ubyte", &test_labels);
tiny_dnn::parse_mnist_images(data_dir_path + "/t10k-images.idx3-ubyte", &test_images, -1.0, 1.0, 2, 2);
std::cout << "start training" << std::endl;
tiny_dnn::progress_display disp(static_cast<unsigned long>(train_images.size()));
tiny_dnn::timer t;
int minibatch_size = 10;
int num_epochs = 30;
optimizer.alpha *= static_cast<tiny_dnn::float_t>(std::sqrt(minibatch_size));
// create callback
auto on_enumerate_epoch = [&](){
std::cout << t.elapsed() << "s elapsed." << std::endl;
tiny_dnn::result res = nn.test(test_images, test_labels);
std::cout << res.num_success << "/" << res.num_total << std::endl;
disp.restart(static_cast<unsigned long>(train_images.size()));
t.restart();
};
auto on_enumerate_minibatch = [&](){
disp += minibatch_size;
};
// training
nn.train<tiny_dnn::mse>(optimizer, train_images, train_labels, minibatch_size, num_epochs, on_enumerate_minibatch, on_enumerate_epoch);
std::cout << "end training." << std::endl;
// test and show results
nn.test(test_images, test_labels).print_detail(std::cout);
// save network model & trained weights
nn.save(data_dir_path + "/LeNet-model");
}
// rescale output to 0-100
template <typename Activation>
static double rescale(double x)
{
Activation a;
return 100.0 * (x - a.scale().first) / (a.scale().second - a.scale().first);
}
static void convert_image(const std::string& imagefilename, double minv, double maxv, int w, int h, tiny_dnn::vec_t& data)
{
tiny_dnn::image<> img(imagefilename, tiny_dnn::image_type::grayscale);
tiny_dnn::image<> resized = resize_image(img, w, h);
// mnist dataset is "white on black", so negate required
std::transform(resized.begin(), resized.end(), std::back_inserter(data),
[=](uint8_t c) { return (255 - c) * (maxv - minv) / 255.0 + minv; });
}
int test_dnn_mnist_train()
{
std::string data_dir_path = "E:/GitCode/NN_Test/data";
train_lenet(data_dir_path);
return 0;
}
int test_dnn_mnist_predict()
{
std::string model { "E:/GitCode/NN_Test/data/LeNet-model" };
std::string image_path { "E:/GitCode/NN_Test/data/images/"};
int target[10] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
tiny_dnn::network<tiny_dnn::sequential> nn;
nn.load(model);
for (int i = 0; i < 10; i++) {
std::string str = std::to_string(i);
str += ".png";
str = image_path + str;
// convert imagefile to vec_t
tiny_dnn::vec_t data;
convert_image(str, -1.0, 1.0, 32, 32, data);
// recognize
auto res = nn.predict(data);
std::vector<std::pair<double, int> > scores;
// sort & print top-3
for (int j = 0; j < 10; j++)
scores.emplace_back(rescale<tiny_dnn::tan_h>(res[j]), j);
std::sort(scores.begin(), scores.end(), std::greater<std::pair<double, int>>());
for (int j = 0; j < 3; j++)
fprintf(stdout, "%d: %f; ", scores[j].second, scores[j].first);
fprintf(stderr, "\n");
// save outputs of each layer
for (size_t j = 0; j < nn.depth(); j++) {
auto out_img = nn[j]->output_to_image();
auto filename = image_path + std::to_string(i) + "_layer_" + std::to_string(j) + ".png";
out_img.save(filename);
}
// save filter shape of first convolutional layer
auto weight = nn.at<tiny_dnn::convolutional_layer<tiny_dnn::tan_h>>(0).weight_to_image();
auto filename = image_path + std::to_string(i) + "_weights.png";
weight.save(filename);
fprintf(stdout, "the actual digit is: %d, correct digit is: %d \n\n", scores[0].second, target[i]);
}
return 0;
}
5. 运行程序,train时,运行结果如下图所示,准确率达到99%以上:
6. 对生成的model进行测试,通过画图工具,每个数字生成一张图像,共10幅,如下图:
7. 通过导入train时生成的model,对这10张图像进行识别,识别结果如下图,其中0,8,9被误识别为2,2,1.
GitHub:https://github.com/fengbingchun/NN_Test
深度学习开源库tiny-dnn的使用(MNIST)的更多相关文章
- MXNet 学习 (1) --- 最易上手的深度学习开源库 --- 安装及环境搭建
安装环境:Win 10 专业版 64位 + Visual Studio 2015 Community. 记录下自己在有GPU的环境下安装配置MXNet的过程.该过程直接使用MXNet release ...
- AI炼丹 - 深度学习必备库 numpy
目录 深度学习必备库 - Numpy 1. 基础数据结构ndarray数组 1.1 为什么引入ndarray数组 1.2 如何创建ndarray数组 1.3 ndarray 数组的基本运算 1.4 n ...
- 谷歌发布了 T2T(Tensor2Tensor)深度学习开源系统
谷歌开源T2T模型库,深度学习系统进入模块化时代! 谷歌大脑颠覆深度学习混乱现状,要用单一模型学会多项任务 https://github.com/tensorflow/models https://g ...
- 深度学习开源工具——caffe介绍
本页是转载caffe的一个介绍,之前的页面图都down了,更新一下. 目录 简介 要点记录 提问 总结 简介 报告时间是北京时间 12月14日 凌晨一点到两点,主讲人是 Caffe 团队的核心之一 E ...
- python数据可视化、数据挖掘、机器学习、深度学习 常用库、IDE等
一.可视化方法 条形图 饼图 箱线图(箱型图) 气泡图 直方图 核密度估计(KDE)图 线面图 网络图 散点图 树状图 小提琴图 方形图 三维图 二.交互式工具 Ipython.Ipython not ...
- 深度学习常用数据集 API(包括 Fashion MNIST)
基准数据集 深度学习中经常会使用一些基准数据集进行一些测试.其中 MNIST, Cifar 10, cifar100, Fashion-MNIST 数据集常常被人们拿来当作练手的数据集.为了方便,诸如 ...
- 【深度学习笔记】(二)基于MNIST数据集的神经网络实验
一.介绍 MNIST(Mixed National Institute of Standards and Technology database)是网上著名的公开数据库之一,是一个入门级的计算机视觉数 ...
- Ubuntu14.04上深度学习Caffe库安装指南(CUDA7.5 + opencv3.1)
Ubuntu14.04上Caffe安装指南 安装的准备工作 首先,安装官方版Caffe时.假设要使用Cuda.须要确认自己确实有NVIDIA GPU. 安装Ubuntu时,将/boot 分区分大概20 ...
- 深度学习练手项目——DNN识别手写数字
该案例主要目的是为了熟悉Keras基本用法,以及了解DNN基本流程. 示例代码: import numpy as np import matplotlib.pyplot as plt from ker ...
随机推荐
- 大屏FAQ
1. 大屏可以分为哪几类?帆软有哪些大屏硬件合作商?编辑 拼接屏:通常由单个46-55寸的液晶显示屏组成屏幕墙,存在拼缝,借助矩阵.屏控系统来进行信号的输入与输出控制,可以实现屏幕墙上多个屏幕的组合. ...
- Codeforces Round #443 (Div. 2) 【A、B、C、D】
Codeforces Round #443 (Div. 2) codeforces 879 A. Borya's Diagnosis[水题] #include<cstdio> #inclu ...
- android中反射技术使用实例
在计算机科学领域.反射是指一类应用,它们能够自描写叙述和自控制.也就是说,这类应用通过採用某种机制来实现对自己行为的描写叙述(self-representation)和监測(examination), ...
- JavaScript权威指南第01章 JavaScript 概述
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/huangbin10025/article/details/27951767 JavaScript 概 ...
- 编程算法 - 数字在排序数组中出现的次数 代码(C)
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/u012515223/article/details/36869869 数字在排序数组中出现的次数 代 ...
- PM2 部署 nodejs 项目
在网上找到pm2.目前似乎最常见的线上部署nodejs项目的有forever,pm2这两种.使用场合: forever管理多个站点,每个站点访问量不大,不需要监控. pm2 网站访问量比较大,需要完整 ...
- js 日历插件开发
1.HTML完整代码如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset=& ...
- PHPStorm自定义主题配置
1.下载喜欢的主题 官方下载地址:下载 2.将.icls主题文件放到PHPStorm的配置中 windows下主题位置:C:\Users\Administrator\.PhpStorm2017.3\c ...
- PAT——1032. 挖掘机技术哪家强
为了用事实说明挖掘机技术到底哪家强,PAT组织了一场挖掘机技能大赛.现请你根据比赛结果统计出技术最强的那个学校. 输入格式: 输入在第1行给出不超过105的正整数N,即参赛人数.随后N行,每行给出一位 ...
- SwaggerUI用户手册
SwaggerUI是一个非常好用的API文档工具,最关键的是他还能在工具内调试API,简直爽的不要不要的~网上针对开发者的文档非常多,但是给用户的手册却非常少.所以我来简单写个用户手册,供没有使用过s ...