1. 导入各种包

from mxnet import gluon
from mxnet.gluon import nn
import matplotlib.pyplot as plt
from mxnet import autograd as autograd
from mxnet import nd
import mxnet as mx
from collections import namedtuple
import random

2. 准备数据

使用和mnist很像的FashionMNIST数据集,使用Gluon下载

def transform(data,label):
return data.astype('float32')/255,label.astype('float32')
fashion_train = gluon.data.vision.FashionMNIST(root='./',train=True,transform=transform)
fashion_test = gluon.data.vision.FashionMNIST(root='./',train=True, transform=transform)
batch_size = 256
train_data = gluon.data.DataLoader(fashion_train,batch_size,shuffle=True)
test_data = gluon.data.DataLoader(fashion_test,batch_size,shuffle=True)

用于显示图像和标签

def show_images(images):
n = images.shape[0]
_, figs = plt.subplots(1, n, figsize=(15, 15))
for i in range(n):
figs[i].imshow(images[i].reshape((28, 28)).asnumpy())
figs[i].axes.get_xaxis().set_visible(False)
figs[i].axes.get_yaxis().set_visible(False)
plt.show()
def get_text_labels(label):
text_labels = [
't-shirt', 'trouser', 'pullover', 'dress,', 'coat',
'sandal', 'shirt', 'sneaker', 'bag', 'ankle boot'
]
return [text_labels[int(i)] for i in label]

看下数据集长啥样

data,label = fashion_train[5:19]
show_images(data)
print(get_text_labels(label))

['coat', 'coat', 'sandal', 'coat', 'bag', 't-shirt', 'bag', 'ankle boot', 't-shirt', 'pullover', 'pullover', 'ankle boot', 'dress,', 'dress,']

3. 精度计算函数

def accuracy(output, label):
return nd.mean(output.argmax(axis=1)==label).asscalar() def evaluate_accuracy(data_iterator, net):
acc = 0.
for data, label in data_iterator:
output = net(nd.transpose(data,(0,3,1,2)))
acc += accuracy(output, label)
return acc / len(data_iterator)

4. 定义网络

4.1 自己定义的层

Gluon模型转到Symbol下只能用HybridSequential模式,HybridSequential是静态图,会对计算有优化,不过HybridSequentialSequential可以很方便的转换,确切的就是一行代码的事。同样自定义的网络,要使用HybridBlock,和Block没有多大区别

class MyDense(nn.HybridBlock):
def __init__(self,**kwargs):
super(MyDense,self).__init__(**kwargs)
with self.name_scope():
self.dense0 = nn.Dense(256)
self.dense1 = nn.Dense(10)
def hybrid_forward(self,F,x): # 这里要使用hybrid_forward而不是forward,并且多了个参数F
return self.dense1(F.relu(self.dense0(x))) # F的作用就是替代 nd,如果是静态图,就是用 sym,否则使用 nd

4.2 使用自定义的层和自带的层组成完整的网络

网络定义和动态图一样,只不过把Sequential替换成了HybridSequential,在最后使用hybridize()会对静态图进行优化

net = nn.HybridSequential()
with net.name_scope():
net.add(gluon.nn.Conv2D(channels=20, kernel_size=5, activation='relu'))
net.add(gluon.nn.MaxPool2D(pool_size=2, strides=2))
net.add(gluon.nn.Conv2D(channels=50, kernel_size=3, activation='relu'))
net.add(gluon.nn.MaxPool2D(pool_size=2, strides=2))
net.add(gluon.nn.Flatten())
net.add(MyDense())
net.initialize(init=mx.init.Xavier())
net.hybridize()
net
HybridSequential(
(0): Conv2D(20, kernel_size=(5, 5), stride=(1, 1))
(1): MaxPool2D(size=(2, 2), stride=(2, 2), padding=(0, 0), ceil_mode=False)
(2): Conv2D(50, kernel_size=(3, 3), stride=(1, 1))
(3): MaxPool2D(size=(2, 2), stride=(2, 2), padding=(0, 0), ceil_mode=False)
(4): Flatten
(5): MyDense(
(dense0): Dense(256, linear)
(dense1): Dense(10, linear)
)
)

