扩散模型代码使用

一 Parser用法

1使用方法

实例化创建一个ArgumentParser对象

import argparse 
parser = argparse.ArgumentParser(description='parser example')

使用add_argument()函数增加参数并设置值

ArgumentParser.add_argument(name or flags...[, action][, nargs]
[, const][, default][, type][, choices][, required][, help][, metavar][, dest])

参数解释:
name or flags - 选项字符串的名字或者列表,例如 foo 或者 -f, --foo。
action - 命令行遇到参数时的动作,默认值是 store
nargs - 应该读取的命令行参数个数,可以是具体的数字,或者是?号,当不指定值时对于 Positional argument 使用 default,对于 Optional argument 使用 const;或者是 * 号,表示 0 或多个参数;或者是 + 号表示 1 或多个参数
const - action 和 nargs 所需要的常量值
default - 不指定参数时的默认值
type - 命令行参数应该被转换成的类型
required - 可选参数是否可以省略 (仅针对可选参数)
help - 参数的帮助信息,当指定为 argparse.SUPPRESS 时表示不显示该参数的帮助信息
metavar - 在 usage 说明中的参数名称,对于必选参数默认就是参数名称,对于可选参数默认是全大写的参数名称

以下是简单的例子:

import argparse

parser = argparse.ArgumentParser(description='test')

parser.add_argument('--sparse', action='store_true', default=False, help='GAT with sparse version or not.')
parser.add_argument('--seed', type=int, default=72, help='Random seed.')
parser.add_argument('--epochs', type=int, default=10000, help='Number of epochs to train.')

args = parser.parse_args()

以下是sdm中的例子:

	#预训练模型
    parser.add_argument(
        "-r",
        "--resume",
        type=str,
        const=True,
        default="",
        nargs="?",
        help="resume from logdir or checkpoint in logdir",
    )
    #基础设置yaml文件
    parser.add_argument(
        "-b",
        "--base",
        nargs="*",
        metavar="base_config.yaml",
        help="paths to base configs. Loaded from left-to-right. "
             "Parameters can be overwritten or added with command-line options of the form `--key value`.",
        default=list(),
    )

二 pytorch_lightning

1 构建模型

pytorch_lightning其实是对pytorch的包装,基本用法不变,本文只展示 pytorch_lightning的用法。使用pytorch_lighting写model类时,类中要包含训练测试优化的过程,继承pytorch_lightning.LightningModule类时强制要求重写下面三种方法:

class FCN(pytorch_lightning.LightningModule): 
    def __init__(self): 
        pass 
    def training_step(self, batch, batch_idx): 
        pass      
    def configure_optimizers(self): 
        pass

下面展示一个具体例子:

#先定义基本内容
class MNISTModel(pytorch_lightning.LightningModule):
    def __init__(self, data_dir=PATH_DATASETS, hidden_size=64, learning_rate=2e-4):
        super().__init__()
        self.data_dir = data_dir
        self.hidden_size = hidden_size
        self.learning_rate = learning_rate
        self.num_classes = 10
        self.dims = (1, 28, 28)
        channels, width, height = self.dims
        self.accuracy = Accuracy()

        # Define PyTorch model
        self.model = FCN(data_dir, hidden_size, learning_rate)

    def forward(self, x):
        return self.model(x)

#再写其他三个函数
class MNISTModel(pytorch_lightning.LightningModule):

    def training_step(self, batch, batch_idx):
        x, y = batch
        logits = self(x)
        loss = F.nll_loss(logits, y)
        self.log("train_loss", loss, prog_bar=True)
        return loss

    def validation_step(self, batch, batch_idx):
        x, y = batch
        logits = self(x)
        loss = F.nll_loss(logits, y)
        preds = torch.argmax(logits, dim=1)
        self.accuracy(preds, y)

        self.log("val_loss", loss, prog_bar=True)
        self.log("val_acc", self.accuracy, prog_bar=True)
        return loss 
   
    def configure_optimizers(self):
        optimizer = torch.optim.Adam(self.parameters(), lr=self.learning_rate)
        return optimizer

2.构建dataloader

