首页 > 编程知识 正文

图像修复算法,神经网络量化方法

时间:2023-05-05 16:26:11 阅读:12571 作者:2116

因为MAML作者提供的源代码很混乱,是由tensorflow编写的。 所以我在Pytorch上写了一个再现MAML的博客。 与MAML模型无关的元学习代码已完全再现(Pytorch版)。 虽然该博客中的再现细节已经很详细,但在omniglot数据集上的精度只有0.92,考虑到omniglot是比较简单的数据集,0.92的精度太低。

因此,我后来调整了几种模型和数据读取方法。 最近的实验表明,在5路1短时任务中,我的再现精度已经达到0.972,与作者在论文中给出的精度区间基本一致。

本文总结了再现MAML时的经验和教训,以及对原始代码的更改。

1数据读取方式我以前的数据读取方式是一次读取omniglot的images_backgroud和images_evaluation这两个文件夹中的数据并分割数据集。

img _ list=NP.load (OS.path.join (root _ dir,' omniglot.npy ' ) ) (1623、20、1、28、28 ) x _ train=ion

img _ list _ train=NP.load (OS.path.join (root _ dir,' omniglot_train.npy ' ) ) 964、20、1、28、28

2模型结构元模型卷积层填充为2,stride也为2; 我把它们修改为1后,实验结果直接从0.92上升到了0.975。 由此可见,模型体系结构的细微调整也会严重影响模型的性能。 大家平时做实验的时候要小心。

原始模型体系结构如下:

# self.conv=nn.sequential (# nn.conv 2d (in _ channels=1,out_channels=64,Kernel_size=) 3,Padnel ) # nn.ReLU (、# nn.MaxPool2d(2)、#nn.conv2d ) in_channels=64,out_channels=64,Kernel_size=) 3,# out_channels=64,Kernel_size=) 3,# nn.ReLU (、# nn.MaxPool2d(2)、#nn.conv2d ) in _ channels=65292; # nn.ReLU (、# nn.MaxPool2d(2)、# FlattenLayer )、#nn.linear )和5 ) )修改后的模型体系结构如下:

# self.conv=nn.sequential (# nn.conv 2d (in _ channels=1,out_channels=64,Kernel_size=) 3,Padnel ) # nn.ReLU (、# nn.MaxPool2d(2)、#nn.conv2d ) in_channels=64,out_channels=64,kernel_size=(3) 3

3), padding = 1, stride = 1),# nn.BatchNorm2d(64),# nn.ReLU(),# nn.MaxPool2d(2), # nn.Conv2d(in_channels = 64, out_channels = 64, kernel_size = (3,3), padding = 1, stride = 1),# nn.BatchNorm2d(64),# nn.ReLU(),# nn.MaxPool2d(2), # nn.Conv2d(in_channels = 64, out_channels = 64, kernel_size = (3,3), padding = 1, stride = 1),# nn.BatchNorm2d(64),# nn.ReLU(),# nn.MaxPool2d(2), # FlattenLayer(),# nn.Linear(64,5)# ) 3 降低对计算资源的要求

在进行20-way-1-shot的实验时,发现用原来的代码将会消耗大量的资源。我修改了一下原来的代码,在不需要记录梯度的位置加上"with torch.no_grad()",从而将计算资源的需求降到了原来的1/5.

原来的代码为:

for k in range(1, self.update_step): y_hat = self.net(x_spt[i], params = fast_weights, bn_training=True) loss = F.cross_entropy(y_hat, y_spt[i]) grad = torch.autograd.grad(loss, fast_weights) tuples = zip(grad, fast_weights) fast_weights = list(map(lambda p: p[1] - self.base_lr * p[0], tuples)) y_hat = self.net(x_qry[i], params = fast_weights, bn_training = True) loss_qry = F.cross_entropy(y_hat, y_qry[i]) loss_list_qry[k+1] += loss_qry with torch.no_grad(): pred_qry = F.softmax(y_hat,dim=1).argmax(dim=1) correct = torch.eq(pred_qry, y_qry[i]).sum().item() correct_list[k+1] += correct

修改后的代码为:

