前言

在前面几篇文章中详细介绍了MXNet的一些特点以及入门基础知识,本篇文章主要介绍如何使用MXNet来训练模型加载模型进行预测预训练模型以及MXNet中GPU使用的相关知识。
在介绍训练模型之前,先介绍MXNet如何使用GPU,因为后面训练模型需要利用GPU来加速训练

MXNet的GPU使用

在训练神经网络的时候,为了获取一个效果比较好的模型通常都需要上万级,甚至上亿级的数据量,所以这需要强大的计算力,通过使用GPU能极大的提升计算机的运算速度,减少训练时间。所以深度学习框架都会支持GPU,不过目前MXNet只支持NVIDA GPU,还不支持AMD GPUIntel GPU。如果想要安装MXNet GPU版本则需要先安装CudaCudnn,具体安装方法在这里我就不详细介绍了

  • 安装gpu的mxnet
    windows系统请打开cmd输入nvcc --version可以看到如下信息

    通过上图可以看出Cuda的版本是9.0的,所以在安装MXNet GPU版本请用pip install mxnet-cu90进行安装
    如果是Ubuntu系统通过nvidia-smi命令查看Cuda的版本,然后再通过pip命令安装即可
    注意:安装的MXNet的版本与cuda的版本不相符合,会导致报cuda* lib not found的错误
  • 查看电脑有几个GPU
    可以通过mxnet的test_utils包进行查看,代码如下
import mxnet as mx#查看GPU的个数
mx.test_utils.list_gpus()
range(0, 0)

通过结果可以发现,我的电脑上只有一个GPU,除此之外,还可以通过mxnet在创建NDArray时,调用不同的GPU,如果这个GPU不存在就会抛异常的特性来查看GPU的数量

for i in range(10):try:#通过ctx参数来选择GPUmx.nd.zeros((1,),ctx=mx.gpu(i))except:print("GPU num:%d"%i)break
GPU num:1
  • 在GPU上创建NDArray
    通过ctx参数可以指定数组创建在哪个GPU上,默认是GPU0,没有指定ctx参数,默认是使用CPU
#使用GPU创建NDArray
mx.nd.ones((3,4),ctx=mx.gpu())
[[1. 1. 1. 1.][1. 1. 1. 1.][1. 1. 1. 1.]]
<NDArray 3x4 @gpu(0)>
  • GPU的通信
    使用MXNet也很容易的再多个GPU之间进行通信,将某个数据拷贝到另一个GPU上,只需要执行以下代码即可,其中x表示的是NDArray
    注意:电脑没有1个以上GPU执行以下代码会报错
x.copyto(gpu(1))

可视化分析数据

在之前的文章中有介绍过,如何使用MXNet的gluon模块来创建一个神经网络,这里我们将详细介绍怎么样来训练网络,将会介绍如何利用mxnet.init来初始化权重参数,利用datasetstansforms来加载和转换数据,通过matplotlib来可视化数据,通过time来统计计算时间

  • 导包
#导入相关包
from mxnet import nd,gluon,autograd,init
from mxnet.gluon import nn
from mxnet.gluon.data.vision import datasets,transforms
from IPython import display
import matplotlib.pyplot as plt
import time
  • 加载数据
    通过gluon.data.vision.datasets来自动的下载数据集,本次主要是构建一个分类网络,来实现FasionMNIST数据集的分类,该数据集主要包含了一些服装的类别,相对于MNIST数据集来说,分类难度稍微要大一些,接下来我们先来下载数据集。训练集一共包含了60000张图片,每张图片的大小为28*28,一共有十种类别
#下载FashionMNIST数据集
fashionMNIST_trian = datasets.FashionMNIST(train=True)
#获取图标和对应的标签
images,labels = fashionMNIST_trian[:]
#获取数据的大小
#一共有60000张图片,图片大小是28*28
print(images.shape,labels.shape)  #(60000, 28, 28, 1) (60000,)
#输出类别标签,类别标签是由0-9组成的类别,分别对应不同的服装类型
print(labels[0])   #2
  • 显示数据
    从训练集中挑选出25张图片来进行可视化显示,便于更好的了解数据
