aiken's blog
  • home
  • archives
  • search
  • Aiken's Blog
  • home
  • posts
  • tags
  • categories
  • archives
  • about
  • search
  • linklog
Home » Tags

ML-Training

Fine Tuning

@Langs: python, torch @reference: d2l-pytorch,transfer_torch This Note focus on the code part. 模型微调和模型预训练,在Pytorch中的使用方式对比汇总。 How to Design the Fine Tune 这一部分主要集中于我们对于微调任务的拆解,有几种不同的预训练和微调的方式,在不同的情景下,对应的参数应该怎么设置和调整是问题的重点。 基于这种Transfer的策略,我们能够学习到一个更通用,泛化能力更强,有助于识别边缘,色彩,等等有助于下游任务的通用特征提取。 在Transfer任务中,有几种不同的调整方式: 固定Bakcbone,只训练Classifier 同步微调网络 区分学习率,微调Backbone,训练Classifirer 为了实现这几种不同的Transfer方式,需要用到以下的几种方式:梯度截断,lr区分设置等。 Code Part 不同lr设置 微调Backbone,训练Classifier作为最经典的Transfer设定,在Code上也较为复杂,所以我们首先举个这种例子。 相关的文档可以参考:torch.optim python # get dataset train_img = torchvision.datasets.ImageFolder(os.path.join(data_dir, 'train')) # get new model pretrained_new = model.expand_dim(dim=out_dim,re_init=True) # pre train it 定义一个用于微调的函数 # pytorch可以通过字典的形式来区分对设置lr def train_fine_tuning(net, learning_rate, batch_size=128, num_epoch=5, diff_lr=True): # set dataloader train_iter = torch.utils.Dataloader(train_img, batch_size=batch_size, shuffle=True) test_iter = ... # set loss loss = nn.CrossEntropyLoss(reduction='none') # set diff lr for diff part of it if diff_lr: params_1x = [param for name, param in net.name_parameters() if name not in ["fc.weight", "fc.bias"]] trainer = torch.optim.SGD([{'params': params_1x}, {'params': net.fc.parameters(), 'lr': learning_rate *10}], lr=learning_rate, weight_decay=0.001 ) else: trainer = torch.optim.SGD(net.parameters(), lr=learning_rate, weight_decay=0.001) 同时不用担心,scheduler可以将我们的两组lr同时进行更新,可以基于下面的代码进行测试 ...

February 8, 2022 · 2 min · 235 words · aikenhong ·  Fine-Tune ·  ML-Training
#Fine-Tune #ML-Training

Training Strategy

@Aiken 2020, 主要针对神经网络的训练过程中的一些基础策略的调整,比如当训练的曲线出现一定的问题的时候,我们应该怎么去调整我们训练过程中的策略。 参数调整过程中最重要的就是优化器(优化或者说是下降算法)和学习率(优化算法的核心参数),此外像是数据增强策略还是Normalization策略,都能极大的影响一个模型的好坏。 优化器 Some Material 实际上虽然有很多的优化算法,但是到最后最常用的还是 SGD+Mon 和 Adam两种: Adam主要的有事在于自适应学习率,他对我们设计的学习率实际上没有那么敏感,但是在具体实验中往往不会有调的好的SGD那么好,只是在SGD的参数调整中会比较费劲。 但是有了根据patient调整lr的scheduler后,我们基本上可以使用SGD做一个较为简单的调整,只要设计好初始的lr的实验以及用来调整学习率的参数值。 学习率 $\omega^{n} \leftarrow \omega^{n}-\eta \frac{\partial L}{\partial \omega^{n}}$ 其中的权重就是学习率lr, ==Basic== 学习率大 学习率小 学习速度 快 慢 使用情景 刚开始训练时 一定的次数过后 副作用 1. Loss爆炸 2.振荡 1.过拟合 2.收敛速度慢 学习率的基本设置 在训练过程中,一般根据训练轮数设置动态变化的学习率。 刚开始训练时:学习率以 0.01 ~ 0.001 为宜。 一定轮数过后:逐渐减缓。 接近训练结束:学习速率的衰减应该在100倍以上。 Note: 如果是 迁移学习 ,由于模型已在原始数据上收敛,此时应设置较小学习率 (≤10−4) 在新数据上进行 微调 。 学习率变化方法 ==warm up== warm up为什么有用 warm up衰减策略与上述的策略有些不同,它是先从一个极低的学习率开始增加,增加到某一个值后再逐渐减少, 这点上倒是和Cosine Anneal LR有一定的相似之处,将这两种结合起来是一种常见的训练策略: 这样训练模型更加稳定,因为在刚开始时模型的参数都是随机初始化的,此时如果学习率应该取小一点,这样就不会使模型一下子跑偏。 而这样的跑偏对于大模型而言,可能是导致很严重的影响,后面收敛了也可能不会达到最佳的效果,一开始的跑偏,可能会造成准确率在后面的严重结果。 ...

December 16, 2021 · 5 min · 922 words · aikenhong ·  ML-Training
#ML-Training

Hard Task Sampling