for k in range(1, self.update_step): y_hat = self.net(x_spt[i], params = fast_weights, bn_training=True) loss = F.cross_entropy(y_hat, y_spt[i]) grad = torch.autograd.grad(loss, fast_weights) tuples = zip(grad, fast_weights) fast_weights = list(map(lambda p: p[1] - self.base_lr * p[0], tuples)) if k < self.update_step - 1: with torch.no_grad(): y_hat = self.net(x_qry[i], params = fast_weights, bn_training = True) loss_qry = F.cross_entropy(y_hat, y_qry[i]) loss_list_qry[k+1] += loss_qry else: y_hat = self.net(x_qry[i], params = fast_weights, bn_training = True) loss_qry = F.cross_entropy(y_hat, y_qry[i]) loss_list_qry[k+1] += loss_qry with torch.no_grad(): pred_qry = F.softmax(y_hat,dim=1).argmax(dim=1) correct = torch.eq(pred_qry, y_qry[i]).sum().item() correct_list[k+1] += correct 4 关于20-way-1-shot实验

2020/5/10更新:

Reptile这篇论文中说,MAML的实验使用到了transductive Learning的实验设定。关于transductive Learning你可以理解成MAML作者汇报的是训练中query集的结果,而不是我们通常意义的测试集中query集的结果。
这个图表来自Reptile的那篇论文。

以下是原文:

我在复现这个实验的过程中,在测试集的query集中的最好结果也只有0.843。但是作者宣称她取得了0.95的实验结果,但是作者的源码中并没有给出20-way-1-shot的实验结果或者logs。

我找到了另一个网友(github账号名:katerkelly)的复现代码,这个人宣称他复现出来的结果是0.92。

20-way 1-shot training, best performance 92%

但是我实际运行以及查看了他的代码后发现,他报告的其实是训练集中query集的结果,而不是测试集中query集的结果。我们都知道在元学习中有support集和query集两者集合,其中:

训练集:分为support集和query集,其中support集用于训练,query集用于更新参数。测试集:分为support集和query集,其中support集用于fine-tune,query集用于评估元学习模型的效果。

而那位网友报告的是训练集中support集的结果,真正的实验结果应该是测试集中support集的实验结果,也就是0.83。

你可以查看那位网友给出的实验结果展示图(下图)。中间那条橙黄色的线是0.92左右,那位网友报告的也是橙黄色这条线的结果,但是实际的实验结果应该是下面这条红色的线。也就是0.83左右,跟我得出的实验结果比较吻合。

有意思的是,MAML作者声称她的实验结果实0.95,而我自己复现的结果中,在测试集的support集上的结果也是0.95-0.96。为了跑出0.9以上的实验结果,我已经做了好几天的实验了,模型架构和超参数改动了几十次,最好的结果还是只有0.843。如果哪位网友能够复现出0.9以上的实验结果,麻烦告诉我一下。

5 实验数据

以下展示在60000轮epoch中,query集的测试集中出现的最好结果:

20 way 1 shot 4 batch meta_lr = 0.0002, base_lr = 0.1 : acc: 0.84

20 way 1 shot 8 batch meta_lr = 0.0001, base_lr = 0.1 : acc: 0.835

20 way 1 shot 8 batch meta_lr = 0.0001, base_lr = 0.1 : acc: 0.843

20 way 1 shot 8 batch meta_lr = 0.0005, base_lr = 0.3 : acc: 0.79

20 way 1 shot 8 batch meta_lr = 0.001, base_lr = 0.1 : acc: 0.82

20 way 1 shot 8 batch meta_lr = 0.001, base_lr = 0.2 : acc: 0.785

5 way 1 shot 4 batch 10 range meta_lr = 0.001, base_lr = 0.1 : acc: 0.96

5 way 1 shot 8 batch 10 range meta_lr = 0.001, base_lr = 0.1 : acc: 0.972

5 way 1 shot 16 batch 10 range meta_lr = 0.001, base_lr = 0.1 : acc: 0.969

5 way 1 shot 32 batch 10 range meta_lr = 0.001, base_lr = 0.1 : acc: 0.975

自己想要复现的朋友,可以参考一下我的实验结果,免得继续做无用功。

6 关于我自己的源码

你可以在我的github上找到我的全部代码(miguealanmath)。喜欢的朋友可以点下小星星。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。