【深度学习】手写神经网络模型保存

开始

上篇写了如何手写神经网络,现在有如下三大需求:利用GPU加速,自动求导,保存读取模型。这里主要讲讲保存读取模型。GPU加速可以用 基于mxnet进行运算的minpy,或者是CuPy。

保存读取模型

这里使用一种较为简单的方法,直接保存训练后的网络对象到文件。学过Java的同学可能知道可以将对象实体固化到文件。这在Python中可以使用Python的pickle模块或者Python的shelve库实现。

具体如下

如何想使用shelve库实现可以参考如何将Python对象保存在本地文件中?

def save(self,path):
    obj = pickle.dumps(self)
    with open(path,"wb") as f:
        f.write(obj)

def load(path):
    obj = None
    with open(path, "rb") as f:
        try:
            obj = pickle.load(f)
        except:
            print("IOError")
    return obj

使用

# 读取训练数据
trainDataPath = "./trainingDigits"
trainMat, trainLabels = handwritingData(trainDataPath)
testDataPath = "./testDigits"
testMat, testLabels = handwritingData(testDataPath)
net = Net()
net.setLearnrate(0.01)
net.train(trainMat, trainLabels, Epoch=2000)
net.save("hr.model")
net.test(testMat, testLabels)

newmodel = Net.load("hr.model")
newmodel.test(testMat, testLabels)

在这里插入图片描述

完整代码

#!/usr/bin/python3
# coding:utf-8
# @Author: Lin Misaka
# @File: net.py
# @Data: 2020/11/30
# @IDE: PyCharm
from os import listdir
import numpy as np
import matplotlib.pyplot as plt
import pickle
# 函数img2vector将图像转换为向量
def img2vector(filename):
    returnVect = np.zeros((1, 1024))
    fr = open(filename)
    for i in range(32):
        lineStr = fr.readline()
        for j in range(32):
            returnVect[0, 32 * i + j] = int(lineStr[j])
    return returnVect


# 读取手写字体txt数据
def handwritingData(dataPath):
    hwLabels = []
    FileList = listdir(dataPath)  # 1 获取目录内容
    m = len(FileList)
    np.Mat = np.zeros((m, 1024))
    for i in range(m):
        # 2 从文件名解析分类数字
        fileNameStr = FileList[i]
        fileStr = fileNameStr.split('.')[0]  # take off .txt
        classNumStr = int(fileStr.split('_')[0])
        hwLabels.append(classNumStr)
        np.Mat[i, :] = img2vector(dataPath + '/%s' % fileNameStr)
    return np.Mat, hwLabels



# diff = True求导
def Sigmoid(x, diff=False):
    def sigmoid(x):        # sigmoid函数
        return 1 / (1 + np.exp(-x))
    def dsigmoid(x):
        f = sigmoid(x)
        return f * (1 - f)
    if (diff == True):
        return dsigmoid(x)
    return sigmoid(x)

# diff = True求导
def SquareErrorSum(y_hat, y, diff=False):
    if (diff == True):
        return y_hat - y
    return (np.square(y_hat - y) * 0.5).sum()


