Using pre-trained model in MXNet
import json
import matplotlib.pyplot as plt
import mxnet as mx
from mxnet import gluon, nd
from mxnet.gluon.model_zoo import vision
import numpy as np
%matplotlib inline
# matplotlib 的作用就是用plot()进行绘图的时候,或者生成一个figure画布的时候,可以直接在python
# console里面生成图像
# load the model
ctx = mx.cpu()
densenet121 = vision.densenet121(root='model/',pretrained=True,ctx=ctx)
mobileNet = vision.mobilenet0_5(root='model/',pretrained=True,ctx=ctx)
resnet18 = vision.resnet18_v1(root='model/',pretrained=True,ctx=ctx)
#查看网络结构
print(mobileNet)
MobileNet(
(features): HybridSequential(
(0): Conv2D(3 -> 16, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
(1): BatchNorm(axis=1, eps=1e-05, momentum=0.9, fix_gamma=False, use_global_stats=False, in_channels=16)
(2): Activation(relu)
(3): Conv2D(1 -> 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=16, bias=False)
(4): BatchNorm(axis=1, eps=1e-05, momentum=0.9, fix_gamma=False, use_global_stats=False, in_channels=16)
(5): Activation(relu)
(6): Conv2D(16 -> 32, kernel_size=(1, 1), stride=(1, 1), bias=False)
(7): BatchNorm(axis=1, eps=1e-05, momentum=0.9, fix_gamma=False, use_global_stats=False, in_channels=32)
(8): Activation(relu)
(9): Conv2D(1 -> 32, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), groups=32, bias=False)
(10): BatchNorm(axis=1, eps=1e-05, momentum=0.9, fix_gamma=False, use_global_stats=False, in_channels=32)
(11): Activation(relu)
(12): Conv2D(32 -> 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
(13): BatchNorm(axis=1, eps=1e-05, momentum=0.9, fix_gamma=False, use_global_stats=False, in_channels=64)
(14): Activation(relu)
(15): Conv2D(1 -> 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=64, bias=False)
(16): BatchNorm(axis=1, eps=1e-05, momentum=0.9, fix_gamma=False, use_global_stats=False, in_channels=64)
(17): Activation(relu)
(18): Conv2D(64 -> 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
(19): BatchNorm(axis=1, eps=1e-05, momentum=0.9, fix_gamma=False, use_global_stats=False, in_channels=64)
(20): Activation(relu)
(21): Conv2D(1 -> 64, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), groups=64, bias=False)
(22): BatchNorm(axis=1, eps=1e-05, momentum=0.9, fix_gamma=False, use_global_stats=False, in_channels=64)
(23): Activation(relu)
(24): Conv2D(64 -> 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
(25): BatchNorm(axis=1, eps=1e-05, momentum=0.9, fix_gamma=False, use_global_stats=False, in_channels=128)
(26): Activation(relu)
(27): Conv2D(1 -> 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=128, bias=False)
(28): BatchNorm(axis=1, eps=1e-05, momentum=0.9, fix_gamma=False, use_global_stats=False, in_channels=128)
(29): Activation(relu)
(30): Conv2D(128 -> 128, kernel_size=(1, 1), stride=(1, 1), bias=False)
(31): BatchNorm(axis=1, eps=1e-05, momentum=0.9, fix_gamma=False, use_global_stats=False, in_channels=128)
(32): Activation(relu)
(33): Conv2D(1 -> 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), groups=128, bias=False)
(34): BatchNorm(axis=1, eps=1e-05, momentum=0.9, fix_gamma=False, use_global_stats=False, in_channels=128)
(35): Activation(relu)
(36): Conv2D(128 -> 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(37): BatchNorm(axis=1, eps=1e-05, momentum=0.9, fix_gamma=False, use_global_stats=False, in_channels=256)
(38): Activation(relu)
(39): Conv2D(1 -> 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=256, bias=False)
(40): BatchNorm(axis=1, eps=1e-05, momentum=0.9, fix_gamma=False, use_global_stats=False, in_channels=256)
(41): Activation(relu)
(42): Conv2D(256 -> 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(43): BatchNorm(axis=1, eps=1e-05, momentum=0.9, fix_gamma=False, use_global_stats=False, in_channels=256)
(44): Activation(relu)
(45): Conv2D(1 -> 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=256, bias=False)
(46): BatchNorm(axis=1, eps=1e-05, momentum=0.9, fix_gamma=False, use_global_stats=False, in_channels=256)
(47): Activation(relu)
(48): Conv2D(256 -> 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(49): BatchNorm(axis=1, eps=1e-05, momentum=0.9, fix_gamma=False, use_global_stats=False, in_channels=256)
(50): Activation(relu)
(51): Conv2D(1 -> 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=256, bias=False)
(52): BatchNorm(axis=1, eps=1e-05, momentum=0.9, fix_gamma=False, use_global_stats=False, in_channels=256)
(53): Activation(relu)
(54): Conv2D(256 -> 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(55): BatchNorm(axis=1, eps=1e-05, momentum=0.9, fix_gamma=False, use_global_stats=False, in_channels=256)
(56): Activation(relu)
(57): Conv2D(1 -> 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=256, bias=False)
(58): BatchNorm(axis=1, eps=1e-05, momentum=0.9, fix_gamma=False, use_global_stats=False, in_channels=256)
(59): Activation(relu)
(60): Conv2D(256 -> 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(61): BatchNorm(axis=1, eps=1e-05, momentum=0.9, fix_gamma=False, use_global_stats=False, in_channels=256)
(62): Activation(relu)
(63): Conv2D(1 -> 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=256, bias=False)
(64): BatchNorm(axis=1, eps=1e-05, momentum=0.9, fix_gamma=False, use_global_stats=False, in_channels=256)
(65): Activation(relu)
(66): Conv2D(256 -> 256, kernel_size=(1, 1), stride=(1, 1), bias=False)
(67): BatchNorm(axis=1, eps=1e-05, momentum=0.9, fix_gamma=False, use_global_stats=False, in_channels=256)
(68): Activation(relu)
(69): Conv2D(1 -> 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), groups=256, bias=False)
(70): BatchNorm(axis=1, eps=1e-05, momentum=0.9, fix_gamma=False, use_global_stats=False, in_channels=256)
(71): Activation(relu)
(72): Conv2D(256 -> 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
(73): BatchNorm(axis=1, eps=1e-05, momentum=0.9, fix_gamma=False, use_global_stats=False, in_channels=512)
(74): Activation(relu)
(75): Conv2D(1 -> 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=512, bias=False)
(76): BatchNorm(axis=1, eps=1e-05, momentum=0.9, fix_gamma=False, use_global_stats=False, in_channels=512)
(77): Activation(relu)
(78): Conv2D(512 -> 512, kernel_size=(1, 1), stride=(1, 1), bias=False)
(79): BatchNorm(axis=1, eps=1e-05, momentum=0.9, fix_gamma=False, use_global_stats=False, in_channels=512)
(80): Activation(relu)
(81): GlobalAvgPool2D(size=(1, 1), stride=(1, 1), padding=(0, 0), ceil_mode=True, global_pool=True, pool_type=avg, layout=NCHW)
(82): Flatten
)
(output): Dense(512 -> 1000, linear)
)
#第一层的参数
print(mobileNet.features[0].params)
mobilenet2_conv0_ (
Parameter mobilenet2_conv0_weight (shape=(16, 3, 3, 3), dtype=<class 'numpy.float32'>)
)
#最后一层的参数
print(mobileNet.output)
Dense(512 -> 1000, linear)
#加载数据集
mx.test_utils.download('https://raw.githubusercontent.com/dmlc/web-data/master/mxnet/doc/tutorials/onnx/image_net_labels.json')
categories = np.array(json.load(open('image_net_labels.json', 'r')))
print(categories[4])
hammerhead, hammerhead shark
#加载一个测试图像;同样也可以自己上传一个图像
filename = mx.test_utils.download('https://github.com/dmlc/web-data/blob/master/mxnet/doc/tutorials/onnx/images/dog.jpg?raw=true', fname='dog.jpg')
print(filename)
dog.jpg
image = mx.image.imread(filename)
plt.imshow(image.asnumpy())
<matplotlib.image.AxesImage at 0x26418a9f240>
#自己上传的一个图像
file = 'lion.jpg'
image1 = mx.image.imread(file)
plt.imshow(image1.asnumpy())
<matplotlib.image.AxesImage at 0x26411f20940>
mxnet.image用于读取和处理图像的支持函数和迭代器
image.imdecode 将图像解码为NDarray多维数组对象
imgage.scale_down 如果尺寸大于图像尺寸,缩小裁剪尺寸
image.resize_short 将较短边调整到合适尺寸
image.fixed_crop 在固定的位置修剪图像,并选择性的调整它的大小
image.random_crop 随机修剪图像
image.center_crop 图像中心裁剪
image.color_normalize 用mean和std对图像进行归一化
image.random_size_crop 按尺寸随机修剪图像
image.CreateAugmenter 创建一个增加器列表
一个支持增加器的列表
image.Augmenter 图像增强基类
image.SequentialAug 组成一个连续的增强列表。
image.RandomOrderAug 将增量表随机打乱
image.ResizeAug 使短边调整到增量大小
#对图像进行数据增强
def transform(image):
resized = mx.image.resize_short(image,224)
cropped,crop_info = mx.image.center_crop(resized,(224,224))
normalized = mx.image.color_normalize(cropped.astype(np.float32)/255,
mean=mx.nd.array([0.485,0.456,0.406]),
std=mx.nd.array([0.229,0.224,0.225]))
# the network expect batches of the form (N,3,224,224)
# Transposing from (224, 224, 3) to (3, 224, 224)
# 矩阵转置操作;只是针对三位数组而言的
transposed = normalized.transpose((2,0,1))
# change the shape from (3, 224, 224) to (1, 3, 224, 224)
# 增添数组的维度
batchified = transposed.expand_dims(axis=0)
return batchified
#测试不同的网络
#网络最后一层要进行概率转换
predictions = resnet18(transform(image1)).softmax()
print(predictions.shape)
#采用top K 测试模型
top_pred = predictions.topk(k=3)[0].asnumpy()
print(top_pred)
#打印预测的类别与他们相应的概率
for index in top_pred:
probability = predictions[0][int(index)]
category = categories[int(index)]
print("{}: {:.2f}%".format(category,probability.asscalar()*100))
(1, 1000)
[291. 287. 260.]
lion, king of beasts, Panthera leo: 99.99%
lynx, catamount: 0.00%
chow, chow chow: 0.00%
#将上述所有的操作集成为一个函数
#参数:图像、模型、一个类别列表和要打印的top类别的数量
import time
def predict(model,image,categories,k):
start = time.time()
predictions = model(transform(image)).softmax()
top_pred = predictions.topk(k=k)[0].asnumpy()
for index in top_pred:
probability = predictions[0][int(index)]
category = categories[int(index)]
print("{}: {:.2f}%".format(category,probability.asscalar()*100))
print('')
end = time.time()
print("运行时间:%.2f秒"%(end-start))
#根据上面函数;测试DenseNet121
import time
start = time.time()
predict(densenet121,image,categories,3)
end = time.time()
print("运行时间:%.2f秒"%(end-start))
boxer: 94.77%
bull mastiff: 2.26%
American Staffordshire terrier, Staffordshire terrier, American pit bull terrier, pit bull terrier: 1.69%
运行时间:0.30秒
#MobileNet
predict(mobileNet,image1,categories,3)
lion, king of beasts, Panthera leo: 80.14%
otterhound, otter hound: 4.96%
Norfolk terrier: 2.34%
运行时间:0.11秒
#Resnet18
predict(resnet18,image1,categories,3)
lion, king of beasts, Panthera leo: 99.99%
lynx, catamount: 0.00%
chow, chow chow: 0.00%
运行时间:0.10秒
从上述运行的时间来看,网络速度越来越快!densenet121->mobilenet->resnet18
#上面是使用网络,下面进行微调预训练模型
#替换预先训练的模型的输出层,以适应自己图像分类任务的类数,例如10个类
num_classes = 10
# name_scope为了更好的管理变量的命名空间而提出的
# variable_scope 实现变量共享的功能
with resnet18.name_scope():
resnet18.output = gluon.nn.Dense(num_classes)
print(resnet18.output)
Dense(None -> 10, linear)
上述就是如何微调神经网络!