7- 深度学习之神经网络核心原理与算法-模型的保存与加载

模型的保存与加载

  • 网络训练完毕你需要保存,以便在产品上使用。(手写识别模型要识别新的图片)
  • 保存网络的结构,权重,偏置,使用的损失函数。
  • 使用别人的模型或者对已有模型进行微调。

训练中断之后从该轮模型参数继续往后进行训练。不需要重新开始。

添加模型保存的相关代码

在network类中添加保存模型的方法。需要一个参数filename,保存到哪里

 # 保存模型
    def save(self, filename):
        data = {"sizes": self.sizes,
                "weights": [w.tolist() for w in self.weights],
                "biases": [b.tolist() for b in self.biases],
                "cost": str(self.cost.__name__)
        }
        f = open(filename, "w")
        json.dump(data, f)
        f.close()

size是一个列表,定义了一共有多少层,每层有多少个神经元。保存模型权重。

w是numpy的array类型,调用它的tolist方法,把它转换成python的列表类型。

这里保存的是cost的类名字。(CrossEntropyCost),json的dump方法可以将字典保存为字符串。

加载文件

# 加载模型
def load(filename):
    f = open(filename, "r")
    data = json.load(f)
    f.close()
    cost = getattr(sys.modules[__name__], data["cost"])
    net = Network(data["sizes"], cost=cost)
    net.weights = [np.array(w) for w in data["weights"]]
    net.biases = [np.array(b) for b in data["biases"]]
    return net

json的load方法将字符串还原为我们的字典。

需要使用一个python的内置函数getattr,首先需要传入sys包。 使用里面的modules方法,去获取当前的模型名字,然后使用data里面的cost,去把我们的cost对应的字符串取出来。

这里的意思是说,如果我,我们的这个文件在python里面是别人的另外的文件引入的,那么这个name的名字就是我们脚本的文件名。然后在我们的脚本里面去找到以CrossEntropyCost为名字的class对象。这样就可以使用它了。

实例化一个network。将权重偏置,网络结构进行填充初始化,然后返回这个network。

应用案例—-进阶版本的前馈神经网络代码的手写数字识别

为了提高神经网络的学习速度,添加了参数初始化,添加了L2正则化项,添加了交叉熵cost。使用增加的这部分代码再来做一遍手写数字识别。来看一下准确率有没有提高

mark

我们首先多添加一些调试信息

每一轮结束之后,打印一下当前运行到了第几轮

            print("Epoch %s training complete" % j)

打印出当前的cost值在训练数据上的表现

            cost = self.total_cost(training_data, lmbda)
            print("Cost on training data: {}".format(cost))

打印一下网络预测的准确率在训练集上的表现是什么样的。

            accuracy = self.accuracy(training_data, convert=True)
            print("Accuracy on training data: {} / {}".format(accuracy, n))

增加两个函数,total_cost和accuracy(传入一个参数convert)

当然也可以看一下在测试集上的表现是什么样的

            if test_data:
                cost = self.total_cost(test_data, lmbda, convert=True)
                print("Cost on test data: {}".format(cost))
                accuracy = self.accuracy(test_data)
                print("Accuracy on test data: {} / {}".format(accuracy, len(test_data)))

测试数据在模型上的准确率是多少?

计算在训练集上的cost和准确率。计算在测试集上的cost和测试集上的准确率。

实现两个函数 total_cost 和 accuracy

之前我们已经有一个函数去计算准确率,evaluate改为accuracy

    def accuracy(self, data, convert=False):
        if convert:
            results = [(np.argmax(self.feedforward(x)), np.argmax(y))
                       for (x, y) in data]
        else:
            # 预测结果[0,1,2,3...]中最大的。然后再把真实值保存下来成为一对。 
            results = [(np.argmax(self.feedforward(x)), y)
                        for (x, y) in data]
        return sum(int(x == y) for (x, y) in results)

默认的convert为flase。通过判断convert来判断我们做什么事情?

