【机器学习】C++ 从零实现神经网络 (五)模型的保存和加载及实时画出输出曲线
发布日期:2021-06-29 14:29:42 浏览次数:2 分类:技术文章

本文共 2920 字,大约阅读时间需要 9 分钟。

长文预警: 共22727字

注意:文末附有所有源码的地址

建议:收藏后找合适时间阅读。

在这里插入图片描述

五、模型的保存和加载及实时画出输出曲线
模型的保存和加载

模型的保存与加载

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

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

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

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

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

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

  • 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
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); }

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

源码链接

所有的代码都已经托管在Github上面,感兴趣的可以去下载查看。源码链接地址为

https://github.com/LiuXiaolong19920720/simple_net

学如逆水行舟,不进则退

转载地址:https://chocolate.blog.csdn.net/article/details/104163257 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:【机器学习】人人都可以做深度学习应用:入门篇(上)深度学习技术
下一篇:【机器学习】C++ 从零实现神经网络(四)神经网络的预测和输入输出解析

发表评论

最新留言

留言是一种美德,欢迎回访!
[***.207.175.100]2024年04月28日 02时07分43秒