搬运自此处
Pytorch-Lightning简明使用教程
Pytorch Lightning 完全攻略
PyTorch Lightning完全继承于Pytorch,Pytorch的所有东西都可以在PyTorch Lightning中使用,PyTorch Lightning的所有物品也可在Pytorch中使用。
PyTorch Lightning作为Pytorch的高级封装,内部包含着完整且可修改的训练逻辑。
PyTorch Lightning的硬件检测基于Pytorch,也可以使用Trainer修改。
PyTorch Lightning中数据类型自动变化,无需.cpu和.cuda。
(1)定义模型
__init__()
:同torch.nn.Module中的__init__,用于构建模型。
forward(*args, **kwargs)
:同torch.nn.Module中的forward,通过__init__中的各个模块实现前向传播。
(2)训练模型
#训练模型
training_step(*args, **kwargs)
"""
训练一批数据并反向传播。参数如下:
- batch (Tensor | (Tensor, …) | [Tensor, …]) – 数据输入,一般为x, y = batch。
- batch_idx (int) – 批次索引。
- optimizer_idx (int) – 当使用多个优化器时,会使用本参数。
- hiddens (Tensor) – 当truncated_bptt_steps > 0时使用。
"""
#举个例子:
def training_step(self, batch, batch_idx): # 数据类型自动转换,模型自动调用.train()
x, y = batch
_y = self(x)
loss = criterion(_y, y) # 计算loss
return loss # 返回loss,更新网络
def training_step(self, batch, batch_idx, hiddens):
# hiddens是上一次截断反向传播的隐藏状态
out, hiddens = self.lstm(data, hiddens)
return {"loss": loss, "hiddens": hiddens}
#--------------------------------------
training_step_end(*args, **kwargs)
"""一批数据训练结束时的操作。一般用不着,分布式训练的时候会用上。参数如下:
- batch_parts_outputs – 当前批次的training_step()的返回值
"""
#举个例子:
def training_step(self, batch, batch_idx):
x, y = batch
_y = self(x)
return {"output": _y, "target": y}
def training_step_end(self, training_step_outputs): # 多GPU分布式训练,计算loss
gpu_0_output = training_step_outputs[0]["output"]
gpu_1_output = training_step_outputs[1]["output"]
gpu_0_target = training_step_outputs[0]["target"]
gpu_1_target = training_step_outputs[1]["target"]
# 对所有GPU的数据进行处理
loss = criterion([gpu_0_output, gpu_1_output], [gpu_0_target, gpu_1_target])
return loss
#--------------------------------------
training_epoch_end(outputs)
"""一轮数据训练结束时的操作。主要针对于本轮所有training_step的输出。参数如下:
- outputs (List[Any]) – training_step()的输出。
"""
#举个例子:
def training_epoch_end(self, outs): # 计算本轮的loss和acc
loss = 0.
for out in outs: # outs按照训练顺序排序
loss += out["loss"].cpu().detach().item()
loss /= len(outs)
acc = self.train_metric.compute()
self.history["loss"].append(loss)
self.history["acc"].append(acc)
三个核心组件:
数据流伪代码:
outs = []
for batch in data:
out = training_step(batch)
outs.append(out)
training_epoch_end(outs)
等价Lightning代码:
def training_step(self, batch, batch_idx):
prediction = ...
return prediction
def training_epoch_end(self, training_step_outputs):
for prediction in predictions:
# do something with these
我们需要做的,就是像填空一样,填这些函数。
(1)方法
__init__(logger=True, checkpoint_callback=True, callbacks=None, \
default_root_dir=None, gradient_clip_val=0, process_position=0, num_nodes=1, \
num_processes=1, gpus=None, auto_select_gpus=False, tpu_cores=None, \
log_gpu_memory=None, progress_bar_refresh_rate=1, overfit_batches=0.0, \
track_grad_norm=-1, check_val_every_n_epoch=1, fast_dev_run=False, \
accumulate_grad_batches=1, max_epochs=1000, min_epochs=1, max_steps=None, \
min_steps=None, limit_train_batches=1.0, limit_val_batches=1.0, \
limit_test_batches=1.0, val_check_interval=1.0, flush_logs_every_n_steps=100, \
log_every_n_steps=50, accelerator=None, sync_batchnorm=False, precision=32, \
weights_summary='top', weights_save_path=None, num_sanity_val_steps=2, \
truncated_bptt_steps=None, resume_from_checkpoint=None, profiler=None, \
benchmark=False, deterministic=False, reload_dataloaders_every_epoch=False, \
auto_lr_find=False, replace_sampler_ddp=True, terminate_on_nan=False, \
auto_scale_batch_size=False, prepare_data_per_node=True, plugins=None, \
amp_backend='native', amp_level='O2', distributed_backend=None, \
automatic_optimization=True, move_metrics_to_cpu=False)
初始化训练器,参数很多,下面将分别介绍:
硬件参数:
精度参数:
训练超参:
日志参数和检查点参数:
测试参数:
分布式参数:
accelerator[None]:
dp(DataParallel)是在同一计算机的GPU之间拆分批处理。
ddp(DistributedDataParallel)是每个节点上的每个GPU训练并同步梯度。TPU默认选项。
ddp_cpu(CPU上的DistributedDataParallel)与ddp相同,但不使用GPU。对于多节点CPU训练或单节点调试很有用。
ddp2是节点上的dp,节点间的ddp。
accumulate_grad_batches[1]: 多少批进行一次梯度累积。
sync_batchnorm[False]: 同步批处理,一般是在分布式多GPU时使用。
自动参数:
确定性参数:
限制性参数和采样参数:
其他参数:
fit(model, train_dataloader=None, val_dataloaders=None, datamodule=None)
开启训练。参数如下:
test(model=None, test_dataloaders=None, ckpt_path=‘best’, verbose=True, datamodule=None)
开启测试。参数如下:
tune(model, train_dataloader=None, val_dataloaders=None, datamodule=None)
训练之前调整超参数。参数如下:
(2)属性
def training_step(self, batch, batch_idx):
self.log('a_val', 2)
callback_metrics = trainer.callback_metricpythons
assert callback_metrics['a_val'] == 2
def training_step(self, batch, batch_idx):
current_epoch = self.trainer.current_epoch
if current_epoch > 100:
# do something
pass
def training_step(self, batch, batch_idx):
logger = self.trainer.logger
tensorboard = logger.experiment
def training_step(self, batch, batch_idx):
self.log('a_val', 2, log=True)
logged_metrics = trainer.logged_metrics
assert logged_metrics['a_val'] == 2
def training_step(self, batch, batch_idx):
img = ...
save_img(img, self.trainer.log_dir)
is_global_zero 是否为全局第一个。
progress_bar_metrics 发送到进度条的指标。举个例子:
def training_step(self, batch, batch_idx):
self.log('a_val', 2, prog_bar=True)
progress_bar_metrics = trainer.progress_bar_metrics
assert progress_bar_metrics['a_val'] == 2
(1)训练方法
on_train_start(trainer, pl_module)
当第一次训练开始时的操作。
on_train_end(trainer, pl_module)
当最后一次训练结束时的操作。
on_train_batch_start(trainer, pl_module, batch, batch_idx, dataloader_idx)
当一批数据训练开始时的操作。
on_train_batch_end(trainer, pl_module, outputs, batch, batch_idx, dataloader_idx)
当一批数据训练结束时的操作。
on_train_epoch_start(trainer, pl_module)
当一轮数据训练开始时的操作。
on_train_epoch_end(trainer, pl_module, outputs)
当一轮数据训练结束时的操作。
(2)验证方法
on_validation_start(trainer, pl_module)
当第一次验证开始时的操作。
on_validation_end(self, trainer, pl_module)
当最后一次验证结束时的操作。
on_validation_batch_start(trainer, pl_module, batch, batch_idx, dataloader_idx)
当一批数据验证开始时的操作。
on_validation_batch_end(trainer, pl_module, outputs, batch, batch_idx, dataloader_idx)
当一批数据验证结束时的操作。
on_validation_epoch_start(trainer, pl_module)
当一轮数据验证开始时的操作。
on_validation_epoch_end(trainer, pl_module)
当一轮数据验证结束时的操作。
(3)测试方法
on_test_start(trainer, pl_module)
当第一次测试开始时的操作。
on_test_end(self, trainer, pl_module)
当最后一次测试结束时的操作。
on_test_batch_start(trainer, pl_module, batch, batch_idx, dataloader_idx)
当一批数据测试开始时的操作。
on_test_batch_end(trainer, pl_module, outputs, batch, batch_idx, dataloader_idx)
当一批数据测试结束时的操作。
on_test_epoch_start(trainer, pl_module)
当一轮数据测试开始时的操作。
on_test_epoch_end(trainer, pl_module)
当一轮数据测试结束时的操作。
(4)其他方法
on_fit_start(trainer, pl_module)
当调用.fit时的操作。
on_fit_end(trainer, pl_module)
.fit结束时的操作。
setup(trainer, pl_module, stage)
teardown(trainer, pl_module, stage)
on_init_start(trainer)
on_init_end(trainer)
on_sanity_check_start(trainer, pl_module)
on_sanity_check_end(trainer, pl_module)
on_batch_start(trainer, pl_module)
on_batch_end(trainer, pl_module)
on_epoch_start(trainer, pl_module)
on_epoch_end(trainer, pl_module)
on_keyboard_interrupt(trainer, pl_module)
on_save_checkpoint(trainer, pl_module)
on_load_checkpoint(checkpointed_state)