在广州开发一个营销网站多少钱,深圳都信建设监理有限公司网站,wordpress 手机写文,营销型网站建设策划书0.持续学习
持续学习相关文章汇总#xff0c;包含论文地址、代码地址、具体分析解读地址
1.LwF算法相关链接
论文地址代码地址
2.基本想法
针对问题#xff1a;在无法获得原始任务训练数据的情况下#xff0c;适合使视觉系统适应新任务#xff0c;并且保证其在旧任务上…0.持续学习
持续学习相关文章汇总包含论文地址、代码地址、具体分析解读地址
1.LwF算法相关链接
论文地址代码地址
2.基本想法
针对问题在无法获得原始任务训练数据的情况下适合使视觉系统适应新任务并且保证其在旧任务上的性能问题建模学习对新任务具有判别能力的参数同时保留训练数据上原始任务的输出将网络分为所有任务共享部分和特定任务独享部分网络架构如下 图片
3.损失函数
待学习参数有三种共享部分参数、旧任务们的独享参数、新任务独享参数由三部分组成旧任务损失、新任务损失、正则化项旧任务损失增长后的网络的输出与增长前的输出尽可能相同采用知识蒸馏损失类似交叉熵损失只不过加大了较小概率的惩罚权重其中关键参数T要大于1来加大小概率的权重文中通过网格搜索将其定位2新任务损失对于新任务的预测与真实值尽可能相同使用交叉熵损失或者NLL损失正则化项限制网络中所有参数权重0.0005新旧任务权衡在新任务损失前面有一个系数来表示对新旧任务性能的权衡文中取1参数越大在新任务上的性能越好在旧任务上的性能越差。通过改变该参数可以获得新旧任务性能曲线。
4.训练流程
热身阶段warm-up step冻结共享部分参数、旧任务们的独享参数单独训练新任务独享参数联合优化阶段joint-optimize step:优化所有参数
5.特点
与传统联合调优方法相比无需存储旧任务的数据新任务只需要通过一次共享层便可以用来进行旧任务和新任务的更新却具有了联合调优的优点。但因为不同任务的分布会不相同所以文中的方法效果会不如传统联合调优传统联合调优的效果可以视为本文方法的上限。效率分析 最慢共享参数的正反向传播最快特征提取层因为只需要训练新任务的参数与传统微调相比多了一步旧任务的独享参数更新效率稍微低一点与传统联合调优相比新旧任务共享的参数只需要进行一次前后向传播效率更高
6.具体细节
使用动量0.9的随机梯度下降在全连接层使用了dropout用旧任务的信息对新任务进行归一化数据增强 5X5的网格上对调整过大小的图像进行随机的固定尺寸裁剪随机镜像裁剪RGB值上添加方差 使用Xavier初始化新任务独享参数学习率是原网络学习率的0.1-0.02倍由于任务独享的特征提取部分参数量少所以使用5倍学习率对于学习速度相似的方法使用相同的训练epoch来进行公平比较有时为了防止过拟合、提升学习速度会接近平稳在的时候将学习率变为0.1倍为了公平比较将热身阶段后的共享网络作为联合训练和微调训练的起始点
7.实验
添加单个新任务添加多个新任务数据集大小的影响网络设计的影响不同损失扩展网络结构的效用小学习率微调来保证旧任务的影响改变任务专属部分的网络层数
8.结论
对于增长节点式的任务专属网络其性能与原本的LwF性能相近但是计算开销却大很多仅仅降低共享网络的学习率对保留旧任务性能的帮助并不大但却会很大程度影响新任务用网络输出的变化来现在旧任务的变化要优于用网络参数的变化来衡量因为网络参数一点小小的改变就可能引起输出巨大的改变知识蒸馏损失略优于L1、L2、交叉熵损失但优势很小训练速度优于联合优化对新任务的性能优于微调本文针对旧任务的损失对旧任务性能上的表现更可解释
9.未来工作
应用到图像分类、跟踪等更多领域分割、检测、视觉外的任务探索根据任务分布针对性地保留一些过去的任务数据和输出由于是面对重尾分布
10.代码解读
参考文章含有备注的model.py
import torch
torch.backends.cudnn.benchmarkTrue
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torch.autograd import Variable
import numpy as np
from PIL import Image
from tqdm import tqdm
import time
import copyimport torchvision.models as models
import torchvision.transforms as transformsdef MultiClassCrossEntropy(logits, labels, T):# Ld -1/N * sum(N) sum(C) softmax(label) * log(softmax(logit))labels Variable(labels.data, requires_gradFalse).cuda()outputs torch.log_softmax(logits/T, dim1) # compute the log of softmax valueslabels torch.softmax(labels/T, dim1)# print(outputs: , outputs)# print(labels: , labels.shape)outputs torch.sum(outputs * labels, dim1, keepdimFalse)outputs -torch.mean(outputs, dim0, keepdimFalse)# print(OUT: , outputs)return Variable(outputs.data, requires_gradTrue).cuda()def kaiming_normal_init(m):if isinstance(m, nn.Conv2d):#判断m是不是nn.Conv2d的类型或子类nn.init.kaiming_normal_(m.weight, nonlinearityrelu)#一种初始化方法要指明激活函数保证输出有一定方差https://zhuanlan.zhihu.com/p/536483424elif isinstance(m, nn.Linear):nn.init.kaiming_normal_(m.weight, nonlinearitysigmoid)class Model(nn.Module):分为超参数、网络架构、类增加三个部分前向传播里没有softmaxdef __init__(self, classes, classes_map, args):# Hyper Parametersself.init_lr args.init_lrself.num_epochs args.num_epochsself.batch_size args.batch_sizeself.lower_rate_epoch [int(0.7 * self.num_epochs), int(0.9 * self.num_epochs)] #hardcoded decay scheduleself.lr_dec_factor 10self.pretrained Falseself.momentum 0.9self.weight_decay 0.0001# Constant to provide numerical stability while normalizingself.epsilon 1e-16# Network architecturesuper(Model, self).__init__()self.model models.resnet34(pretrainedself.pretrained)self.model.apply(kaiming_normal_init)独享层:一层全连接层,与classes数量有关,且没有偏置num_features self.model.fc.in_featuresself.model.fc nn.Linear(num_features, classes, biasFalse)self.fc self.model.fc共享层:resnet34除去最后一层#nn.Sequential按序列构建模型https://blog.csdn.net/hxxjxw/article/details/106231242#.children()返回模型的最外层与.model()的区别类似于attend和extendself.feature_extractor nn.Sequential(*list(self.model.children())[:-1])#*用于迭代地取出list中的内容#用nn.DataParallel包装模型可以在多GPU上运行https://zhuanlan.zhihu.com/p/647169457self.feature_extractor nn.DataParallel(self.feature_extractor) # n_classes is incremented(递增) before processing new data in an iteration# n_known is set to n_classes after all data for an iteration has been processed数据处理完后n_known设为n_classesself.n_classes 0self.n_known 0self.classes_map classes_mapdef forward(self, x):x self.feature_extractor(x)x x.view(x.size(0), -1)x self.fc(x)return xdef increment_classes(self, new_classes):Add n classes in the final fc layern len(new_classes)print(new classes: , n)in_features self.fc.in_featuresout_features self.fc.out_featuresweight self.fc.weight.data#保存旧任务的网络权重if self.n_known 0:new_out_features nelse:new_out_features out_features nprint(new out features: , new_out_features)self.model.fc nn.Linear(in_features, new_out_features, biasFalse)self.fc self.model.fckaiming_normal_init(self.fc.weight)#所有任务网络统一初始化self.fc.weight.data[:out_features] weight#还原旧任务网络权重self.n_classes ndef classify(self, images):Classify images by softmaxArgs:x: input image batchReturns:preds: Tensor of size (batch_size,)_, preds torch.max(torch.softmax(self.forward(images), dim1), dim1, keepdimFalse)return predsdef update(self, dataset, class_map, args):self.compute_means True# Save a copy to compute distillation outputs保存旧网络来计算旧任务原始输出prev_model copy.deepcopy(self)prev_model.cuda()classes list(set(dataset.train_labels))#print(Classes: , classes)print(Known: , self.n_known)if self.n_classes 1 and self.n_known 0:#self.n_classes初始值是1不是0吗new_classes [classes[i] for i in range(1,len(classes))]else:new_classes [cl for cl in classes if class_map[cl] self.n_known]#有新任务就动态调整网络if len(new_classes) 0:self.increment_classes(new_classes)self.cuda()loader torch.utils.data.DataLoader(dataset, batch_sizeself.batch_size,shuffleTrue, num_workers12)print(Batch Size (for n_classes classes) : , len(dataset))optimizer optim.SGD(self.parameters(), lrself.init_lr, momentum self.momentum, weight_decayself.weight_decay)with tqdm(totalself.num_epochs) as pbar:for epoch in range(self.num_epochs):# Modify learning rate# if (epoch1) in lower_rate_epoch:# self.lr self.lr * 1.0/lr_dec_factor# for param_group in optimizer.param_groups:# param_group[lr] self.lrfor i, (indices, images, labels) in enumerate(loader):seen_labels []images Variable(torch.FloatTensor(images)).cuda()seen_labels torch.LongTensor([class_map[label] for label in labels.numpy()])labels Variable(seen_labels).cuda()# indices indices.cuda()optimizer.zero_grad()logits self.forward(images)cls_loss nn.CrossEntropyLoss()(logits, labels)if self.n_classes//len(new_classes) 1:dist_target prev_model.forward(images)logits_dist logits[:,:-(self.n_classes-self.n_known)]dist_loss MultiClassCrossEntropy(logits_dist, dist_target, 2)loss dist_losscls_losselse:loss cls_lossloss.backward()optimizer.step()if (i1) % 1 0:tqdm.write(Epoch [%d/%d], Iter [%d/%d] Loss: %.4f %(epoch1, self.num_epochs, i1, np.ceil(len(dataset)/self.batch_size), loss.data))pbar.update(1)