5. 训练

使用Adam优化算法,训练的速度会快点

softmax_cross_entropy = gluon.loss.SoftmaxCrossEntropyLoss()
trainer = gluon.Trainer(net.collect_params(), 'Adam', {'learning_rate': 0.008})
for epoch in range(5):
train_loss = 0.
train_acc = 0.
test_acc = 0.
for data, label in train_data:
data = nd.transpose(data,(0,3,1,2))
with autograd.record():
output = net(data)
loss = softmax_cross_entropy(output, label)
loss.backward()
trainer.step(batch_size) train_loss += nd.mean(loss).asscalar()
train_acc += accuracy(output, label) test_acc = evaluate_accuracy(test_data, net)
print("Epoch %d. Loss: %f, Train acc %f, Test acc %f" % (
epoch, train_loss/len(train_data), train_acc/len(train_data), test_acc))
Epoch 0. Loss: 0.498041, Train acc 0.817226, Test acc 0.865459
Epoch 1. Loss: 0.312128, Train acc 0.884813, Test acc 0.894265
Epoch 2. Loss: 0.274009, Train acc 0.898454, Test acc 0.898604
Epoch 3. Loss: 0.247741, Train acc 0.906521, Test acc 0.914910
Epoch 4. Loss: 0.226967, Train acc 0.913736, Test acc 0.914334

6. 保存成Symbol格式的网络和参数(重点)

要注意保存网络参数的时候,需要net.collect_params().save()这样保存,而不是net.save_params()保存

最新版的mxnet已经有可以导出到symbol格式下的接口了。需要mxnet版本在20171015以上

下面示例代码也已经改成新版的保存,加载方式

#新版本的保存方式
net.export('Gluon_FashionMNIST')

7. 使用Symbol加载网络并绑定

symnet = mx.symbol.load('Gluon_FashionMNIST-symbol.json')
mod = mx.mod.Module(symbol=symnet, context=mx.cpu())
mod.bind(data_shapes=[('data', (1, 1, 28, 28))])
mod.load_params('Gluon_FashionMNIST-0000.params')
Batch = namedtuple('Batch', ['data'])

8. 预测试试看效果

img,label = fashion_test[random.randint(0, 60000)]
data = img.transpose([2,0,1])
data = data.reshape([1,1,28,28])
mod.forward(Batch([data]))
out = mod.get_outputs()
prob = out[0]
predicted_labels = prob.argmax(axis=1) plt.imshow(img.reshape((28, 28)).asnumpy())
plt.axis('off')
plt.show()
print('predicted labels:',get_text_labels(predicted_labels.asnumpy())) print('true labels:',get_text_labels([label]))

predicted labels: ['pullover']
true labels: ['pullover']