class Net():
    def __init__(self):
        # X Input
        self.X =  np.random.randn(1024, 1)
        self.W1 = np.random.randn(16, 1024)
        self.b1 = np.random.randn(16, 1)
        self.W2 = np.random.randn(16, 16)
        self.b2 = np.random.randn(16, 1)
        self.W3 = np.random.randn(10, 16)
        self.b3 = np.random.randn(10, 1)
        self.alpha = 0.01  #学习率
        self.losslist = [] #用于作图

    def forward(self, X, y, activate):
        self.X = X
        self.z1 = np.dot(self.W1, self.X) + self.b1
        self.a1 = activate(self.z1)
        self.z2 = np.dot(self.W2, self.a1) + self.b2
        self.a2 = activate(self.z2)
        self.z3 = np.dot(self.W3, self.a2) + self.b3
        self.y_hat = activate(self.z3)
        Loss = SquareErrorSum(self.y_hat, y)
        return Loss, self.y_hat

    def backward(self, y, activate):
        self.delta3 = activate(self.z3, True) * SquareErrorSum(self.y_hat, y, True)
        self.delta2 = activate(self.z2, True) * (np.dot(self.W3.T, self.delta3))
        self.delta1 = activate(self.z1, True) * (np.dot(self.W2.T, self.delta2))
        dW3 = np.dot(self.delta3, self.a2.T)
        dW2 = np.dot(self.delta2, self.a1.T)
        dW1 = np.dot(self.delta1, self.X.T)
        d3 = self.delta3
        d2 = self.delta2
        d1 = self.delta1
        #update weight
        self.W3 -= self.alpha * dW3
        self.W2 -= self.alpha * dW2
        self.W1 -= self.alpha * dW1
        self.b3 -= self.alpha * d3
        self.b2 -= self.alpha * d2
        self.b1 -= self.alpha * d1

    def setLearnrate(self, l):
        self.alpha = l

    def save(self,path):
        obj = pickle.dumps(self)
        with open(path,"wb") as f:
            f.write(obj)

    def load(path):
        obj = None
        with open(path, "rb") as f:
            try:
                obj = pickle.load(f)
            except:
                print("IOError")
        return obj

    def train(self, trainMat, trainLabels, Epoch=5, bitch=None):
        for epoch in range(Epoch):
            acc = 0.0
            acc_cnt = 0
            label = np.zeros((10, 1))#先生成一个10x1是向量,减少运算。用于生成one_hot格式的label
            for i in range(len(trainMat)):#可以用batch,数据较少,一次训练所有数据集
                X = trainMat[i, :].reshape((1024, 1)) #生成输入

                labelidx = trainLabels[i]
                label[labelidx][0] = 1.0

                Loss, y_hat = self.forward(X, label, Sigmoid)#前向传播
                self.backward(label, Sigmoid)#反向传播

                label[labelidx][0] = 0.0#还原为0向量
                acc_cnt += int(trainLabels[i] == np.argmax(y_hat))

            acc = acc_cnt / len(trainMat)
            self.losslist.append(Loss)
            print("epoch:%d,loss:%02f,accrucy : %02f%%" % (epoch, Loss, acc*100))
        self.plotLosslist(self.losslist, "Loss:Init->randn,alpha=0.01")

    def plotLosslist(self, Loss, title):
        font = {'family': 'simsun',
                'weight': 'bold',
                'size': 20,
                }
        m = len(Loss)
        X = range(m)
        # plt.figure(1)
        plt.subplots(nrows=1, ncols=1, figsize=(10, 8))
        plt.subplot(111)
        plt.title(title, font)
        plt.plot(X, Loss)
        plt.xlabel(r'Epoch', font)
        plt.ylabel(u'Loss', font)
        plt.show()

    def test(self, testMat, testLabels, bitch=None):
        acc = 0.0
        acc_cnt = 0
        label = np.zeros((10, 1))#先生成一个10x1是向量,减少运算。用于生成one_hot格式的label
        if(bitch == None):
            bitch = len(testMat)
        for i in range(bitch):#可以用batch,数据较少,一次训练所有数据集
            X = testMat[i, :].reshape((1024, 1)) #生成输入

            labelidx = testLabels[i]
            label[labelidx][0] = 1.0

            Loss, y_hat = self.forward(X, label, Sigmoid)#前向传播

            label[labelidx][0] = 0.0#还原为0向量
            acc_cnt += int(testLabels[i] == np.argmax(y_hat))
        acc = acc_cnt / bitch
        print("test num: %d, accrucy : %05.3f%%"%(bitch,acc*100))


# 读取训练数据
trainDataPath = "./trainingDigits"
trainMat, trainLabels = handwritingData(trainDataPath)
testDataPath = "./testDigits"
testMat, testLabels = handwritingData(testDataPath)
net = Net()
net.setLearnrate(0.01)
net.train(trainMat, trainLabels, Epoch=2000)
net.save("hr.model")
net.test(testMat, testLabels)

