日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【mxnet速成】mxnet图像分类从模型自定义到测试

發布時間:2025/3/20 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【mxnet速成】mxnet图像分类从模型自定义到测试 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章首發于微信公眾號《與有三學AI》

【mxnet速成】mxnet圖像分類從模型自定義到測試

這是給大家準備的mxnet速成例子

這一次我們講講mxnet,相關的代碼、數據都在我們 Git 上,希望大家 Follow 一下這個 Git 項目,后面會持續更新不同框架下的任務。

https://github.com/longpeng2008/LongPeng_ML_Course

作者&編輯 | 言有三

?

01?mxnet是什么

mxnet是amazon的官方框架,下面參考mxnet的官方簡介

https://mxnet-bing.readthedocs.io/en/latest/zh/overview.html

深度學習系統通常有兩種編程方式,一種是聲明式編程(declarative programming),用戶只需要聲明要做什么,而具體執行則由系統完成。以Caffe,TensorFlow的計算圖為代表。優點是由于在真正開始計算的時候已經拿到了整個計算圖,所以可以做一系列優化來提升性能。實現輔助函數也容易,例如對任何計算圖都提供forward和backward函數,另外也方便對計算圖進行可視化,將圖保存到硬盤和從硬盤讀取。缺點是debug很麻煩,監視一個復雜的計算圖中的某個節點的中間結果并不簡單,邏輯控制也不方便。

一種是命令式編程(imperative programming),以numpy,torch/pytorch為代表,每個語句按照原來的意思順序執行。它 的特點是語義上容易理解,靈活,可以精確控制行為。通常可以無縫地和主語言交互,方便地利用主語言的各類算法,工具包,debug和性能調試器,但是實現統一的輔助函數和提供整體優化都很困難。

MXNet嘗試將兩種模式無縫的結合起來。在命令式編程上MXNet提供張量運算,進行模型的迭代訓練和更新中的控制邏輯;在聲明式編程中MXNet支持符號表達式,用來描述神經網絡,并利用系統提供的自動求導來訓練模型。

隨著pytorch的崛起,mxnet已經掉出前三梯隊,但不影響喜歡它的人使用。相比于重量級的tensorflow,mxnet非常輕量,占用內存少,分布式訓練方便,常被用于比賽刷榜(見筆者以前用來刷榜的文)。

如何步入深度學習刷榜第一重境界

?

02?mxnet安裝配置

喜歡自定義安裝和精確控制版本的朋友,可以自行編譯,喜歡偷懶的pip安裝即可,方便快捷。

sudo pip install mxnet

不過如果你要多機多卡使用,還是源碼編譯安裝吧。

https://github.com/apache/incubator-mxnet

?

03?mxnet自定義數據

下面就開始我們的任務,跟以往項目一樣,從自定義數據和自定義網絡開始。

mxnet分類任務要求的輸入分類文件的格式與caffe不一樣,為下面的格式,其中分別是序號,標簽,路徑

01../../../../../datas/mouth/1/182smile.jpg

11../../../../../datas/mouth/1/435smile.jpg

數據的載入需要用到接口DataBatch和DataIter

https://mxnet.incubator.apache.org/api/python/io/io.html

首先我們定義一下相關的參數配置,主要用于載入訓練/測試數據集路徑data-train,data-val,rgb均值rgb-mean,類別數目num-classes與訓練樣本集大小num-examples

def add_data_args(parser):

? ? data = parser.add_argument_group('Data', 'the input images')

? ? data.add_argument('--data-train', type=str, help='the training data')

? ? data.add_argument('--data-val', type=str, help='the validation data')

? ? data.add_argument('--rgb-mean', type=str, default='123.68,116.779,103.939',help='a tuple of size 3 for the mean rgb')

? ? data.add_argument('--pad-size', type=int, default=0,

help='padding the input image')

? ? data.add_argument('--image-shape', type=str,

help='the image shape feed into the network, e.g. (3,224,224)')

? ? data.add_argument('--num-classes', type=int,help='the number of classes')

? ? data.add_argument('--num-examples', type=int, help='the number of training examples')

? ? data.add_argument('--data-nthreads', type=int, default=4,help='number of threads for data decoding')

? ? data.add_argument('--benchmark', type=int, default=0,

help='if 1, then feed the network with synthetic data')

? ? data.add_argument('--dtype', type=str, default='float32',help='data type: float32 or float16')

? ? return data

然后,使用mx.img.ImageIter來載入圖像數據