为false就表示是测试数据集,我们就跟之前一样。

如果是训练数据集赋值是为真的。这个y有点变化。因为在训练集中的这个y不是一个实数,而是一个十维的向量。如果哪一维是真实的数据就会赋值成1.其他维全部为0[onehot]

定义一个计算损失的函数,兼容测试集和训练集两种,通过convert来区别

 def total_cost(self, data, lmbda, convert=False):
        cost = 0.0
        for x, y in data:
            a = self.feedforward(x)
            if convert: y = vectorized_result(y)
            cost += self.cost.fn(a, y)/len(data)
        cost += 0.5*(lmbda/len(data))*sum(
            np.linalg.norm(w)**2 for w in self.weights)
        return cost

如果它是真,就表示它是测试数据集。因为测试数据集这个y是一个实数。 我们要把它改变成一个onehot编码之后的数。

通过vectorized_result方法进行onehot编码

def vectorized_result(j):
    """Return a 10-dimensional unit vector with a 1.0 in the j'th position
    and zeroes elsewhere.  This is used to convert a digit (0...9)
    into a corresponding desired output from the neural network.

    """
    e = np.zeros((10, 1))
    e[j] = 1.0
    return e
if __name__ == '__main__':
    import mnist_loader

    traning_data, validation_data, test_data = mnist_loader.load_data_wrapper()

    # net = Network([784, 30, 10])
    # net.SGD(traning_data, 30, 10, 0.5, test_data=test_data)

    net = Network([784, 60, 10])
    net.SGD(traning_data, 30, 10, 0.5, 5.0, test_data=test_data)

训练结果

mark

mark

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏数据结构与算法

36:计算多项式的值

36:计算多项式的值 总时间限制: 1000ms 内存限制: 65536kB描述 假定多项式的形式为xn+xn-1+…+x2+x+1,请计算给定单精度浮点数x...

42111
来自专栏余林丰

9.动态规划(2)——子集和问题

注:因为对“子集和问题”的学习不够深入,所以本文在讲解动态规划递推公式中可能存在叙述不清,或者错误的地方,如有发现望能不吝赐教。   子集和问题可描述如下:给定...

2308
来自专栏深度学习那些事儿

pytorch中autograd以及hook函数详解

有些公式为图片,如果这个页面加载不出来,请看这里:https://oldpan.me/archives/pytorch-autograd-hook

85910
来自专栏marsggbo

Augmentor 使用介绍

<img src="https://ask.qcloudimg.com/draft/1215004/jfwdwyxm4.jpg" style="border:5...

4535
来自专栏量子位

数据载入过慢?这里有一份TensorFlow加速指南

王小新 编译自 Towards Data Science 量子位 出品 | 公众号 QbitAI 机器学习算法烂熟于心,网络结构顺手拈来,但是如果数据集载入时耗...

4548
来自专栏marsggbo

使用numpy解决图像维度变换问题

在机器学习中经常会碰到各种图像数据集,有的是按照num*height*width*channel来存储的,而有的则是num*channel*height*wid...

902
来自专栏C语言及其他语言

【编程经验】优秀题解

今天给大家带来一个我站“Manchester”大神写的一份优质题解(j解题思路很清晰):原题问题:1709: 算法7-16:弗洛伊德最短路径算法:

921
来自专栏WindCoder

求十个数中最大值和最小值-C++

1351
来自专栏人工智能LeadAI

TensorFlow官方教程翻译:导入数据

需要注意的是,如下教程的tf.data的模块需要将tensorflow升级到1.4的版本,才可以支持,低于1.4的版本的导入数据教程,见之前的翻译教程,戳这里(...

6466
来自专栏数据小魔方

左手用R右手Python系列——因子变量与分类重编码

今天这篇介绍数据类型中因子变量的运用在R语言和Python中的实现。 因子变量是数据结构中用于描述分类事物的一类重要变量。其在现实生活中对应着大量具有实际意义的...

3165

扫码关注云+社区