def plot_show():#设置每个类标的标签text_labels = ["t-shirt","trouser","pullover","dress","coat","sandal","shirt","sneaker","bag","ankle boot"]#从训练集中选25个图像可视化part_images,part_labels = images[:25],labels[:25]display.set_matplotlib_formats("svg")_,figs = plt.subplots(5,5,figsize=(15,15))for row in range(5):for col in range(5):f = figs[row][col]#将3D图片数据转为2D便于可视化f.imshow(part_images[row*5+col].reshape((28,28)).asnumpy())ax = f.axes#设置标题ax.set_title(text_labels[int(part_labels[row*5+col])])#设置字体大小ax.title.set_fontsize(14)#隐藏坐标轴ax.get_xaxis().set_visible(False)ax.get_yaxis().set_visible(False)plt.show()

训练模型

在之前的文章中有介绍过使用gluon来构建模型,这里我们将详细介绍如何利用gluo来训练、加载、预训练模型

  • 转换数据
    在前面可视化数据的时候介绍了通过gluon.vision.datasets来加载数据,在使用gluon构建模型的时候需要使用到这些数据,模型训练的时候对于数据的格式有一定的要求(channel,height,width)并且要求数据是浮点类型。所以,我们还需要对之前的数据做一些转换。利用transforms可以很方便的实现数据的转换
#transforms链式转换数据
transformer = transforms.Compose([transforms.ToTensor(),transforms.Normalize(0.13,0.31)])
#转换数据
fashion_data = fashion_train_data.transform_first(transformer)

通过ToTensor方法可以将图片数据转为(channel,height,width)float类型的数据,通过Normalize方法可以设置数据的均值标准差,这里将图片的均值设置为0.13,标准差设置为0.31,最后再通过Compose将这些数据转换过程组合成一个链式的处理。
由于内存的限制,在训练模型的时候通常都是指定一个batch的数据进行迭代训练,所以我们还需要将整个数据转成一个batch迭代器,每次从这个迭代器中取一个batch数据进行训练,gluon提供了一个DataLoader可以实现,而且通过num_workers参数来设置多个线程进行并行处理,但是在windows上测试的时候请将这个参数设置为0,避免线程错误问题

#设置batch的大小
batch_size = 256
#在windows系统上,请将num_workers设置为0,否则会导致线程错误
train_data = gluon.data.DataLoader(fashion_data
,batch_size=batch_size,shuffle=True,num_workers=0)
#每次从tran_data中取出一个batch大小的数据
for data,label in train_data:print(data.shape,label.shape)#(256, 1, 28, 28) (256,)break
  • 训练模型保存模型文件
    使用gluon来构建一个LeNet的网络结构,然后利用MXNet提供的GPU加速来训练模型。MXNet可以很方便就能够支持多个GPU同时加速训练,在使用GPU加速训练的时候,需要特别注意需要将参数和数据都放在GPU上,否则会出现错误
    训练完成之后,保存模型文件的时候,MXNet提供了两种不同的方式,在保存模型文件的时候,可以选择只保存参数同时保存参数和模型结构,通常参数是保存在.params文件中,模型结构是保存在.json文件中。如果只保存了参数,在加载模型的时候,则需要事先定义好网络结构给网络的参数赋值。如果有.json文件,则不需要定义网络的结构,直接通过.josn文件加载即可。
