跳转到主要内容

AI项目用Wingman库。

项目描述

Wingman

Wingman是一个用于管理深度学习项目的Python库。目前,Wingman能够自动处理

  • 自动保存和版本控制权重
  • 平滑WanbB集成
  • 流行torch模块的构建块
  • 平滑处理命令行参数和*.yaml配置文件

安装

pip3 install jj-wingman

Wingman默认不包含PyTorch要求,因此默认禁用了所有torch功能。如果您希望使用Wingman的PyTorch功能,请为您的机器安装兼容的Pytorch版本。这通常通过以下方式完成:pip3 install torch

哲学

Wingman被设计成非常易于集成到您的深度学习项目中。Wingman不会通过包装器包装您的模型或围绕Wingman设计模型,而是适应您的项目,您是决定何时以及在哪里使用Wingman的人。

模块

Wingman有多个核心模块和静态函数,所有这些都可以独立使用或结合使用。


from wingman import Wingman

这是Wingman的核心模块,Wingman需要在您的项目目录中某个可访问的位置有一个最简单的config.yaml文件,这可以通过在命令行上运行wingman-generate-yaml [可选的文件名]来生成。最简单的yaml文件如下

# wingman required params
debug: false

save_directory: 'weights'
model_id: null
ckpt_number: 0
log_status: false

increment: true
logging_interval: 10
max_skips: 5
greater_than: 0.0

wandb: false
wandb_name: ''
wandb_notes: ''
wandb_id: ''
wandb_entity: 'jjshoots'
wandb_project: 'my_new_project'

以下是对参数的描述

  • debug:是否将模型设置为调试模式
  • save_directory:Wingman应指向何处保存模型权重
  • model_id:Wingman 记录此 ID 下的模型,如果留空,Wingman 将自动选择一个数字。
  • ckpt_number:如果留空,Wingman 将使用此数字检查点模型,如果将 increment 参数设置为 true,则发生自动检查点编号。
  • log_status:是否保存 Wingman 输出的 .txt 日志文件。
  • increment:是否增加检查点编号,如果设置为 false,Wingman 不会保存相同模型的多个变体。
  • logging_interval:在训练期间,将训练步骤传递给 Wingman,在 logging_interval 步骤通过后,Wingman 将记录训练。如果 Wingman 找到一个新的最低点,则将模型权重保存到新文件。
  • max_skips:在找到新的最低点(使用 logging_interval 参数指定)之前,跳过了多少个日志步骤,然后 Wingman 将保存模型的中间检查点。
  • greater_than:您可以通过此值告诉 Wingman 仅在先前检查点的损失大于当前损失时检查点模型。
  • wandb:是否将内容记录到 WandB。
  • wandb_name:在 WandB 中显示的运行名称。如果留空,Wingman 将根据模型版本号自动分配一个。
  • wandb_notes:一些有用的注释,您可以为将要记录在 WandB 中的运行留下。
  • wandb_id:此运行的唯一 ID。如果留空,将自动分配一个。
  • wandb_entity:您的 WandB 用户名/组织名称。
  • wandb_project:此运行所在的工程。

如果您需要更多参数,可以将它们添加到 config.yaml 文件中,并在以后轻松地参考这些参数。此外,Wingman 还会自动生成一个 device 参数,如果您的系统有 GPU,则此参数将自动设置为 GPU,可以用于以后的张量轻松传输。

您还可以使用 config.yaml 文件定义一组合理的默认值,然后稍后使用命令行参数覆盖它们。这是因为 Wingman 会自动将 config.yaml 文件中的所有参数转换为命令行参数,使用 Python 模块 argparse。这使得您的 main.py 文件更加简洁,无需在顶部编写 50 多行代码来定义参数。例如,如果您在 config.yaml 中有 hack_level=10.3,则可以通过命令行参数通过执行 python3 your_program.py --hack_level=69.420 来覆盖其值。

在定义您的 config.yaml 文件后,Wingman 的基本用法如下

    from wingman import Wingman

    # initialize Wingman and get all the parameters from the `config.yaml` file
    wm = Wingman("./config.yaml")
    cfg = wm.cfg

    # load the model and optimizer, `cfg.device` is automatically generated
    model = Model(cfg.YOUR_PARAM, cfg.YOUR_OTHER_PARAM).to(cfg.device)
    optim = optimizer.AdamW(model.parameters(), lr=cfg.YOUR_LEARNING_RATE_PARAM, amsgrad=True)

    # we can check if we have trained this model before, and if we have, just load it
    # this checking is done using the `model_id` param, if `latest=True` is set,
    # Wingman automatically searches for the latest model checkpoint,
    # otherwise, Wingman uses the checkpoint specified by `ckpt_number`
    have_file, weight_file, optim_file = wm.get_weight_files(latest=True)
    if have_file:
        # Wingman simply returns a string of where the weight files are
        # no unnecessary wrapping!
        model.load_state_dict(torch.load(model_file))
        optim.load_state_dict(torch.load(optim_file))

    # let's run some training:
    while(training):
        ...
        # training code here
        loss = YOUR_LOSS_FUNCTION(model)
        ...

        # when wandb is enabled (via `wandb = true` in the yaml file)
        # logging can be done by passing Wingman a dictionary
        # the dictionary is logged to wandb every logging interval
        wm.log = {"log": 5, "these": 2.34, "values": -5.432}

        # ... or you can force wandb logging using
        wm.wandb_log()

        # let Wingman handle checkpointing for you
        update_weights, model_file, optim_file = wm.checkpoint(loss, training_step)
        if update_weights:
            # if Wingman deems that the weights should be checkpointed, it returns
            # a string of where the weight files should go for it to be found later
            torch.save(model.state_dict(), model_file)
            torch.save(optim.state_dict(), optim_file)

