[代码阅读笔记01] MLNT

 class_loss.backward(retain_graph=True) 

这行代码使用 backward() 函数对分类损失进行反向传播,计算梯度,并将梯度传播到模型的参数中。参数 retain_graph=True 表示在计算梯度时保留计算图,这样可以在后续的计算中重复使用计算图,而不需要重新计算。

通常情况下,在调用一次 backward() 后,计算图会被释放,如果需要再次使用相同的计算图进行额外的计算或梯度更新,就需要将 retain_graph 设置为 True

# args.start_iter=500, args.mid_iter=2000, args.alpha=1
if batch_idx>args.start_iter or epoch>1:
    if batch_idx>args.mid_iter or epoch>1:
         args.eps=0.999
         alpha = args.alpha
    else:
         u = (batch_idx-args.start_iter)/(args.mid_iter-args.start_iter)
         alpha = args.alpha*math.exp(-5*(1-u)**2) 

如果batch_idx在500到2000之间: 

u=\frac{batchidx-500}{2000-500}

\alpha =e^{-5(1-u)^2}

人造噪声标签

# batch_size=32, args.perturb_ratio=0.5
for i in range(args.num_fast):
    targets_fast = targets.clone()
    randidx = torch.randperm(targets.size(0))
    for n in range(int(targets.size(0)*args.perturb_ratio)):
        num_neighbor = 10
        idx = randidx[n]
        feat = feats[idx]
        feat.view(1,feat.size(0))
        feat.data = feat.data.expand(targets.size(0),feat.size(0))
        dist = torch.sum((feat-feats)**2,dim=1)
        _, neighbor = torch.topk(dist.data,num_neighbor+1,largest=False)
        targets_fast[idx] = targets[neighbor[random.randint(1,num_neighbor)]]
  • targets.size(0)=32
  • randidx是包含了 0 到 31 的整数的随机排列
  • for n in range(16):替换掉原始标签的一半,使噪声概率为0.5
  • _, neighbor = torch.topk(dist.data,num_neighbor+1,largest=Falsedist.data是一个包含了每个样本与其他样本的距离的张量。
    num_neighbor + 1表示要找到距离最近的前 num_neighbor + 1个样本(因为最近的样本是其自身,所以需要额外加 1)。
    参数 largest=False表示找到最小的元素。
    返回的 neighbor张量包含了最近的 num_neighbor + 1 个样本的索引。

  • random.randint(1, num_neighbor) 返回一个介于 1 和 num_neighbor 之间(包括 1 和 num_neighbor的随机整数。 

Meta-train 

\theta _m^{'}=\theta -\alpha \bigtriangledown _\theta L_c(X,\widehat{Y}_m,\theta )

fast_loss = criterion(outputs,targets_fast)
grads = torch.autograd.grad(fast_loss, net.parameters(), create_graph=True, retain_graph=True, only_inputs=True)
for grad in grads:
    grad = grad.detach()
    grad.requires_grad = False  
fast_weights = OrderedDict((name, param - args.meta_lr*grad) for ((name, param), grad) in zip(net.named_parameters(), grads))                

为什么不用backward(),因为这一步不是为了更新整个模型的参数,反而需要保留\theta

fast_weights为有序字典

留下一个疑问:grad的各种用法

sys.stdout.write('\r')
sys.stdout.write('| Epoch [%3d/%3d] Iter[%3d/%3d]\t\tLoss: %.4f Acc@1: %.3f%%'
                %(epoch, args.num_epochs, batch_idx+1, (len(train_loader.dataset)//args.batch_size)+1, class_loss.data[0], 100.*correct/total))
sys.stdout.flush()

 

if acc > best:
    best = acc
    print('| Saving Best Model (net)...')
    save_point = './checkpoint/%s.pth.tar'%(args.id)
    save_checkpoint({
            'state_dict': net.state_dict(),
            'best_acc': best,
    }, save_point)       

save_checkpoint({...}, save_point):这行代码调用了一个函数 save_checkpoint(),并传入了两个参数:一个字典和保存模型参数的文件路径。这个函数的作用是将模型的状态字典和其他相关信息保存到指定的文件中。

record=open('./checkpoint/'+args.id+'.txt','w')
record.write('learning rate: %f\n'%args.lr)
record.write('batch size: %f\n'%args.batch_size)
record.write('start iter: %d\n'%args.start_iter)  
record.write('mid iter: %d\n'%args.mid_iter)  
record.flush()
  • record = open('./checkpoint/' + args.id + '.txt', 'w'):这行代码打开一个文本文件,文件名根据参数 args.id 动态生成,并将文件对象赋值给变量 record。参数 'w' 表示以写入模式打开文件,如果文件不存在则创建文件,如果文件已存在则清空文件内容。
  • record.flush():这行代码用于强制将缓冲区中的数据写入到文件中,确保数据被及时地写入到文件中。
net = models.resnet50(pretrained=True)
net.fc = nn.Linear(2048,14)

 net.fc = nn.Linear(2048, 14) 将最后一层全连接层(fc)替换为一个新的线性层。原始的 ResNet-50 模型中,最后一层全连接层的输入特征数量为 2048(即 ResNet-50 最后一个池化层输出的特征图大小为 2048x1x1),输出特征数量为 1000(对应 ImageNet 数据集的类别数量)。这里将输出特征数量修改为 14,以适应你的特定任务,其中 14 是你的任务中的类别数量。

best_model = torch.load('./checkpoint/%s.pth.tar'%args.id)
test_net.load_state_dict(best_model['state_dict'])

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值