#加载验证数据
fashion_val_data = gluon.data.vision.FashionMNIST(train=False)
val_data = gluon.data.DataLoader(fashion_val_data.transform_first(transformer),batch_size=batch_size,num_workers=0)
#定义使用的GPU,使用GPU加速训练,如果有多个GPU,可以定义多个
gpu_devices = [mx.gpu(0)]
#定义网络结构
LeNet = nn.Sequential()
#构建一个LeNet的网络结构
LeNet.add(nn.Conv2D(channels=6,kernel_size=5,activation="relu"),nn.MaxPool2D(pool_size=2,strides=2),nn.Conv2D(channels=16,kernel_size=3,activation="relu"),nn.MaxPool2D(pool_size=2,strides=2),nn.Flatten(),nn.Dense(120,activation="relu"),nn.Dense(84,activation="relu"),nn.Dense(10)
)#初始化神经网络的权重参数,使用GPU来加速训练
LeNet.collect_params().initialize(force_reinit=True,ctx=gpu_devices)
#定义softmax损失函数
softmax_cross_entropy = gluon.loss.SoftmaxCrossEntropyLoss()
#设置优化算法,使用随机梯度下降sgd算法,学习率设置为0.1
trainer = gluon.Trainer(LeNet.collect_params(),"sgd",{"learning_rate":0.1})
#计算准确率
def acc(output,label):return (output.argmax(axis=1) == label.astype("float32")).mean().asscalar()#设置迭代的轮数
epochs = 10
#训练模型
for epoch in range(epochs):train_loss,train_acc,val_acc = 0,0,0epoch_start_time = time.time()for data,label in train_data:#使用GPU来加载数据加速训练data_list = gluon.utils.split_and_load(data,gpu_devices)label_list = gluon.utils.split_and_load(label,gpu_devices)#前向传播with autograd.record():#获取多个GPU上的预测结果pred_Y = [LeNet(x) for x in data_list]#计算多个GPU上预测值的损失losses = [softmax_cross_entropy(pred_y,Y) for pred_y,Y in zip(pred_Y,label_list)]#反向传播更新参数for l in losses:l.backward()trainer.step(batch_size)#计算训练集上的总损失train_loss += sum([l.sum().asscalar() for l in losses])#计算训练集上的准确率train_acc += sum([acc(output_y,y) for output_y,y in zip(pred_Y,label_list)])for data,label in val_data:data_list = gluon.utils.split_and_load(data,ctx_list=gpu_devices)label_list = gluon.utils.split_and_load(label,ctx_list=gpu_devices)#计算验证集上的准确率val_acc += sum(acc(LeNet(val_X),val_Y) for val_X,val_Y in zip(data_list,label_list))print("epoch %d,loss:%.3f,train acc:%.3f,test acc:%.3f,in %.1f sec"%(epoch+1,train_loss/len(labels),train_acc/len(train_data),val_acc/len(val_data),time.time()-epoch_start_time))
#保存模型参数
LeNet.save_parameters("LeNet.params")

  • 保存网络结构和参数文件
    想要同时将模型参数模型结构保存为文件,其实也很简单,只需要修改上面几行代码即可,将nn.Sequential修改为nn.HybridSequential,然后再添加LeNet.hybridize(),将最后保存模型文件的代码由save_parameters方法改为export,具体代码如下