权重目录压缩

如果您训练了大量的模型,权重目录可能会开始占用大量的磁盘空间。在命令行上运行 wingman-compress-weights [可选目录名称] 将删除所有冗余的检查点编号并删除所有空目录。


from wingman import NeuralBlocks

Neural blocks 是一个用于快速原型设计神经网络架构的模块。它提供了定义标准化模块的几种更简单的方法

简单的 3 层 MLP,具有 ReLU 激活

>>> from wingman import NeuralBlocks
>>> features = [4, 16, 64, 3]
>>> activation = ["relu", "tanh", "identity"]
>>> norm = "batch"
>>> bias = True
>>> MLP = NeuralBlocks.generate_linear_stack(features, activation, norm, bias)
>>> print(MLP)

Sequential(
  (0): Sequential(
    (0): BatchNorm1d(4, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
    (1): Linear(in_features=4, out_features=16, bias=True)
    (2): ReLU()
  )
  (1): Sequential(
    (0): BatchNorm1d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
    (1): Linear(in_features=16, out_features=64, bias=True)
    (2): Tanh()
  )
  (2): Sequential(
    (0): BatchNorm1d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
    (1): Linear(in_features=64, out_features=3, bias=True)
    (2): Identity()
  )
)

具有相同填充和最后一个两层 MaxPool2d 的 4 层卷积网络

>>> from wingman import NeuralBlocks
>>> channels = [3, 16, 32, 64, 1]
>>> kernels = [3, 1, 3, 1]
>>> pooling = [0, 0, 2, 2]
>>> activation = ["relu", "relu", "tanh", "tanh"]
>>> padding = None # this is equivalent to same padding
>>> norm = "batch"
>>> CNN = NeuralBlocks.generate_conv_stack(channels, kernels, pooling, activation, padding, norm)
>>> print(CNN)

Sequential(
  (0): Sequential(
    (0): BatchNorm2d(3, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
    (1): Conv2d(3, 16, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (2): ReLU()
  )
  (1): Sequential(
    (0): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
    (1): Conv2d(16, 32, kernel_size=(1, 1), stride=(1, 1))
    (2): ReLU()
  )
  (2): Sequential(
    (0): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
    (1): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    (3): Tanh()
  )
  (3): Sequential(
    (0): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
    (1): Conv2d(64, 1, kernel_size=(1, 1), stride=(1, 1))
    (2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    (3): Tanh()
  )
)

2 层转置卷积网络

>>> from wingman import NeuralBlocks
>>> channels = [64, 32, 3]
>>> kernels = [4, 4]
>>> padding = [1, 1]
>>> stride = [2, 2]
>>> activation = ["lrelu", "lrelu"]
>>> norm = "non"
>>> TCNN = NeuralBlocks.generate_deconv_stack(channels, kernels, padding, stride, activation, norm)
>>> print(TCNN)

Sequential(
  (0): Sequential(
    (0): ConvTranspose2d(64, 32, kernel_size=(4, 4), stride=(2, 2), padding=(1, 1))
    (1): LeakyReLU(negative_slope=0.01)
  )
  (1): Sequential(
    (0): ConvTranspose2d(32, 3, kernel_size=(4, 4), stride=(2, 2), padding=(1, 1))
    (1): LeakyReLU(negative_slope=0.01)
  )
)

Neural Blocks 模块还具有生成单个模块的功能,请参阅文件本身以获取更多信息。


from wingman import gpuize, cpuize

这些是提升生活质量的独立函数。

>>> import numpy as np
>>> from wingman import gpuize, cpuize
>>> foo = np.random.random((5, 5))
>>> print(foo)

[[0.28392764 0.50936983 0.55433616 0.45614518 0.82523046]
 [0.77437072 0.20900382 0.86220494 0.69071239 0.94863786]
 [0.70082865 0.92780018 0.98392965 0.76945165 0.72886401]
 [0.47702485 0.54968522 0.22110942 0.72436276 0.42574472]
 [0.78330221 0.84888837 0.68529167 0.61878902 0.13556213]]

>>> bar = gpuize(foo, "cuda:0")
>>> print(bar)

tensor([[0.2839, 0.5094, 0.5543, 0.4561, 0.8252],
        [0.7744, 0.2090, 0.8622, 0.6907, 0.9486],
        [0.7008, 0.9278, 0.9839, 0.7695, 0.7289],
        [0.4770, 0.5497, 0.2211, 0.7244, 0.4257],
        [0.7833, 0.8489, 0.6853, 0.6188, 0.1356]], device='cuda:0')

>>> baz = cpuize(bar)
>>> print(baz)

[[0.28392764 0.50936983 0.55433616 0.45614518 0.82523046]
 [0.77437072 0.20900382 0.86220494 0.69071239 0.94863786]
 [0.70082865 0.92780018 0.98392965 0.76945165 0.72886401]
 [0.47702485 0.54968522 0.22110942 0.72436276 0.42574472]
 [0.78330221 0.84888837 0.68529167 0.61878902 0.13556213]]

如果与 Wingman 一起使用,当 cfg 被定义为之前所示时,可以简单地执行 gpuize(foo, cfg.device)



为什么每架飞机都有两个飞行员?实际上,您只需要一个飞行员。让我们去掉第二个飞行员。让这个该死的计算机来飞。

项目详情


发布历史 发布通知 | RSS 源

下载文件

下载适用于您平台的文件。如果您不确定选择哪个,请了解有关安装包的更多信息。

源分发

jj_wingman-0.22.2.tar.gz (16.2 kB 查看散列值)

上传时间

构建分发

jj_wingman-0.22.2-py3-none-any.whl (19.0 kB 查看散列值)

上传时间 Python 3

由以下机构支持

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误日志 StatusPage StatusPage 状态页面