C++从零实现深度神经网络之五——模型的保存和加载以及画出实时输出曲线

本文由@星沉阁冰不语出品,转载请注明作者和出处。

文章链接:http://blog.csdn.net/xingchenbingbuyu/article/details/53704085

微博:http://weibo.com/xingchenbing 

一、模型的保存和加载


在我们完成对神经网络的训练之后,一般要把模型保存起来。不然每次使用模型之前都需要先训练模型,对于data hungry的神经网络来说,视数据多寡和精度要求高低,训练一次的时间从几分钟到数百个小时不等,这是任何人都耗不起的。把训练好的模型保存下来,当需要使用它的时候,只需要加载就行了。


现在需要考虑的一个问题是,保存模型的时候,我们到底要保存哪些东西?


之前有提到,可以简单的认为权值矩阵就是所谓模型。所以权值矩阵一定要保存。除此之外呢?不能忘记的一点是,我们保存模型是为了加载后能使用模型。显然要求加载模型之后,输入一个或一组样本就能开始前向运算和反向传播。这也就是说,之前实现的时候,forward()之前需要的,这里也都需要,只是权值不是随意初始化了,而是用训练好的权值矩阵代替。基于以上考虑,最终决定要保存的内容如下4个:


1.layer_neuron_num,各层神经元数目,这是生成神经网络需要的唯一参数。

2.weights,神经网络初始化之后需要用训练好的权值矩阵去初始化权值。

3.activation_function,使用神经网络的过程其实就是前向计算的过程,显然需要知道激活函数是什么。

4.learning_rate,如果要在现有模型的基础上继续训练以得到更好的模型,更新权值的时候需要用到这个函数。


再决定了需要保存的内容之后,接下来就是实现了,仍然是保存为xml格式,上一篇已经提到了保存和加载xml是多么的方便:

	//Save model;
	void Net::save(std::string filename)
	{
		cv::FileStorage model(filename, cv::FileStorage::WRITE);
		model << "layer_neuron_num" << layer_neuron_num;
		model << "learning_rate" << learning_rate;
		model << "activation_function" << activation_function;

		for (int i = 0; i < weights.size(); i++)
		{
			std::string weight_name = "weight_" + std::to_string(i);
			model << weight_name << weights[i];
		}
		model.release();
	}

	//Load model;
	void Net::load(std::string filename)
	{
		cv::FileStorage fs;
		fs.open(filename, cv::FileStorage::READ);
		cv::Mat input_, target_;

		fs["layer_neuron_num"] >> layer_neuron_num;
		initNet(layer_neuron_num);

		for (int i = 0; i < weights.size(); i++)
		{
			std::string weight_name = "weight_" + std::to_string(i);
			fs[weight_name] >> weights[i];
		}

		fs["learning_rate"] >> learning_rate;
		fs["activation_function"] >> activation_function;

		fs.release();
	}

二、实时画出输出曲线


有时候我们为了有一个直观的观察,我们希望能够是实时的用一个曲线来表示输出误差。但是没有找到满意的程序可用,于是自己就写了一个非常简单的函数,用来实时输出训练时的loss。理想的输出大概像下面这样:




为什么说是理想的输出呢,因为一般来说误差很小,可能曲线直接就是从左下角开始的,上面一大片都没有用到。不过已经能够看出loss的大致走向了。


这个函数的实现其实就是先画俩个作为坐标用的直线,然后把相邻点用直线连接起来:

	//Draw loss curve
	void draw_curve(cv::Mat& board, std::vector<double> points)
	{
		cv::Mat board_(620, 1000, CV_8UC3, cv::Scalar::all(200));
		board = board_;
		cv::line(board, cv::Point(0, 550), cv::Point(1000, 550), cv::Scalar(0, 0, 0), 2);
		cv::line(board, cv::Point(50, 0), cv::Point(50, 1000), cv::Scalar(0, 0, 0), 2);

		for (size_t i = 0; i < points.size() - 1; i++)
		{
			cv::Point pt1(50 + i * 2, (int)(548 - points[i]));
			cv::Point pt2(50 + i * 2 + 1, (int)(548 - points[i + 1]));
			cv::line(board, pt1, pt2, cv::Scalar(0, 0, 255), 2);
			if (i >= 1000)
			{
				return;
			}
		}
		cv::imshow("Loss", board);
		cv::waitKey(10);
	}

至此,神经网络已经实现完成了。完整的代码可以在Github上找到。


下一步,就是要用编写的神经网络,用实际样本开始训练了。下一篇,用MNIST数据训练神经网络。


时间: 2024-10-07 11:54:47

C++从零实现深度神经网络之五——模型的保存和加载以及画出实时输出曲线的相关文章

第13章保存和加载你的模型

第13章保存和加载你的模型 在上一章,我们使用keras库学习了怎样训练CNNs.但是,我们注意到,在我们每次想评估网络或测试一批图像时,都需要首先训练它.这在网络模型很深.数据集很大时,将花费巨大时间来训练.那么有没有一种方式在训练完模型后,将它保存在磁盘上,然后在分类新图像时仅仅从磁盘加载就可以? 这种保存和加载一个已训练模型的过程称为模型序列化(model serialization),即本章主要的主题. 1         将一个模型序列化到磁盘上 使用keras库,模型序列化通过对已训

