4000-520-616
欢迎来到免疫在线!(蚂蚁淘生物旗下平台)  请登录 |  免费注册 |  询价篮
主营:原厂直采,平行进口,授权代理(蚂蚁淘为您服务)
咨询热线电话
4000-520-616
当前位置: 首页 > 新闻动态 >
新闻详情
Mxnet (32): 迁移学习(Fine-Tuning)进行热狗识别_泛泛之素-CSDN博客
来自 : fanfanzhisu.blog.csdn.net/arti 发布时间:2021-03-25
224∗224像素的输入。测试过程中 将图片缩放为宽高为256像素 然后在图片的中心区域截取宽高224的区域作为输入。此外将RGB三个通道归一化。

# 归一化normalize gluon.data.vision.transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])train_augs gluon.data.vision.transforms.Compose([ gluon.data.vision.transforms.RandomResizedCrop(224), # 随机裁剪并resize gluon.data.vision.transforms.RandomFlipLeftRight(), # 左右翻转 gluon.data.vision.transforms.ToTensor(), normalize])test_augs gluon.data.vision.transforms.Compose([ gluon.data.vision.transforms.Resize(256), # resize gluon.data.vision.transforms.CenterCrop(224), # 中间裁剪 gluon.data.vision.transforms.ToTensor(), normalize])
2. 初始化模型

使用在ImageNet数据集上经过预训练的ResNet-18作为源模型。通过gluon.model_zoo模块获取模型 pretrained True自动下载并加载预训练的模型参数。首次使用的话需要在网上下载模型和参数。

pretrained_net gluon.model_zoo.vision.resnet18_v2(pretrained True)

预训练的源模型有两个成员变量 features和output。前者为除去输出层的所有层 后者为输出层。这样划分主要是方便衔接自己模型的输出层 而对其他层进行微调。

这是创建目标模型 同样使用model_zoo获取模型 通过classes指定分类的类型 即输出数量。

finetune_net gluon.model_zoo.vision.resnet18_v2(classes 2)

将预训练模型的features复制给目标模型 并初始化目标模型的输出层。成员变量output中的模型参数是随机初始化的 通常需要更高的学习率才能从头开始学习 需要调高学习率。这里设置输出层的lr_mult为10 意味着输出层的学习率为其他层的10倍。

finetune_net.features pretrained_net.featuresfinetune_net.output.initialize(init.Xavier())# 设置输出层学习率为10倍finetune_net.output.collect_params().setattr( lr_mult , 10)
3. 微调模型

定义train_fine_tuning函数用于训练模型

def accuracy(y_hat, y):  if len(y_hat.shape) 1 and y_hat.shape[1] 1: y_hat y_hat.argmax(axis 1) cmp y_hat.astype(y.dtype) y return float(cmp.sum())def train_batch(net, features, labels, loss, trainer, devices, split_f d2l.split_batch): X_shards, y_shards split_f(features, labels, devices) with autograd.record(): pred_shards [net(X_shard) for X_shard in X_shards] ls [loss(pred_shard, y_shard) for pred_shard, y_shard in zip(pred_shards, y_shards)] for l in ls: l.backward() # ignore_stale_grad代表可以使用就得梯度参数 trainer.step(labels.shape[0], ignore_stale_grad True) train_loss_sum sum([float(l.sum()) for l in ls]) train_acc_sum sum(accuracy(pred_shard, y_shard) for pred_shard, y_shard in zip(pred_shards, y_shards)) return train_loss_sum, train_acc_sumdef train(net, train_iter, test_iter, loss, trainer, num_epochs, devices d2l.try_all_gpus(), split_f d2l.split_batch): num_batches, timer len(train_iter), d2l.Timer() epochs_lst, loss_lst, train_acc_lst, test_acc_lst [],[],[],[] for epoch in range(num_epochs): metric d2l.Accumulator(4) for i, (features, labels) in enumerate(train_iter): timer.start() l, acc train_batch( net, features, labels, loss, trainer, devices, split_f) metric.add(l, acc, labels.shape[0], labels.size) timer.stop() if (i 1) % (num_batches // 5) 0: epochs_lst.append(epoch i / num_batches) loss_lst.append(metric[0] / metric[2]) train_acc_lst.append(metric[1] / metric[3]) test_acc_lst.append(d2l.evaluate_accuracy_gpus(net, test_iter, split_f)) print(f [epock {epoch 1}] train loss: {metric[0] / metric[2]:.3f} train acc: {metric[1] / metric[3]:.3f} ,  f test_loss: {test_acc_lst[-1]:.3f} ) print(f loss {metric[0] / metric[2]:.3f}, train acc  f {metric[1] / metric[3]:.3f}, test acc {test_acc_lst[-1]:.3f} ) print(f {metric[2] * num_epochs / timer.sum():.1f} examples/sec on  f {str(devices)} ) fig go.Figure() fig.add_trace(go.Scatter(x epochs_lst, y loss_lst, name train loss )) fig.add_trace(go.Scatter(x epochs_lst, y train_acc_lst, name train acc )) fig.add_trace(go.Scatter(x list(range(1,len(test_acc_lst) 1)), y test_acc_lst, name test acc )) fig.update_layout(width 800, height 480, xaxis_title epoch , yaxis_range [0, 1]) fig.show()def train_fine_tuning(net, learning_rate, batch_size 64, num_epochs 5): train_iter gluon.data.DataLoader(train_imgs.transform_first(train_augs), batch_size, shuffle True) test_iter gluon.data.DataLoader(test_imgs.transform_first(test_augs), batch_size) net.collect_params().reset_ctx(npx.gpu()) net.hybridize() loss gluon.loss.SoftmaxCrossEntropyLoss() trainer gluon.Trainer(net.collect_params(), sgd , { learning_rate : learning_rate, wd : 0.001}) train(net, train_iter, test_iter, loss, trainer, num_epochs, [npx.gpu()])

进行训练, 由于预训练模型已经训练过因此学习率给的比较低:0.01

train_fine_tuning(finetune_net, 0.01)

\"在这里插入图片描述\"

可以看到仅仅5个epoch就有0.94的准度 确实很快

\"在这里插入图片描述\"

为了比较迁移学习的效果 这里创建一个同样的模型 但是不复制预训练模型的参数 而是全部初始化 对比一些训练效果。由于是重新开始训练 因此提高了学习率 0.1

scratch_net gluon.model_zoo.vision.resnet18_v2(classes 2)scratch_net.initialize(init init.Xavier())train_fine_tuning(scratch_net, 0.1)

\"在这里插入图片描述\"

\"在这里插入图片描述\"

很明显由于参数的初始值更好 因此经过微调的模型倾向于在同一时期获得更高的精度。

4.参考

https://d2l.ai/chapter_computer-vision/fine-tuning.html

5.代码

github

本文链接: http://npfine.immuno-online.com/view-728494.html

发布于 : 2021-03-25 阅读(0)