import mxnet as mx
from mxnet.gluon import nn
from mxnet import gluon,nd,autograd,init
from mxnet.gluon.data.vision import datasets,transforms
from IPython import display
import matplotlib.pyplot as plt
import time
import numpy as np#下载fashionMNIST数据集
fashion_train_data = datasets.FashionMNIST(train=True)
#获取图片数据和对应的标签
images,labels = fashion_train_data[:]#transforms链式转换数据
transformer = transforms.Compose([transforms.ToTensor(),transforms.Normalize(0.13,0.31)])
#转换数据
fashion_data = fashion_train_data.transform_first(transformer)#设置batch的大小
batch_size = 256
#在windows系统上,请将num_workers设置为0,否则会导致线程错误
train_data = gluon.data.DataLoader(fashion_data,batch_size=batch_size,shuffle=True,num_workers=0)#加载验证数据
fashion_val_data = gluon.data.vision.FashionMNIST(train=False)
val_data = gluon.data.DataLoader(fashion_val_data.transform_first(transformer),batch_size=batch_size,num_workers=0)
#定义使用的GPU,使用GPU加速训练,如果有多个GPU,可以定义多个
gpu_devices = [mx.gpu(0)]
#定义网络结构
LeNet = nn.HybridSequential()
#构建一个LeNet的网络结构
LeNet.add(nn.Conv2D(channels=6,kernel_size=5,activation="relu"),nn.MaxPool2D(pool_size=2,strides=2),nn.Conv2D(channels=16,kernel_size=3,activation="relu"),nn.MaxPool2D(pool_size=2,strides=2),nn.Flatten(),nn.Dense(120,activation="relu"),nn.Dense(84,activation="relu"),nn.Dense(10)
)
LeNet.hybridize()
#初始化神经网络的权重参数,使用GPU来加速训练
LeNet.collect_params().initialize(force_reinit=True,ctx=gpu_devices)
#定义softmax损失函数
softmax_cross_entropy = gluon.loss.SoftmaxCrossEntropyLoss()
#设置优化算法,使用随机梯度下降sgd算法,学习率设置为0.1
trainer = gluon.Trainer(LeNet.collect_params(),"sgd",{"learning_rate":0.1})
#计算准确率
def acc(output,label):return (output.argmax(axis=1) == label.astype("float32")).mean().asscalar()#设置迭代的轮数
epochs = 10
#训练模型
for epoch in range(epochs):train_loss,train_acc,val_acc = 0,0,0epoch_start_time = time.time()for data,label in train_data:#使用GPU来加载数据加速训练data_list = gluon.utils.split_and_load(data,gpu_devices)label_list = gluon.utils.split_and_load(label,gpu_devices)#前向传播with autograd.record():#获取多个GPU上的预测结果pred_Y = [LeNet(x) for x in data_list]#计算多个GPU上预测值的损失losses = [softmax_cross_entropy(pred_y,Y) for pred_y,Y in zip(pred_Y,label_list)]#反向传播更新参数for l in losses:l.backward()trainer.step(batch_size)#计算训练集上的总损失train_loss += sum([l.sum().asscalar() for l in losses])#计算训练集上的准确率train_acc += sum([acc(output_y,y) for output_y,y in zip(pred_Y,label_list)])for data,label in val_data:data_list = gluon.utils.split_and_load(data,ctx_list=gpu_devices)label_list = gluon.utils.split_and_load(label,ctx_list=gpu_devices)#计算验证集上的准确率val_acc += sum(acc(LeNet(val_X),val_Y) for val_X,val_Y in zip(data_list,label_list))print("epoch %d,loss:%.3f,train acc:%.3f,test acc:%.3f,in %.1f sec"%(epoch+1,train_loss/len(labels),train_acc/len(train_data),val_acc/len(val_data),time.time()-epoch_start_time))
#保存模型参数
LeNet.export("lenet",epoch=1)#加载模型文件
LeNet = gluon.nn.SymbolBlock.imports("lenet-symbol.json",["data"],"lenet-0001.params")

加载预训练模型

在上面介绍了如何来训练模型,并且保存模型文件,我们可以利用已经保存好的模型文件来做很多事情,如直接加载好训练好的模型文件来预测数据利用模型文件来进行微调等。