C++从零实现深度神经网络之二——前向传播和反向传播

本文由@星沉阁冰不语出品,转载请注明作者和出处. 文章链接:http://blog.csdn.net/xingchenbingbuyu/article/details/53677630 微博:http://weibo.com/xingchenbing  前一篇博客Net类的设计和神经网络的初始化中,大部分还是比较简单的.因为最重要事情就是生成各种矩阵并初始化.神经网络中的重点和核心就是本文的内容--前向和反向传播两大计算过程.每层的前向传播分别包含加权求和(卷积?)的线性运算和激活函数的非线性运

tensorflow 之模型的保存与加载(一)

怎样让通过训练的神经网络模型得以复用? 本文先介绍简单的模型保存与加载的方法,后续文章再慢慢深入解读. 1 #!/usr/bin/env python3 2 #-*- coding:utf-8 -*- 3 ############################ 4 #File Name: saver.py 5 #Brief: 6 #Author: frank 7 #Mail: [email protected] 8 #Created Time:2018-06-22 22:12:52 9 ###

tensorflow 之模型的保存与加载(三)

前面的两篇博文 第一篇:简单的模型保存和加载,会包含所有的信息:神经网络的op,node,args等; 第二篇:选择性的进行模型参数的保存与加载. 本篇介绍,只保存和加载神经网络的计算图,即前向传播的过程. #!/usr/bin/env python3 #-*- coding:utf-8 -*- ############################ #File Name: save_restore.py #Brief: #Author: frank #Mail: [email protect

深度神经网络全面概述:从基本概念到实际模型和硬件基础

国内镜像:苏轶然-CSDN 论文地址:https://arxiv.org/pdf/1703.09039.pdf 原文地址:机器之心-深度神经网络全面概述:从基本概念到实际模型和硬件基础 目前,包括计算机视觉.语音识别和机器人在内的诸多人工智能应用已广泛使用了深度神经网络(deep neural networks,DNN).DNN 在很多人工智能任务之中表现出了当前最佳的准确度,但同时也存在着计算复杂度高的问题.因此,那些能帮助 DNN 高效处理并提升效率和吞吐量,同时又无损于表现准确度或不会增加

深度学习实践系列(2)- 搭建notMNIST的深度神经网络

如果你希望系统性的了解神经网络,请参考零基础入门深度学习系列,下面我会粗略的介绍一下本文中实现神经网络需要了解的知识. 什么是深度神经网络? 神经网络包含三层:输入层(X).隐藏层和输出层:f(x) 每层之间每个节点都是完全连接的,其中包含权重(W).每层都存在一个偏移值(b). 每一层节点的计算方式如下: 其中g()代表激活函数,o()代表softmax输出函数. 使用Flow Graph的方式来表达如何正向推导神经网络,可以表达如下: x: 输入值 a(x):表示每个隐藏层的pre-acti

深度神经网络DNN的多GPU数据并行框架 及其在语音识别的应用

深度神经网络(Deep Neural Networks, 简称DNN)是近年来机器学习领域中的研究热点,产生了广泛的应用.DNN具有深层结构.数千万参数需要学习,导致训练非常耗时.GPU有强大的计算能力,适合于加速深度神经网络训练.DNN的单机多GPU数据并行框架是腾讯深度学习平台的一部分,腾讯深度学习平台技术团队实现了数据并行技术加速DNN训练,提供公用算法简化实验过程.对微信语音识别应用,在模型收敛速度和模型性能上都取得了有效提升--相比单GPU 4.6倍加速比,数十亿样本的训练数天收敛,测

第十一章——训练深度神经网络

上一章我们训练了一个浅层神经网络,只要两个隐层.但如果处理复杂的问题,例如从高分辨率图像中识别上百种类的物品,这就需要训练一个深度DNN.也行包含十层,每层上百个神经元,几十万个连接.这绝不是闹着玩的: 首先,需要面对梯度消失(或者相对的梯度爆炸)问题,这会导致浅层很难被训练. 其次,这么大一个网络,训练速度很慢. 最后,一个包含上百万参数的模型,存在很大过拟合的风险. 11.1 梯度消失(爆炸)问题 反向传播算法会计算损失函数关于每一个参数的偏导数,然后使用梯度下降更新参数.不幸的是,反向传播

numpy 构建深度神经网络来识别图片中是否有猫

目录 1 构建数据 2 随机初始化数据 3 前向传播 4 计算损失 5 反向传播 6 更新参数 7 构建模型 8 预测 9 开始训练 10 进行预测 11 以图片的形式展示预测后的结果 搭建简单神经网络来识别图片中是否有猫 代码借鉴地址:纯用NumPy实现神经网络 搭建一个简单易懂的神经网络来帮你理解深度神经网络 通过简单的猫识别的例子来帮你进一步进行理解 本代码用 numpy 来实现,不含有正则化,批量等算法 这里我们先来理清楚神经网络的步骤 (1) 构建数据.我们要构建出这样的一个数据,sh