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)的更多相关文章

  1. MXNet 学习 (1) --- 最易上手的深度学习开源库 --- 安装及环境搭建

    安装环境:Win 10 专业版 64位 + Visual Studio 2015 Community. 记录下自己在有GPU的环境下安装配置MXNet的过程.该过程直接使用MXNet release ...

  2. AI炼丹 - 深度学习必备库 numpy

    目录 深度学习必备库 - Numpy 1. 基础数据结构ndarray数组 1.1 为什么引入ndarray数组 1.2 如何创建ndarray数组 1.3 ndarray 数组的基本运算 1.4 n ...

  3. 谷歌发布了 T2T(Tensor2Tensor)深度学习开源系统

    谷歌开源T2T模型库,深度学习系统进入模块化时代! 谷歌大脑颠覆深度学习混乱现状,要用单一模型学会多项任务 https://github.com/tensorflow/models https://g ...

  4. 深度学习开源工具——caffe介绍

    本页是转载caffe的一个介绍,之前的页面图都down了,更新一下. 目录 简介 要点记录 提问 总结 简介 报告时间是北京时间 12月14日 凌晨一点到两点,主讲人是 Caffe 团队的核心之一 E ...

  5. python数据可视化、数据挖掘、机器学习、深度学习 常用库、IDE等

    一.可视化方法 条形图 饼图 箱线图(箱型图) 气泡图 直方图 核密度估计(KDE)图 线面图 网络图 散点图 树状图 小提琴图 方形图 三维图 二.交互式工具 Ipython.Ipython not ...

  6. 深度学习常用数据集 API(包括 Fashion MNIST)

    基准数据集 深度学习中经常会使用一些基准数据集进行一些测试.其中 MNIST, Cifar 10, cifar100, Fashion-MNIST 数据集常常被人们拿来当作练手的数据集.为了方便,诸如 ...

  7. 【深度学习笔记】(二)基于MNIST数据集的神经网络实验

    一.介绍 MNIST(Mixed National Institute of Standards and Technology database)是网上著名的公开数据库之一,是一个入门级的计算机视觉数 ...

  8. Ubuntu14.04上深度学习Caffe库安装指南(CUDA7.5 + opencv3.1)

    Ubuntu14.04上Caffe安装指南 安装的准备工作 首先,安装官方版Caffe时.假设要使用Cuda.须要确认自己确实有NVIDIA GPU. 安装Ubuntu时,将/boot 分区分大概20 ...

  9. 深度学习练手项目——DNN识别手写数字

    该案例主要目的是为了熟悉Keras基本用法,以及了解DNN基本流程. 示例代码: import numpy as np import matplotlib.pyplot as plt from ker ...

随机推荐

  1. 在 Deepin 中搭建 GitLab

    入职半个月了,一直在接受业务知识以及企业文化知识的培训,下周终于要开始上岗入手项目了.由于公司使用自己搭建的 GitLab 服务作为项目版本控制器,所以我决定学习一下 GitLab,由于这货跟 Git ...

  2. ubuntu命令安装jdk

    1.ubuntu使用的是openjdk,所以我们需要先找到合适的jdk版本.在命令行中输入命令: $apt-cache search openjdk 1 返回结果列表(因个人电脑而有所不同): def ...

  3. gluoncv 导入方式

    了解了sys.path和python 的import 的话,之前修改gluoncv 的方式就可以有了新的简单的方法: 如果你pip install gluoncv的,然后脚本又git clone了,发 ...

  4. PHP面试系列 之Linux(二)---- Linux系统定时任务

    环境:ubuntu 16 一.cron实现定时任务 cron实现的定时任务是周期性循环执行的. 1.安装cron sudo apt-get install cron 2.添加定时任务(进行编辑) cr ...

  5. HDU 3746 Cyclic Nacklace(求补齐循环节最小长度 KMP中next数组的使用 好题!!!)

    Cyclic Nacklace Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

  6. Gradle Goodness: Parse Files with SimpleTemplateEngine in Copy Task

    With the copy task of Gradle we can copy files that are parsed by Groovy's SimpleTemplateEngine. Thi ...

  7. centos7字体中英文转化

    [root@localhost oracle]#vi /etc/locate.conf,把里面的内容改为: 转化为英文: LANG="en_US.UTF-8"LANGUAGE=&q ...

  8. iOS:文字相关(19-01-08更)

    0.写在前面 1.小技巧 UILabel类: 1-1-1).设置行间距富文本,有省略号要求的,需要再次设置省略(初始化时设置的会失效). UITextField类: 1-2-1).清空按钮. UITe ...

  9. iOS:通信录(完成)(18-01-18更)

    1.读取通信录 1).9.0以前:AddressBook 2).9.0以后:Contacts 2.调用通信录UI(不弄) 1).9.0以前:AddressBookUI 2).9.0以后:Contact ...

  10. c#采用emit将DataTable转List

    前面已经说了List转DataTable,也整理了代码. 现在转回来说说DataTable转List. 先举一个例子 public class Person { public int Age{get; ...