from mxnet.gluon import nn
from mxnet.gluon.data.vision import datasets,transforms
from IPython import display
import matplotlib.pyplot as plt#构建模型
LeNet = nn.Sequential()
#注意模型的结果必须与训练时的模型结构一模一样
LeNet.add(nn.Conv2D(channels=6,kernel_size=5,activation="relu"),nn.MaxPool2D(pool_size=2,strides=2),nn.Conv2D(channels=16,kernel_size=3,activation="relu"),nn.MaxPool2D(pool_size=2,strides=2),nn.Flatten(),nn.Dense(units=120,activation="relu"),nn.Dense(84,activation="relu"),nn.Dense(10)
)
#加载模型
LeNet.load_parameters("LeNet.params")
#构建一个数据转换器
transformer = transforms.Compose([transforms.ToTensor(),transforms.Normalize(0.13,0.31)
])
#获取数据
mnist_valid = datasets.FashionMNIST(train=False)
X,Y = mnist_valid[:10]
preds = []
for x in X:x = transformer(x).expand_dims(axis=0)#获取预测结果pred = LeNet(x).argmax(axis=1)preds.append(pred.astype("int32").asscalar())_,figs = plt.subplots(1,10,figsize=(15,15))
text_labels = ['t-shirt', 'trouser', 'pullover', 'dress', 'coat','sandal', 'shirt', 'sneaker', 'bag', 'ankle boot']
display.set_matplotlib_formats("svg")
for f,x,y,pred_y in zip(figs,X,Y,preds):f.imshow(x.reshape((28,28)).asnumpy())ax = f.axes#显示图片的真实标签和预测标签ax.set_title(text_labels[y]+"\n"+text_labels[pred_y])#设置字体ax.title.set_fontsize(14)#隐藏坐标轴ax.get_xaxis().set_visible(False)ax.get_yaxis().set_visible(False)
plt.show()

从Gluon model zoo加载预训练模型

Gluon model zoo提供了非常多的预训练模型(AlexNet、DenseNet、Inception、ResNet、MobileNet等),都是基于ImageNet数据训练的,我们可以很方便的去加载这些模型,然后在我们自己的数据上进行微调,以获取一个适合自己数据的模型。

from mxnet.gluon.model_zoo import vision as models
from mxnet.gluon.utils import download
from mxnet import image,nd
import matplotlib.pyplot as plt#加载一个ResNet v2模型
net = models.resnet50_v2(pretrained=True)
#从网络上下载imageNET的标签名称
url = 'http://data.mxnet.io.s3-website-us-west-1.amazonaws.com/models/imagenet/synset.txt'
fname = download(url)
with open(fname, 'r') as f:text_labels = [' '.join(l.split()[1:]) for l in f]
#获取网络上的图片
url = 'https://upload.wikimedia.org/wikipedia/commons/thumb/b/b5/\
Golden_Retriever_medium-to-light-coat.jpg/\
365px-Golden_Retriever_medium-to-light-coat.jpg'
fname = download(url)
x = image.imread(fname)
#将图片的短边缩放为256个像素
x = image.resize_short(x, 256)
#从图片中心随机裁剪一个224大小的图片
x, _ = image.center_crop(x, (224,224))
#显示图片
# plt.imshow(x.asnumpy())
# plt.show()
#转换数据
def transform(data):data = data.transpose((2,0,1)).expand_dims(axis=0)rgb_mean = nd.array([0.485, 0.456, 0.406]).reshape((1,3,1,1))rgb_std = nd.array([0.229, 0.224, 0.225]).reshape((1,3,1,1))#设置图片的均值和方差return (data.astype('float32') / 255 - rgb_mean) / rgb_std
#获取预测图片的结果
prob = net(transform(x)).softmax()
#获取top5的结果
idx = prob.topk(k=5)[0]
for i in idx:i = int(i.asscalar())print('With prob = %.5f, it contains %s' % (prob[0,i].asscalar(), text_labels[i]))