MxNet新前端Gluon模型转换到Symbol的更多相关文章

  1. 使用MxNet新接口Gluon提供的预训练模型进行微调

    1. 导入各种包 from mxnet import gluon import mxnet as mx from mxnet.gluon import nn from mxnet import nda ...

  2. 前端MVVM框架avalon - 模型转换1

    轻量级前端MVVM框架avalon - 模型转换(一) 接上一章 ViewModel modelFactory工厂是如何加工用户定义的VM? 附源码 洋洋洒洒100多行内部是魔幻般的实现 1: fun ...

  3. 轻量级前端MVVM框架avalon - 模型转换

    接上一章 ViewModel modelFactory工厂是如何加工用户定义的VM? 附源码 洋洋洒洒100多行内部是魔幻般的实现 1: function modelFactory(scope) { ...

  4. 混合前端seq2seq模型部署

    混合前端seq2seq模型部署 本文介绍,如何将seq2seq模型转换为PyTorch可用的前端混合Torch脚本.要转换的模型来自于聊天机器人教程Chatbot tutorial. 1.混合前端 在 ...

  5. 【模型推理】Tengine 模型转换及量化

      欢迎关注我的公众号 [极智视界],回复001获取Google编程规范   O_o   >_<   o_O   O_o   ~_~   o_O   本文介绍一下 Tengine 模型转换 ...

  6. 将List 中的ConvertAll的使用:List 中的元素转换,List模型转换, list模型转数组

    一,直接入代码 using System; using System.Collections.Generic; using System.Linq; using System.Web; using S ...

  7. Blazor——Asp.net core的新前端框架

    原文:Blazor--Asp.net core的新前端框架 Blazor是微软在Asp.net core 3.0中推出的一个前端MVVM模型,它可以利用Razor页面引擎和C#作为脚本语言来构建WEB ...

  8. 看JQ时代过来的前端,如何转换思路用Vue打造选项卡组件

    前言 在Vue还未流行的时候,我们都是用JQuery来封装一个选项卡插件,如今Vue当道,让我们一起来看看从JQ时代过来的前端是如何转换思路,用数据驱动DOM的思想打造一个Vue选项卡组件. 接下来, ...

  9. tensorflow,object,detection,在model zoom,新下载的模型,WARNING:root:Variable [resnet_v1_50/block1/unit_3/bottleneck_v1/conv3/BatchNorm/gamma] is not available in checkpoint

    现象: WARNING:root:Variable [resnet_v1_50/block1/unit_1/bottleneck_v1/conv1/BatchNorm/beta] is not ava ...

随机推荐

  1. 交换机的Ethernet Channel

    端口聚合也叫做以太通道(ethernet channel),主要用于交换机之间连接.由于两个交换机之间有多条冗余链路的时候,STP会将其中的几条链路关闭,只保留一条,这样可以避免二层的环 路产生.但是 ...

  2. 201521123024《Java程序设计》第3周学习总结

    1. 本周学习总结 2. 书面作业 1.代码阅读 public class Test1 { private int i = 1;//这行不能修改 private static int j = 2; p ...

  3. 201521123112《Java程序设计》第1周学习总结

    1.本周学习总结 本周通过面授课和上机课,以及在课后通过对<Java学习笔记>前一二章的阅读,初步了解了Java在计算机领域中的重要性,以及Java为什么能够这么广泛的运用在编程中.通过上 ...

  4. lintcode.245 子树

    子树   描述 笔记 数据 评测 有两个不同大小的二进制树: T1 有上百万的节点: T2 有好几百的节点.请设计一种算法,判定 T2 是否为 T1的子树. 注意事项 若 T1 中存在从节点 n 开始 ...

  5. Oracle-表的字段增加修改删除操作

    表结构修改 ALTER TABLE SCOTT.TEST RENAME TO TEST1--修改表名 ALTER TABLE SCOTT.TEST RENAME COLUMN NAME TO NAME ...

  6. 利用ASCII码生成指定规则的字符串

    /** * 上送终端编号的后两位生成规则 总共可以生成 (36*36-1)1295个编号 * 01...09 0A...0Z * 10...19 1A...1Z * ............... * ...

  7. JDBC操作数据库之批处理

    JDBC开发中,操作数据库需要和数据库建立连接,然后将要执行的SQL语句发送到数据库服务器,最后关闭数据库连接,都是按照这样的操做的,如果按照此流程要执行多条SQL语句,那么就要建立多个数据库连接,将 ...

  8. C#关于通过反射PropertyType判读字符串类型方法

    今天在通过反射判读实体属性来映射数据库表是否修改的时候发现,最开始我通过 p.GetValue(entity) == null && p.PropertyType.IsValueTyp ...

  9. Download the Hibernate Tools

    首先去官网上下载最新版本的Hibernate Tools JBoss Tools 4.5.0.Final Requirements: Java 8 and Eclipse Oxygen 4.7 有 4 ...

  10. NDK调试

    第一种(控制台输出): 1.配置好环境变量,这是为了方便起见.将你sdk和ndk的根目录放到环境变量path中.配置完成之后可以来个小检测: 在命令行分别输入adb和ndk-stack后点击回车,只要 ...