dataset创建部分和pytorch一样
在Pytorch Lightning中,DataLoader实例需要被包含在一个继承自pytorch_lightning.LightningDataModule的类中,在这个类里重写各个方法,返回不同的DataLoader实例

class MNISTData(pytorch_lightning.LightningDataModule):
    def __init__(self):
      self.data_dir = PATH_DATASETS
      self.transform = transforms.Compose([transforms.ToTensor(),
                transforms.Normalize((0.1307,), (0.3081,)),])

    def prepare_data(self):
        # download
        torchvision.datasets.MNIST(self.data_dir, train=True, download=True)
        torchvision.datasets.MNIST(self.data_dir, train=False, download=True)

    def setup(self, stage=None):
        # Assign train/val datasets for use in dataloaders
        if stage == "fit" or stage is None:
            mnist_full = torchvision.datasets.MNIST(self.data_dir, train=True, transform=self.transform)
            self.mnist_train, self.mnist_val = random_split(mnist_full, [55000, 5000])

        # Assign test dataset for use in dataloader(s)
        if stage == "test" or stage is None:
            self.mnist_test = torchvision.datasets.MNIST(self.data_dir, train=False, transform=self.transform)

    def train_dataloader(self):
        return DataLoader(self.mnist_train, batch_size=BATCH_SIZE)

    def val_dataloader(self):
        return DataLoader(self.mnist_val, batch_size=BATCH_SIZE)

    def test_dataloader(self):
        return DataLoader(self.mnist_test, batch_size=BATCH_SIZE)

3 开始训练

3.1基础训练

在前两节我们准备好了:
模型:包括了将Pytorch模型实例化以及具体的训练/验证/测试步骤
数据:包括训练/验证/测试集划分及各自的DataLoader
那么训练代码如下:

def train():
    model = MNISTModel()
    data = MNISTData()
    trainer = Trainer()
    trainer.fit(model, data)

if __name__ == "__main__":
    train()

使用Pytorch Lightning可以免去手动添加.cuda()的这些操作,也可以较方便地在多卡GPU及TPU上进行训练,同时因为LightningModule中training_step等方法的区分,也免去了with torch.no_grad() model.eval() model.train()等的操作。

3.2 logging

要记录日志到Tensorboard和/或进度条,请使用log()方法,该方法可以从LightningModule中的任何方法调用。

def training_step(self, batch, batch_idx):
    self.log('my_metric', x)

def training_step(self, batch, batch_idx):
    self.log('my_loss', loss, on_step=True, on_epoch=True, prog_bar=True, logger=True)

log()方法有几个选项:

on_step (记录训练中该步骤的度量)
on_epoch (在epoch结束时自动累积并记录) 注:on_epoch =True将在整个训练期间累积记录的值
prog_bar (记录到进度条)
logger (记录到记录器,如 Tensorboard )
根据调用日志的位置,Lightning auto会为你确定正确的模式。当然,你可以通过手动设置标志来覆盖默认行为。

3.3 Trainer的参数接收

3.3.1 基础应用

Trainer接收的参数可以在文件中硬编码,也可以像往常一样使用argparse来接收

Trainer可以接受的参数可以直接使用Trainer.add_argparse_args来添加,免去手动去写一条条的argparse

在实例化Trainer时,使用Trainer.from_argparse_args(args)来导入接收到的args

例如:

from argparse import ArgumentParser

parser = ArgumentParser()
parser.add_argument("--layer_1_dim", type=int, default=128)
args = parser.parse_args()

#这样就可以用下面方式运行代码:
python trainer.py --layer_1_dim 64
3.3.2 进阶应用

3.4 设配选择

# CPU 
trainer = Trainer(accelerator="cpu") 
# GPU 
trainer = Trainer(accelerator="gpu") 

#设置使用的硬件之后,对于多GPU,还可以指定使用的数量或是使用哪一个
#设置为整数时为调用的硬件数量,这里实际调用的为id为0,1的GPU 
trainer = Trainer(devices=2, accelerator="gpu") 
# 传入list,调用id为1,3的GPU 
trainer = Trainer(devices=[1, 3], accelerator="gpu") 
# 选取所有GPU 
trainer = Trainer(devices=-1, accelerator="gpu") 

