李宏毅机器学习课程——Lifelonglearning学习笔记
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
李宏毅机器学习课程——Lifelonglearning学习笔记概述
lifelong learning⾮常直观,意思是机器不能前边学后边忘。
常见的⽅法是对前边的task中学习出来的参数加⼀个保护系数,在后⾯的任务中,训练参数时,对保护系数⼤的参数很难训练,⽽保护系数⼩的参数则容易⼀些。
下⾯的图⾮常直观,颜⾊的深浅代表loss的⼤⼩,颜⾊越深loss越⼩。
在task1中θ2的变化对loss的变化⾮常敏感,⽽θ1则不敏感,所以在task2中尽量只通过改变θ1来减⼩loss,⽽不要改变θ2。
在lifelong learning中,loss的计算公式如下:
L′(θ)=L(θ)+λΣi b i(θi−θb i)2
其中b i就是对θ的保护系数,θi表⽰本次task中需要学习的参数,θb i是从之前的task中学习到的参数。
不同的⽅法差异就在于b i的计算。
这⾥将会结合Coding整理⼀下遇到的三个⽅法。
Coding
这部分针对HW14,介绍了EWC,MAS,SCP三种⽅法,这⾥讲解⼀下具体的代码实现,并定性地分析⼀下这些⽅法是如何把哪些重要的参数保护起来。
EWC
EWC中不同的保护系数f i使⽤如下的⽅法计算得到:
F=[∇log(p(y n|x n,θ∗A))∇log(p(y n|x n,θ∗A))T]
F的对⾓线的各个数就是各个θ的保护系数。
p(y n|x n,θ∗A)指的就是模型在给点之前 task 的 data x n以及给定训练完 task A (原来)存下来的模型参数θ∗A得到y n(x n对应的 label ) 的后验概率。
其实对参数θi,它的保护系数就是向量log(p(y n|x n,θ∗A))对θ1的偏导数∂log(p(y n|x n,θ∗A))
∂θ1与⾃⾝的内积。
当对这个参数敏感时,这个偏导数会
变⼤,当预测结果正确率⾼时,p(y n|x n)也会⾼,最终都会使的保护系数变⼤。
某⼀个参数⽐较敏感,这个参数下正确率⾼时,这个参数就会被很好地保护起来。
for dataloader in self.dataloaders:
for data in dataloader:
self.model.zero_grad()
input = data[0].to(self.device)
output = self.model(input).view(1,-1)
label = output.max(1)[1].view(-1)
loss = F.nll_loss(F.log_softmax(output,dim),label)
loss.backward()
for n,p in d_parameters():
precision_matrices[n].data += p.grad.data ** 2 / number_data
precision_matrices = {n: p for n, p in precision_matrices.items()}
MAS
MAS中保护系数的计算⽅法如下所⽰:
Ωi=||∂ℓ22(M(x k;θ))
∂θi||
x k是来⾃于前⾯ task 的 sample data。
式⼦上的作法就是对最后模型的 output vector (最后⼀层)做2范数后取平⽅,再对各⾃的weight微分(取gradient) 并且取该 gradient 的绝对值。
for dataloader in self.dataloaders:
for data in dataloader:
self.model.zero_grad()
output = self.model(data[0].to(self.device))
output.pow_(2)
loss = torch.sum(output,dim=1) # 2范数的平⽅即元素的平⽅和
loss = loss.mean()
loss.backward()
for n, p in d_parameters():
precision_matrices[n].data += p.grad.abs() / num_data ## difference with EWC precision_matrices = {n: p for n, p in precision_matrices.items()}
SCP
SCP⽅法保护系数的计算⽅法(Γ矩阵)如下:
初始化矩阵为0矩阵。
模型的output对所有的task A的输⼊x A取平均值:
¯ϕ∗A =
1
NΣN
n=1ϕ(x
A
n
;θ∗A)
从k维球⾯依次随机取L个单位向量,注意要与¯ϕ∗
A的维度要⼀致,每次取得的ξl,依次执⾏如下操作:
计算内积ρ=ξl∗¯ϕ∗A
取梯度∇θρ
Γ+=1
L(∇
θ
ρ)(∇θρ)T
def sample_spherical(npoints, ndim=3):
vec = np.random.randn(npoints, ndim)
vec = (vec.T / np.linalg.norm(vec, axis=1)).T
return vec
## main
for dataloader in self.dataloaders:
for data in dataloader:
self.model.zero_grad()
output = self.model(data[0].to(self.device))
vec_mean = output.mean(dim=0)
L_vecs = sample_spherical(self.L,vec_mean.size()[0])
for vec in L_vecs:
rou = torch.dot(torch.from_numpy(vec).to(self.device),vec_mean.double()) rou.backward(retain_graph=True)
for n, p in d_parameters():
precision_matrices[n].data += p.grad.data ** 2 / self.L
self.model.zero_grad()
precision_matrices = {n: p for n, p in precision_matrices.items()}
Processing math: 100%。