newmodel = Net.load("hr.model")
newmodel.test(testMat, testLabels)

参考

[1] 如何将Python对象保存在本地文件中?

链接失效Call我。
github:https://github.com/MisakaMikoto128
个人网站


pickle简单使用

在这里插入图片描述

下面部分转自:Ellison张 - 侵删

import pickle
class A:
    def __init__(self,name,a):
        self.name=name
        self.a=a
    def rewrite(self,args):
        self.a=args
'''

'''
#将对象使用pickle模块转换成二进制文件然后写入文件中
#但此种方法无法直接更新对象文件的信息
#此时存入文件的应该是对象本身而不是内存地址
obj1=A("qw","1")
obj1=pickle.dumps(obj1)
with open("userinfo","ab")as f:
    f.write(obj1)
obj2=A("qa","2")
obj2=pickle.dumps(obj2)
with open("userinfo","ab")as f:
    f.write(obj2)
obj3=A("qs","3")
obj3=pickle.dumps(obj3)
with open("userinfo","ab")as f:
    f.write(obj3)

#读取文件中的对象文件
#pickle.load()一次只读取一个对象文件
f=open("userinfo","rb")
while 1:
    try:
        obj = pickle.load(f)
        print(obj.a,obj)
    except:
        break
f.close()
f=open("userinfo","rb")
while 1:
    try:
        obj = pickle.load(f)
        print(obj.a,obj)
    except:
        break
f.close()

可以将对象放进列表中再写入文件
如需修改对象时,将列表中的对象修改后再放回列表中最后再重新写入文件中

使用Python的shelve库。

其和Python内置的数据结构“字典”操作很类似不同点是shelve存储在外部文件中而不是存储在计算机内存中。

import shelve
class A:
    def __init__(self,name,a):
        self.name=name
        self.a=a
    def rewrite(self,args):
        self.a=args
obj1=A("qw","1")
obj2=A("qa","2")
obj3=A("qs","3")
#写入文件
db=shelve.open("userinfo1")
db["qw"]=obj1
db["qa"]=obj2
db["qs"]=obj3
db.close()
#更新信息
db=shelve.open("userinfo1")
for k in db:
    print(db[k].a)
    a=db[k]
    a.a=12
    db[k]=a
db.close()
db=shelve.open("userinfo1")
for k in db:
    print(db[k].a)