#自动选择GPU
#自动选择两个可用gpu
trainer = Trainer(gpus=2, auto_select_gpus=True) 
#选取所有可用的GPU 
Trainer(gpus=-1, auto_select_gpus=True) 

3.5 基础设置(log目录,检查点,终止条件,进度条显示)

3.5.1 设置保存训练log以及checkpoint的目录,默认为当前目录,可根据需要设定
# 默认 
trainer = Trainer(default_root_dir=os.getcwd()) 
3.5.2 保存检查点

默认开启检查点,开启后会在Trainer的回调函数列表callbacks中加入一个ModelCheckpoint回调默认保存的是最新一个epoch的检查点

trainer = Trainer(enable_checkpointing=True) 

也可以实现自己的ModelCheckpoint回调来保存满足需要的检查点,例如保存验证集上误差最小的检查点:

from pytorch_lightning.callbacks import ModelCheckpoint 
# 初始化ModelCheckpoint,设置监控的变量名称 
checkpoint_callback = ModelCheckpoint(monitor="val_acc") 
# 将checkpoint_callback加入Trainer的回调函数列表 
trainer = Trainer(enable_checkpointing=True, callbacks=[checkpoint_callback]) 

检查点默认保存位置与default_root_dir一致,可以专门设置weights_save_path为模型保存的位置

trainer = Trainer(weights_save_path="./checkpoints") 
3.5.3 加载检查点
trainer.fit(ckpt_path="./checkpoints/latest.ckpt") 
#推荐上面那种方法
trainer = Trainer(resume_from_checkpoint="./checkpoints/latest.ckpt") 
3.5.4 设置终止条件

设置训练最大/最小的epoch,也可以设置step,默认参数为:

trainer = Trainer(min_epochs = None, max_epochs = None, min_steps = None, max_steps = -1) 

此外也可以设置最大的训练时长,接受的格式为字符串或字典

trainer = Trainer(max_time="01:05:00:00") 
trainer = Trainer(max_time={"days": 1, "hours": 5}) 

3.5.5 进度条

可以选择是否显示进度条以及进度条的刷新频率

trainer = Trainer(enable_progress_bar=True, progress_bar_refresh_rate=1) 

3.6 辅助工具

3.6.1 最大batch size搜索

可以在训练开始之前来搜索可以使用的最大batch size,并应用于trainer
设置auto_scale_batch_size=“binsearch”,并执行trainer.tune(model)进行搜索,搜索到的最大batch size后将会自动覆盖trainer的hparams.batch_size

trainer = Trainer(auto_scale_batch_size="binsearch")  
trainer.tune(model)   
3.6.2 自动学习率查找

用法与自动batch size查找类似,设置auto_lr_find=True,并使用trainer.tune(model)来查找最合适的初始学习率

trainer = Trainer(auto_lr_find=True)  
trainer.tune(model)   

三 omegaconf 库

1 基础用法

OmegaConf 是一个用于处理配置文件的工具库,它可以帮助开发者轻松地读取、修改和管理配置信息
用以下config.yaml作为示范:

model:
    name: "ResNet"
    num_layers: 18
    dropout: 0.5
    optimizer:
        name: "Adam"
        learning_rate: 0.001

加载配置文件:

from omegaconf import OmegaConf
# 使用 YAML 文件加载配置
config = OmegaConf.load("config.yaml")

访问配置文件:

#使用点运算符来访问嵌套配置项:
model_name = config.model.name
num_layers = config.model.num_layers

#使用索引来访问列表项:
layer_1 = config.model.layers[0]
layer_2 = config.model.layers[1]

#使用 get() 方法来访问配置项,并提供默认值:
dropout = config.model.get("dropout", 0.0)
learning_rate = config.model.optimizer.get("learning_rate", 0.01)

修改配置信息:

#使用点运算符来修改嵌套配置项:
config.model.name = "VGG"
config.model.num_layers = 16

#使用索引来修改列表项:
config.model.layers[0] = "Conv"
config.model.layers[1] = "ReLU"

#使用 update() 方法来修改整个配置块:
config.model.optimizer.update({"learning_rate": 0.0001})