?train = mx.img.ImageIter(

? ? ? ? label_width? ? ? ? ?= 1,

? ? ? ? path_root? ? = 'data/',?

? ? ? ? path_imglist? ? ? ? ?= args.data_train,

? ? ? ? data_shape? ? ? ? ? = (3, N_pix, N_pix),

? ? ? ? batch_size? ? ? ? ? = args.batch_size,

? ? ? ? rand_crop? ? ? ? ? ?= True,

? ? ? ? rand_resize? ? ? ? ?= True,

? ? ? ? rand_mirror? ? ? ? ?= True,

? ? ? ? shuffle? ? ? ? ? ? ?= True,

? ? ? ? brightness? ? ? ? ? = 0.4,

? ? ? ? contrast? ? ? ? ? ? = 0.4,

? ? ? ? saturation? ? ? ? ? = 0.4,

? ? ? ? pca_noise? ? ? ? ? ?= 0.1,

? ? ? ? num_parts? ? ? ? ? ?= nworker,

? ? ? ? part_index? ? ? ? ? = rank)

注意到上面配置了rand_crop,rand_resize,rand_mirror,shuffle,brightness,contrast,saturation,pca_noise等選項,這些就是常見的數據增強操作了,如果不懂,可以去看看我們以前的文章

[綜述類] 一文道盡深度學習中的數據增強方法(上)

【技術綜述】深度學習中的數據增強(下)

【開源框架】一文道盡主流開源框架中的數據增強

mxnet的數據增強接口使用非常的方便,定義如下

def add_data_aug_args(parser):

? ? aug = parser.add_argument_group(

? ? ? ? 'Image augmentations', 'implemented in src/io/image_aug_default.cc')

? ? aug.add_argument('--random-crop', type=int, default=1,help='if or not randomly crop the image')

? ? aug.add_argument('--random-mirror', type=int, default=1,help='if or not randomly flip horizontally')

? ? aug.add_argument('--max-random-h', type=int, default=0,help='max change of hue, whose range is [0, 180]')

? ? aug.add_argument('--max-random-s', type=int, default=0,help='max change of saturation, whose range is [0, 255]')

? ? aug.add_argument('--max-random-l', type=int, default=0,help='max change of intensity, whose range is [0, 255]')

? ? aug.add_argument('--max-random-aspect-ratio', type=float, default=0,help='max change of aspect ratio, whose range is [0, 1]')

? ? aug.add_argument('--max-random-rotate-angle', type=int, default=0,help='max angle to rotate, whose range is [0, 360]')

? ? aug.add_argument('--max-random-shear-ratio', type=float, default=0,help='max ratio to shear, whose range is [0, 1]')

? ? aug.add_argument('--max-random-scale', type=float, default=1,help='max ratio to scale')

? ? aug.add_argument('--min-random-scale', type=float, default=1,help='min ratio to scale, should >= img_size/input_shape. otherwise use --pad-size')

? ? return aug

可以看到level >= 1,就可以使用隨機裁剪,鏡像操作,level >= 2,就可以使用對比度變換操作,level >= 3,就可以使用旋轉,縮放等操作。

def set_data_aug_level(aug, level):

? ? if level >= 1:

? ? ? ? aug.set_defaults(random_crop=1, random_mirror=1)

? ? if level >= 2:

? ? ? ? aug.set_defaults(max_random_h=36, max_random_s=50, max_random_l=50)

? ? if level >= 3:

? ? ? ? aug.set_defaults(max_random_rotate_angle=10, max_random_shear_ratio=0.1, max_random_aspect_ratio=0.25)

?

04?mxnet網絡搭建

同樣是三層卷積,兩層全連接的網絡,話不多說,直接上代碼,使用到的api是mxnet.symbol

import mxnet as mx

def get_symbol(num_classes, **kwargs):
? ?if 'use_global_stats' not in kwargs:
? ? ? ?use_global_stats = False
? ?else:
? ? ? ?use_global_stats = kwargs['use_global_stats']

