校园网站做等级保护,wordpress小机巧,32套网站后台管理系统模板,我的个人博客网站基本介绍 今天的应用实践的领域是计算机视觉领域#xff0c;更确切的说是图像分类任务#xff0c;不过#xff0c;与昨日不同的是#xff0c;今天所使用的模型是ShuffleNet模型。ShuffleNetV1是旷视科技提出的一种计算高效的CNN模型#xff0c;和MobileNet, SqueezeNet等一…基本介绍 今天的应用实践的领域是计算机视觉领域更确切的说是图像分类任务不过与昨日不同的是今天所使用的模型是ShuffleNet模型。ShuffleNetV1是旷视科技提出的一种计算高效的CNN模型和MobileNet, SqueezeNet等一样主要应用在移动端所以模型的设计目标就是利用有限的计算资源来达到最好的模型精度。今天会简单介绍一些ShuffleNet模型并使用CIFAR-10数据集进行训练与评估最后进行模型预测
ShuffleNet模型简介 ShuffleNetV1的设计核心是引入了两种操作Pointwise Group Convolution和Channel Shuffle这在保持精度的同时大大降低了模型的计算量。因此ShuffleNetV1和MobileNet类似都是通过设计更高效的网络结构来实现模型的压缩和加速 Pointwise Group Convolution
Group Convolution分组卷积原理如下图所示相比于普通的卷积操作分组卷积的情况下每一组的卷积核大小为in_channels/g*k*k一共有g组所有组共有(in_channels/g*k*k)*out_channels个参数是正常卷积参数的1/g。分组卷积中每个卷积核只处理输入特征图的一部分通道其优点在于参数量会有所降低但输出通道数仍等于卷积核的数量 Channel Shuffle Group Convolution的弊端在于不同组别的通道无法进行信息交流堆积GConv层后一个问题是不同组之间的特征图是不通信的这就好像分成了g个互不相干的道路每一个人各走各的这可能会降低网络的特征提取能力。这也是XceptionMobileNet等网络采用密集的1x1卷积Dense Pointwise Convolution的原因。为了解决不同组别通道“近亲繁殖”的问题ShuffleNet优化了大量密集的1x1卷积在使用的情况下计算量占用率达到了惊人的93.4%引入Channel Shuffle机制通道重排。这项操作直观上表现为将不同分组通道均匀分散重组使网络在下一层能处理不同组别通道的信息。 以上两个结构就是ShuffleNet的主要结构ShuffleNet的模型代码MindSpore版如下
class ShuffleNetV1(nn.Cell):def __init__(self, n_class1000, model_size2.0x, group3):super(ShuffleNetV1, self).__init__()print(model size is , model_size)self.stage_repeats [4, 8, 4]self.model_size model_sizeif group 3:if model_size 0.5x:self.stage_out_channels [-1, 12, 120, 240, 480]elif model_size 1.0x:self.stage_out_channels [-1, 24, 240, 480, 960]elif model_size 1.5x:self.stage_out_channels [-1, 24, 360, 720, 1440]elif model_size 2.0x:self.stage_out_channels [-1, 48, 480, 960, 1920]else:raise NotImplementedErrorelif group 8:if model_size 0.5x:self.stage_out_channels [-1, 16, 192, 384, 768]elif model_size 1.0x:self.stage_out_channels [-1, 24, 384, 768, 1536]elif model_size 1.5x:self.stage_out_channels [-1, 24, 576, 1152, 2304]elif model_size 2.0x:self.stage_out_channels [-1, 48, 768, 1536, 3072]else:raise NotImplementedErrorinput_channel self.stage_out_channels[1]self.first_conv nn.SequentialCell(nn.Conv2d(3, input_channel, 3, 2, pad, 1, weight_initxavier_uniform, has_biasFalse),nn.BatchNorm2d(input_channel),nn.ReLU(),)self.maxpool nn.MaxPool2d(kernel_size3, stride2, pad_modesame)features []for idxstage in range(len(self.stage_repeats)):numrepeat self.stage_repeats[idxstage]output_channel self.stage_out_channels[idxstage 2]for i in range(numrepeat):stride 2 if i 0 else 1first_group idxstage 0 and i 0features.append(ShuffleV1Block(input_channel, output_channel,groupgroup, first_groupfirst_group,mid_channelsoutput_channel // 4, ksize3, stridestride))input_channel output_channelself.features nn.SequentialCell(features)self.globalpool nn.AvgPool2d(7)self.classifier nn.Dense(self.stage_out_channels[-1], n_class)def construct(self, x):x self.first_conv(x)x self.maxpool(x)x self.features(x)x self.globalpool(x)x ops.reshape(x, (-1, self.stage_out_channels[-1]))x self.classifier(x)return x
数据集准备 采用CIFAR-10数据集对ShuffleNet进行预训练。CIFAR-10共有60000张32*32的彩色图像均匀地分为10个类别其中50000张图片作为训练集10000图片作为测试集。可直接使用mindspore.dataset.Cifar10Dataset接口下载并加载CIFAR-10的训练集。这部分的操作和昨天几乎一样就不进行展示
模型训练与评估 采用随机初始化的参数做预训练。首先调用ShuffleNetV1定义网络参数量选择2.0x并定义损失函数为交叉熵损失学习率经过4轮的warmup后采用余弦退火优化器采用Momentum总共训练5轮。最后用train.model中的Model接口将模型、损失函数、优化器封装在model中并用model.train()对网络进行训练。将ModelCheckpoint、CheckpointConfig、TimeMonitor和LossMonitor传入回调函数中将会打印训练的轮数、损失和时间并将ckpt文件保存在当前目录下。具体训练代码如下
def train():mindspore.set_context(modemindspore.PYNATIVE_MODE, device_targetAscend)net ShuffleNetV1(model_size2.0x, n_class10)loss nn.CrossEntropyLoss(weightNone, reductionmean, label_smoothing0.1)min_lr 0.0005base_lr 0.05lr_scheduler mindspore.nn.cosine_decay_lr(min_lr,base_lr,batches_per_epoch*250,batches_per_epoch,decay_epoch250)lr Tensor(lr_scheduler[-1])optimizer nn.Momentum(paramsnet.trainable_params(), learning_ratelr, momentum0.9, weight_decay0.00004, loss_scale1024)loss_scale_manager ms.amp.FixedLossScaleManager(1024, drop_overflow_updateFalse)model Model(net, loss_fnloss, optimizeroptimizer, amp_levelO3, loss_scale_managerloss_scale_manager)callback [TimeMonitor(), LossMonitor()]save_ckpt_path ./config_ckpt CheckpointConfig(save_checkpoint_stepsbatches_per_epoch, keep_checkpoint_max5)ckpt_callback ModelCheckpoint(shufflenetv1, directorysave_ckpt_path, configconfig_ckpt)callback [ckpt_callback]print( Starting Training )start_time time.time()# 由于时间原因epoch 5可根据需求进行调整model.train(5, dataset, callbackscallback)use_time time.time() - start_timehour str(int(use_time // 60 // 60))minute str(int(use_time // 60 % 60))second str(int(use_time % 60))print(total time: hour h minute m second s)print( Train Success )
评估的时候直接使用model.eval()进行评估具体代码如下
def test():mindspore.set_context(modemindspore.GRAPH_MODE, device_targetAscend)dataset get_dataset(./dataset/cifar-10-batches-bin, 128, test)net ShuffleNetV1(model_size2.0x, n_class10)param_dict load_checkpoint(shufflenetv1-5_390.ckpt)load_param_into_net(net, param_dict)net.set_train(False)loss nn.CrossEntropyLoss(weightNone, reductionmean, label_smoothing0.1)eval_metrics {Loss: nn.Loss(), Top_1_Acc: Top1CategoricalAccuracy(),Top_5_Acc: Top5CategoricalAccuracy()}model Model(net, loss_fnloss, metricseval_metrics)start_time time.time()res model.eval(dataset, dataset_sink_modeFalse)use_time time.time() - start_timehour str(int(use_time // 60 // 60))minute str(int(use_time // 60 % 60))second str(int(use_time % 60))log result: str(res) , ckpt: ./shufflenetv1-5_390.ckpt \ , time: hour h minute m second sprint(log)filename ./eval_log.txtwith open(filename, a) as file_object:file_object.write(log \n)
模型预测 训练完毕则可进行模型预测并将预测结果可视化结果如下 可以看出shuffleNet效果还是不错的在轻量化的前提下也保证了一定的精度。
Jupyter运行情况