MXNet:迁移学习与图像分类实践

质量声明:原创文章,内容质量问题请评论吐槽。如对您产生干扰,可私信删除。
主要参考:李沐等:动手学深度学习-伯克利教材; GluonCV官网



摘要: MXNet实践: 以迁移学习的方法,微调 ResNet 进行12品种的猫分类.


迁移学习

虽然深度网络适用的数据集并不相同,但模型抽取的图像特征都是比较通用的,如边缘、纹理、形状和物体组成等,这些类似的特征对于其他场景或者目标可能也同样有效。迁移学习(transfer learning),就是将从源数据集学到的知识迁移到⽬标数据集上。微调(fine tuning)是迁移学习中的⼀种常⽤技术。假设模型在源数据集上学到的知识同样适用于目标数据集,且源模型输出层与源数据集标签紧密相关,从头训练输出层,而其余层参数由源模型参数微调得到当目标数据集远小于源数据集时,微调有助于提升模型的泛化能力。微调步骤如下:

  1. 在源数据集(如ImageNet数据集)上预训练一个源模型
  2. 通过复制源模型的结构和参数(除了输出层)创建目标模型
  3. 为目标模型添加类别匹配的输出层,并随机初始化该层的模型参数
  4. 在目标数据集上训练目标模型

在这里插入图片描述

gluonCV

推荐阅读GluonCV的缘来和简介:李沐:GluonCV — 计算机视觉的深度学习工具包

项目实践:预训练模型直接预测图像分类

from mxnet import nd, image
from gluoncv.data.transforms.presets.imagenet import transform_eval
from gluoncv.model_zoo import get_model
from matplotlib import pyplot as plt

# 读取图像
src = image.imread("data/dog.png")

# 图像变换
img = transform_eval(src)

# 显示图像
plt.subplot(121), plt.imshow(src.asnumpy()), plt.axis("off"), plt.title(src.shape)
plt.subplot(122), plt.imshow(nd.transpose(img[0], (1,2,0)).asnumpy()), plt.axis("off"), plt.title(img.shape)
plt.show()

# 导入模型
net = get_model("ResNet50_v2", pretrained=True)

# 预测
pred = net(img); 
assert pred.shape == (1, 1000)

# 输出前5项预测结果
top_k = 5
print("The input picture is classified to be")
for i in range(len(img)):
    pred_ = pred[i]
    index = nd.topk(pred, k=top_k).asnumpy().astype("int").flatten()
    for j in range(top_k):
        class_ = net.classes[index[j]]
        prob = pred_[index[j]].asscalar()
        print(f"{class_:25} probability = {prob:.3f}")

在这里插入图片描述
可以看出, 预测的前五项都属于狗类: Welsh springer spaniel 威尔士史宾格犬; Brittany spaniel 布列塔尼西班牙猎狗; cocker spaniel 可卡犬; Blenheim spaniel 布伦海姆西班牙猎狗; clumber 矮脚西班牙猎犬

项目实践: 微调预训练模型进行猫咪分类

数据集

由于目前缺少算力支持, 不能实践大型数据集. GluonCV官网的示例程序用的是 MINC-2500, 但是也有2.6GB, 没有GPU只能放弃…找了好久, 看到 百度AI 练习项目: 猫12分类问题, 该项目已经完结, 但数据集可以下载, 这里我只下载了训练集, 因为测试集没有标签. 其中包含12种类的猫的图片, 每类猫咪180张图像, 合计184MB, 感觉挺适合CPU训练的. 按如下程序进行数据集分割, 一分为二进行迁移学习.

import os, shutil
import pandas as pd
import numpy as np

np.random.seed(42)

# 获取当前路径
root = os.path.abspath('.')
src_path = os.path.join(root, 'images')

# 新建目录
dir_names = ["train", "test"]
for dir_name in dir_names:
    path = os.path.join(root, dir_name)
    if not os.path.isdir(path):
        os.<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值