MXNet快速入门之训练加载预训练模型(四)相关推荐

  1. pytorch:加载预训练模型(多卡加载单卡预训练模型,多GPU,单GPU)

    在pytorch加载预训练模型时,可能遇到以下几种情况. 分为以下几种 在pytorch加载预训练模型时,可能遇到以下几种情况. 1.多卡训练模型加载单卡预训练模型 2. 多卡训练模型加载多卡预训练模 ...

  2. keras冻结_Keras 实现加载预训练模型并冻结网络的层

    在解决一个任务时,我会选择加载预训练模型并逐步fine-tune.比如,分类任务中,优异的深度学习网络有很多. ResNet, VGG, Xception等等... 并且这些模型参数已经在imagen ...

  3. 加载预训练模型时报错 KeyError: param ‘initial_lr‘ is not specified in param_groups[0]

    在加载预训练模型继续训练时,程序报错:KeyError: "param 'initial_lr' is not specified in param_groups[0] when resum ...

  4. Pytorch网络模型权重初始化、保存与加载模型、加载预训练模型、按需设置学习率

    前言 在我们对神经网络模型进行训练时,往往需要对模型进行初始化或者加载预训练模型.本文将对模型的权重初始化与加载预训练模型做一个学习记录,以便后续查询使用. 权重初始化 常见的初始化方法 PyTorc ...

  5. Caffe2教程实例,加载预训练模型

    Caffe2教程实例,加载预训练模型 概述 本教程使用模型库中的预训练模型squeezenet 里分类我们自己的图片.我们需要提供要分类图片的路径或者URL信息作为输入.了解ImageNet对象代码可 ...

  6. HuggingFace学习3:加载预训练模型完成机器翻译(中译英)任务

    加载模型页面为:https://huggingface.co/liam168/trans-opus-mt-zh-en 文章目录 整理文件 跑通程序,测试预训练模型 拆解Pipeline,逐步进行翻译任 ...

  7. 解决HuggingFace加载预训练模型时报错TypeError: expected str, bytes or os.PathLike object, not NoneType

    完整报错: TypeError: expected str, bytes or os.PathLike object, not NoneType 解决方法 检查下载的组件: 步骤1:完整的下载组件,包 ...

  8. pytorch加载预训练模型_Pytorch-Transformers 1.0发布,支持六个预训练框架,含27个预训练模型...

    AI 科技评论按:刚刚在Github上发布了开源 Pytorch-Transformers 1.0,该项目支持BERT, GPT, GPT-2, Transfo-XL, XLNet, XLM等,并包含 ...

  9. pytorch加载预训练模型遇到的问题:KeyError: ‘bn1.num_batches_tracked‘

    问题 最近在使用pytorch1.0加载resnet预训练模型时,遇到的一个问题,在此记录一下.     KeyError: 'layer1.0.bn1.num_batches_tracked' 其实 ...

最新文章

  1. 剑指offer:旋转数组的最小数字
  2. javascript 模块化编程----模块的写法
  3. android资源的热更新(替换 AssetManager+LoadedApk中的资源路径)
  4. fcn网络训练代码_用FCN做分割
  5. 从函数中返回多个值的方法
  6. Java实现qq截图工具
  7. Zookeeper3.6.1常用的Shell命令
  8. 赋能时空云计算,阿里云数据库时空引擎Ganos上线
  9. 在GlassFish应用服务器上创建并运行你的第一个Restful Web Service【翻译】
  10. python字典常见操作
  11. dota5显示正在连接协调服务器,win10系统打开dota2提示已连接至DOTA2游戏协调服务器正在登陆中如何解决...
  12. Win10设置内存压缩
  13. 软件测试面试题:所有的软件缺陷都能修复吗?所有的软件缺陷都要修复吗?
  14. 给出三个坐标点,求三角形周长。
  15. LeetCode——缺失数字(C语言)
  16. 电脑开机时多出来个 Windows PE 操作系统选项? 如何去除掉?
  17. Java二维数组声明与初始化
  18. 《笨方法学python》第五天
  19. PCB这个工艺,免费了!
  20. 【论文阅读】TRO2022: A Two-Stage Optimization-Based Motion Planner for Safe Urban Driving

热门文章

  1. NX二次开发 查找错误_dll执行函数时捕获到异常
  2. linux 命令行 time,Linux 命令行日常交互篇
  3. iOS开发创建苹果证书、制作p12证书流程
  4. 探索互联网工具的奇妙世界
  5. MOS管的GS波形分析,教你如何消除MOS管的GS波形振荡~
  6. Matlab信号处理常用函数
  7. 怎么快速查询UPS多个单号物流信息
  8. 哲学家用餐问题——多线程死锁问题
  9. 武汉凯迪正大KD305系列智能数字绝缘电阻测试仪
  10. Altium Designer 20 凡亿教育视频学习-05