db.close()

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 深度学习是当今计算机科学领域最为热门的研究方向之一,其在图像分类、语言识别、自然语言处理等诸多领域都有广泛的应用。而卷积神经网络(CNN)是深度学习中最为核心的模型之一,它能够有效地提取图像的特征并进行分类。本文将介绍如何使用matlab搭建卷积神经网络。 首先,我们需要准备好所需的数据集,这是构建卷积神经网络的必要条件。可以在网上找到一些现成的数据集,如MNIST数字数据集,CIFAR-10图像分类数据集等等。 接下来,我们需要创建一个卷积神经网络。在matlab中,可以使用Deep Learning Toolbox来创建卷积神经网络模型。我们需要指定网络的层数、每层的神经元个数、激活函数等参数,以及网络的损失函数、优化算法等参数。 然后,我们需要将数据集分成训练集和测试集,并将其加载到matlab的工作空间中。可以使用matlab自带的数据集加载函数或者自己编数据集加载函数来完成这一步骤。 接下来,我们需要对数据进行预处理,以便将其交给卷积神经网络进行训练。预处理包括图像的标准化、图像增强、数据扩充等操作。 最后,我们需要使用trainNetwork函数来训练我们的卷积神经网络,并使用testNetwork函数来测试网络的性能。网络训练完毕后,可以保存模型以备将来使用。 总的来说,用matlab进行卷积神经网络的搭建十分方便,并且matlab还提供了许多实用的工具箱和函数来辅助网络的训练和测试。若想深入研究深度学习,matlab是一个不错的选择。 ### 回答2: 深度学习是现代计算机科学的热门领域,它通过神经网络的层次结构来学习复杂的模式,特别是在图像、语音和自然语言处理上表现突出。Matlab是一种广泛用于数学建模、数据分析和科学计算的软件工具,也被用于深度学习领域。本文将介绍如何使用Matlab从零开始搭建卷积神经网络CNN。 首先,我们需要导入一些深度学习常用的库。例如 MatConvNet 和 VLFeat,这两个库都是由Matlab编的,方便用户在Matlab中实现卷积神经网络。接下来,我们需要构建神经网络模型,包括卷积层、池化层、全连接层等。这里,我们将使用卷积层、池化层交替的组合来搭建CNN模型,并设置相关的参数,例如数目、步长和大小等。 然后,我们需要准备好训练数据和测试数据,这些数据可以是图像、语音或文本等。我们需要将数据集进行预处理,例如归一化、预处理等,以确保数据数据量相等和格式标准化。接下来,我们需要定义模型的训练方法,例如使用反向传播算法以最小化误差和损失函数,而优化器可以选择常用的SGD、Adam或Adagrad等。 最后,我们需要对我们训练好的模型进行测试,测试过程中会给出一些输入样例,然后模型会输出对应的预测结果,我们可以根据这些结果来评估模型的性能和准确度。如果模型的性能不好,我们可以使用更多的层数、更多的节点或更多的数据来改善模型。 总之,使用Matlab搭建卷积神经网络的过程比较复杂,需要对深度学习的知识有一定的了解,并具备一定的程序能力。通过本文的介绍,相信读者能够初步了解到如何搭建卷积神经网络,并在实践中逐渐提高自己的能力。 ### 回答3: 在进行深度学习研究时,卷积神经网络(CNN)是一种非常常见的网络结构。使用Matlab可以高效地实现并训练CNN。下面将以一个简单的数字识别任务为例,从0开始介绍如何在Matlab中搭建和训练卷积神经网络。 首先需要导入数字数据集。在Matlab中已经内置了一个数字数据集,可以使用以下命令导入: ``` digitDatasetPath = fullfile(matlabroot,'toolbox','nnet','nndemos','nndatasets','DigitDataset'); imds = imageDatastore(digitDatasetPath, 'IncludeSubfolders', true, 'LabelSource', 'foldernames'); ``` 接下来,需要设置网络结构和超参数。这里选择一个包含两个卷积层和两个全连接层的CNN,同时设置学习率、迭代轮数等超参数。 ``` layers = [ imageInputLayer([28 28 1]) convolution2dLayer(3,16,'Padding','same') batchNormalizationLayer reluLayer maxPooling2dLayer(2,'Stride',2) convolution2dLayer(3,32,'Padding','same') batchNormalizationLayer reluLayer maxPooling2dLayer(2,'Stride',2) fullyConnectedLayer(256) batchNormalizationLayer reluLayer fullyConnectedLayer(10) softmaxLayer classificationLayer]; options = trainingOptions('adam', ... 'MaxEpochs',20,... 'MiniBatchSize',128, ... 'InitialLearnRate',0.001, ... 'Shuffle','every-epoch', ... 'Verbose',false, ... 'Plots','training-progress'); ``` 然后可以开始训练模型。使用以下命令可以开始训练: ``` net = trainNetwork(imds,layers,options); ``` 最后,可以使用测试集对训练好的模型进行评估,并计算出模型的准确率: ``` YPred = classify(net,augimdsTest); YTest = imdsTest.Labels; accuracy = sum(YPred == YTest)/numel(YTest); ``` 通过这个例子,可以看出使用Matlab搭建和训练卷积神经网络是非常简单的。同时,Matlab提供了许多预训练模型和工具箱,可以方便地进行深度学习研究和应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值