? ?data = mx.symbol.Variable(name='data')
? ?conv1 = mx.symbol.Convolution(name='conv1', data=data , num_filter=12, kernel=(3,3), stride=(2,2), no_bias=True)
? ?conv1_bn = mx.symbol.BatchNorm(name='conv1_bn', data=conv1 , use_global_stats=use_global_stats, fix_gamma=False, eps=0.000100)
? ?conv1_scale = conv1_bn
? ?relu1 = mx.symbol.Activation(name='relu1', data=conv1_scale , act_type='relu')
? ?conv2 = mx.symbol.Convolution(name='conv2', data=relu1 , num_filter=24, kernel=(3,3), stride=(2,2), no_bias=True)
? ?conv2_bn = mx.symbol.BatchNorm(name='conv2_bn', data=conv2 , use_global_stats=use_global_stats, fix_gamma=False, eps=0.000100)
? ?conv2_scale = conv2_bn
? ?relu2 = mx.symbol.Activation(name='relu2', data=conv2_scale , act_type='relu')
? ?conv3 = mx.symbol.Convolution(name='conv3', data=relu2 , num_filter=48, kernel=(3,3), stride=(2,2), no_bias=True)
? ?conv3_bn = mx.symbol.BatchNorm(name='conv3_bn', data=conv3 , use_global_stats=use_global_stats, fix_gamma=False, eps=0.000100)
? ?conv3_scale = conv3_bn
? ?relu3 = mx.symbol.Activation(name='relu3', data=conv3_scale , act_type='relu')
? ?pool = mx.symbol.Pooling(name='pool', data=relu3 , pooling_convention='full', global_pool=True, kernel=(1,1), pool_type='avg')
? ?fc = mx.symbol.Convolution(name='fc', data=pool , num_filter=num_classes, pad=(0, 0), kernel=(1,1), stride=(1,1), no_bias=False)
? ?flatten = mx.symbol.Flatten(data=fc, name='flatten')
? ?softmax = mx.symbol.SoftmaxOutput(data=flatten, name='softmax')
? ?return softmax

if __name__ == "__main__":
? ?net = get_symbol(2)? ##二分類任務
? ?net.save('simpleconv3-symbol.json')

最后我們可以將其存到json文件里,net.save('simpleconv3-symbol.json'),下面是conv1的部分,詳細大家可以至git查看

? ? {

? ? ? "op": "Convolution",?

? ? ? "name": "conv1",?

? ? ? "attr": {

? ? ? ? "kernel": "(3, 3)",?

? ? ? ? "no_bias": "True",?

? ? ? ? "num_filter": "12",?

? ? ? ? "stride": "(2, 2)"

? ? ? },?

? ? ? "inputs": [[0, 0, 0], [1, 0, 0]]

? ? },

?

05?模型訓練、測試

5.1 模型訓練

準備工作都做好了,訓練代碼非常簡潔,下面就是全部的代碼

import os
import argparse
import logging
logging.basicConfig(level=logging.DEBUG)
from common import find_mxnet
from common import data, fit
import mxnet as mx

import os, urllib

if __name__ == "__main__":
? ?parser = argparse.ArgumentParser(description="simple conv3 net",
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? formatter_class=argparse.ArgumentDefaultsHelpFormatter)
? ?train = fit.add_fit_args(parser)
? ?data.add_data_args(parser)
? ?aug = data.add_data_aug_args(parser)
? ?data.set_data_aug_level(parser, 1)
? ?parser.set_defaults(image_shape='3,48,48', num_epochs=200,
? ? ? ? ? ? ? ? ? ? ? ?lr=.001, wd=0)
? ?args = parser.parse_args()

? ?# define simpleconv3
? ?net = mx.sym.load('models/simple-conv3-symbol.json')
? ?print "net",net

? ?# train
? ?fit.fit(args ? ? ? ?= args,
? ? ? ? ? ?network ? ? = net,
? ? ? ? ? ?data_loader = data.get_rec_iter)

其中調用了fit接口定義優化目標和策略,我們只分析其中的核心代碼,首先是模型創建

? ?model = mx.mod.Module(
? ? ? ?context ? ? ? = devs,
? ? ? ?symbol ? ? ? ?= network
? ?)

然后是optimizer配置,默認使用adam

? ?optimizer_params = {
? ? ? ? ? ?'learning_rate': lr,
? ? ? ? ? ?'wd' : args.wd

? ?}

初始化

? ?initializer = mx.init.Xavier(rnd_type='gaussian', factor_type="in", magnitude=2.34)

最后是完整的接口

? ?model.fit(train,
? ? ? ?begin_epoch ? ? ? ?= args.load_epoch if args.load_epoch else 0,
? ? ? ?num_epoch ? ? ? ? ?= args.num_epochs,
? ? ? ?eval_data ? ? ? ? ?= val,
? ? ? ?eval_metric ? ? ? ?= eval_metrics,
? ? ? ?kvstore ? ? ? ? ? ?= kv,
? ? ? ?optimizer ? ? ? ? ?= args.optimizer,
? ? ? ?optimizer_params ? = optimizer_params,
? ? ? ?initializer ? ? ? ?= initializer,
? ? ? ?arg_params ? ? ? ? = arg_params,
? ? ? ?aux_params ? ? ? ? = aux_params,
? ? ? ?batch_end_callback = batch_end_callbacks,
? ? ? ?epoch_end_callback = checkpoint,
? ? ? ?allow_missing ? ? ?= True,
? ? ? ?monitor ? ? ? ? ? ?= monitor)

然后開始愉快的訓練吧

python train.py --gpus 0 \
? ?--data-train data/train.txt \
? ?--model-prefix 'models/simple-conv3' \
? ?--batch-size 80 --num-classes 2 --num-examples 900 2>&1 | tee log.txt

訓練模型會存為simple-conv3-epoch.params的格式。

5.2 訓練過程可視化

由于前面我們的tensorflow,pytorch,keras都使用了tensorborad進行可視化,mxnet也可以借助tensorboard進行可視化,只需要再設計一些mxnet接口即可。具體方法不再贅述,參考https://github.com/awslabs/mxboard

網絡結構的可視化則可用mx.viz.plot_network(sym).view()。

5.3 模型測試

使用mx.model.load_checkpoint載入預訓練的模型,如下

epoch = int(sys.argv[1]) #check point step
gpu_id = int(sys.argv[2]) #GPU ID for infer
prefix = sys.argv[3]
ctx = mx.gpu(gpu_id)
sym, arg_params, aux_params = mx.model.load_checkpoint(prefix, epoch)
arg_params, aux_params = ch_dev(arg_params, aux_params, ctx)

然后使用bind接口進行forward,具體操作如下

sym ?= mx.symbol.SoftmaxOutput(data = sym, name = 'softmax')? ? ? ?

img_full_name = os.path.join(imgdir,imgname)
img = cv2.cvtColor(cv2.imread(img_full_name), cv2.COLOR_BGR2RGB)
img = np.float32(img)
rows, cols = img.shape[:2]
resize_width = 48
resize_height = 48
img = cv2.resize(img, (resize_width, resize_height), interpolation=cv2.INTER_CUBIC)
h, w, _ = img.shape

img_crop = img[0:h,0:w] ##此處使用整圖
img_crop = np.swapaxes(img_crop, 0, 2)
img_crop = np.swapaxes(img_crop, 1, 2) ?# mxnet的訓練是rgb的順序輸入,所以需要調整為r,g,b訓練
img_crop = img_crop[np.newaxis, :]

arg_params["data"] = mx.nd.array(img_crop, ctx)
arg_params["softmax_label"] = mx.nd.empty((1,), ctx)
exe = sym.bind(ctx, arg_params ,args_grad=None, grad_req="null", aux_states=aux_params)
exe.forward(is_train=False)
probs = exe.outputs[0].asnumpy()

?

06 總結

好了,就這么多。到今天為止,主流的機器學習框架caffe,tensorflow,pytorch,paddlepaddle,keras,mxnet我們已經全部給大家提供了快速入門【文末提供了全部鏈接】。從自定義數據集,自定義網絡,到模型的訓練,可視化,測試,全套腳本都提供到了github上,歡迎star和fork。

?

同時,在我的知乎專欄也會開始同步更新這個模塊,歡迎來交流

https://zhuanlan.zhihu.com/c_151876233

注:部分圖片來自網絡

本系列完整文章:

第一篇:【caffe速成】caffe圖像分類從模型自定義到測試

第二篇:【tensorflow速成】Tensorflow圖像分類從模型自定義到測試

第三篇:【pytorch速成】Pytorch圖像分類從模型自定義到測試

第四篇:【paddlepaddle速成】paddlepaddle圖像分類從模型自定義到測試

第五篇:【Keras速成】Keras圖像分類從模型自定義到測試

第六篇:【mxnet速成】mxnet圖像分類從模型自定義到測試

第七篇:【cntk速成】cntk圖像分類從模型自定義到測試

第八篇:【chainer速成】chainer圖像分類從模型自定義到測試

第九篇:【DL4J速成】Deeplearning4j圖像分類從模型自定義到測試

第十篇:【MatConvnet速成】MatConvnet圖像分類從模型自定義到測試

第十一篇:【Lasagne速成】Lasagne/Theano圖像分類從模型自定義到測試

第十二篇:【darknet速成】Darknet圖像分類從模型自定義到測試

感謝各位看官的耐心閱讀,不足之處希望多多指教。后續內容將會不定期奉上,歡迎大家關注有三公眾號 有三AI

?

?

?

總結

以上是生活随笔為你收集整理的【mxnet速成】mxnet图像分类从模型自定义到测试的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。