四 transformers库

4.1 NLP Tokenizer

处理文本数据的主要工具是tokenizer,首先tokenizer会根据一组规则将文本拆分成token,然后将这些token转换成数值(根据词表,即 vocab),这些数值会被构建成张量并作为模型的输入,模型所需要的其他输入也是有tokenizer添加的。

4.1.1 加载

from transformers import BertTokenizer,BertModel
 
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
model = BertModel.from_pretrained('bert-base-uncased')
 

4.1.2 使用

BertTokenizer主要实现文本分词和把分词后的token编码成符合模型输入要求的整数索引功能, 为满足不同预训练模型对文本序列的要求,BertTokenizer还会自动在文本序列中添加一些额外符号([CLS]、[SEP]、[PAD])等。
BertTokenizer类包含三个文件:vocab.txt,tokenizer.json和tokenizer_config.json,vocab.txt是词表文件(文件中是保留符号和单个汉字索引,字符),tokenizer.jsontokenizer_config.json是分词的配置文件,根据设置文件把vocab词表中的词按顺序生成索引号(行号-1就是索引号),模型根据词对应的索引号编码生成one-hot向量与embeding训练权重矩阵相乘获得该字符的词向量。(简单说就是token根据词表中单词对应的索引编号查找Embedding.weight的词向量表生成模型可使用的词向量。)

此外,tokenizer主要完成的工作:

1.分词:将文本数据分词为字或者字符;
2.构建词典:根据数据集分词的结果,构建词典。射(这一步并不绝对,如果采用预训练词向量,词典映射要根据词向量文件进行处理)。
3.数据转换:根据构建好的词典,将分词处理后的数据做映射,将文本序列转换为数字序列。数字序列还要变成符合模型需求的tensor格式。
4.数据填充与截断:在以batch输入到模型的方式中,需要对过短的数据进行填充,过长的数据进行截断,保证数据长度符合模型能接受的范围,同时batch内的数据维度大小一致,否则无法成批次变成tensor张量。

4.1.2.1 tokenize

该函数实现分词功能

txt = '这是一个美丽的城市'
token_ids = tokenizer.tokenize(txt)
print(token_ids)
#['这', '是', '一', '个', '美', '丽', '的', '城', '市']
4.1.2.2 convert_tokens_to_ids

该函数将每个词转换为词典的索引

input_ids = tokenizer.convert_tokens_to_ids(token_ids)
print(input_ids)
#[6821, 3221, 671, 702, 5401, 714, 4638, 1814, 2356]
4.1.2.3 encode

encode()方法完成分词和整数编码的同时,系统对文本序列自动添加分类符和间隔符,在函数实参传递过程中不设置return_tensors属性时函数返回值为列表,设置return_tensors='pt’返回值为pytorch的tensor张量。

txt = '这是一个美丽的城市'
ckpt = r'.\ConvAdapter\vocab\bert\chinese_roberta_wwm_base_ext_pytorch'
tokenizer =BertTokenizer.from_pretrained(ckpt)
 
######encode函数######
input_ids = tokenizer.encode(txt,max_length=20,add_special_tokens=True,                                 
                              padding='max_length', truncation=True)
print(input_ids) 
 
#返回一个list
#[101, 6821, 3221, 671, 702, 5401, 714, 4638, 1814, 2356, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0]
4.1.2.4 add_tokens([new_vocab])

向词典添加新词

num_added_toks = tokenizer.add_tokens('COVID')
print(num_added_toks)
# num_added_toks表示新添加词汇数量
 
result = tokenizer.tokenize('COVID')
print(result)

N 其他零散函数

1.functools.partial

functools.partial 可以用来固定一个函数的部分参数,从而创建一个新的函数,这个新函数的调用会比原函数少接受一些参数

from functools import partial

# 定义一个简单的函数
def multiply(x, y):
    return x * y

# 使用 partial 固定其中一个参数为 2
double = partial(multiply, 2)

# 现在 double 就是一个新的函数,只需要一个参数 y
result = double(3)  # 等价于调用 multiply(2, 3)
print(result)  # 输出 6

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值