Trick:Hard Task 思路来源于Meta-Tranfer-Learning,基本思路是在Meta-Learning的每一次Meta-Test的时候,会从预训练错误率比较高的Task中再次采样,增加那些task的训练次数。也就是难题多做的策略。 基本思路 对比Adaboost 这样的思路其实和AdaBoost的想法是有一定的异曲同工之妙的,或者说其实就是AdaBoost的思路: Adaboost 参考笔记 ,从该笔记中我们可以看到,AdaBoost的基本思路如下: Boosting算法的工作机制是首先从训练集用初始权重训练出一个弱学习器1,根据弱学习的学习误差率表现来更新训练样本的权重,使得之前弱学习器1学习误差率高的训练样本点的权重变高,使得这些误差率高的点在后面的弱学习器2中得到更多的重视。然后基于调整权重后的训练集来训练弱学习器2.,如此重复进行,直到弱学习器数达到事先指定的数目T,最终将这T个弱学习器通过集合策略进行整合,得到最终的强学习器. 和Meta-Transfer-Learning对比一下,我们可以发现,这个方法实际上就是讲Transfer Learning的与训练网络当成弱学习器1,然后通过弱学习器1的训练样本权重,来增大Hard-Task的配比(也就是增加任务的权重)完全一致。 具体实现 实现上主要是,样本sample的过程,就是如何在进行参数选择后和原本的Dataloader,结合起来。在这里我们主要参考MTL中的方法,进行网络的构建处理。 第一部分:sampler构建,为了后续Dataloader中进行数据的采样,需要构建一个这样的sampler,关键在于index的对应关系,以及最后输出的是index的集合。 python import torch import numpy as np # 注意的点,我们需要确定我们batch数目,cls数目和每次每个cls选出多少个数据per # 紧接着定义一个sample,sample输出的是对应原dataset中的数据的index, class CatagoriesSampler(): def __init__(self, label, n_batch, n_cls, n_per): self.n_batch = n_batch self.n_cls = n_cls self.n_per = n_per label = np.array(label) # 根据不同的label输入情况,我们可可能需要找到每个label对应的样本的index,将其整合在一起。如下(option) self.m_idx = [] for i in range(max(label)+1): idx = np.argwhere(label==i).reshape(-1) idx = torch.from_numpy(idx) self.m_idx.append(idx) def __len__(self): # 要注意一下这里数据的长度是根据我们要输出的batch数目决定的 return self.n_batch def __iter__(self): # 直接定义每次采样的时候的batch输出 for i_batch in range(self.n_batch): batch = [] classes = torch.randperm(len(self.m_idx))[:self.n_cls] for c in classes: # 随机选择出的类标签 l = self.m_idx[c] # 随机选择样本 random_pos = torch.randperm(len(l))[:self.n_per] batch.append(l[random_pos]) # stack t and reshape的作用👇 # stack 变成n_cls * n_per , t转置,reshape(-1)变成行向量 batch = torch.stack(batch).t().reshape(-1) yield batch 第二部分:直接调用部分 ...

November 28, 2021 · 1 min · 139 words · aikenhong ·  ML-Training
#ML-Training

并行训练

How to Train Really Large Models on Many GPUs? (lilianweng.github.io) 对于浮点运算,模型参数的存储和中间计算输出(梯度和优化器状态)的存储的在 GPU 内存上的大量需求使得我们需要并行化,下面我们参考一些常用的并行化范式: 数据并行策略: 在Multi-GPUs上Duplicate模型,然后分别feed数据,进行运算,每个batch同步或者异步的进行多卡间的梯度传递和模型同步。 同步可能会导致每个batch需要停止训练,异步则是可能会使用陈旧的梯度进行一段时间的训练,增加了计算时间。 而在PT1.5以来,使用一种中间的方式:每隔x次迭代,进行多卡间的全局同步梯度一次,使用这种梯度积累的策略,根据计算图来进行计算和通信调度的优化,提高吞吐量。 模型并行范式: 是为了解决单模型过大无法存储在单一的Node上的问题,但是这样会有GPU间的顺序依赖,虽然减少了内存的占用和计算量,但是这种IO的需求导致计算资源的利用率严重不足。 在这种pipeline中,就存在利用率的bubble,也就是空白的部分 Pipeline并行策略: 混合模型和数据并行的策略,来减少低效时间的泡沫,也就是,将一个batch切分成多个小batch,然后分发到每个node上,减少相应的等待时间,只要我们对计算量和运行速度有合理的把握,就能极大的降低这个inefficient time bubbles. 多个mini-batch的梯度聚集起来最后同步更新. 最有情况下甚至可以忽略气泡的开销 $$ 1- \frac{2md}{(2m+2(d-1))d} = \frac{d-1}{m+d-1} $$ m个mini-batch和d个分布, bubble的比例将如上述所示 ...

November 28, 2021 · 1 min · 72 words · aikenhong ·  Parallel_Training ·  ML-Training
#Parallel_Training #ML-Training
© 2025 aiken's blog Licensed under CC BY-NC 4.0 · Powered by Hugo & PaperMod Visitors: Views: