首页 > 解决方案 > 如何序列化 NLP 分类 PyTorch 模型

问题描述

我正在尝试在 PyTorch android 演示应用程序Demo App Git中使用新的 NLP 模型,但是我正在努力序列化模型以使其适用于 Android。

PyTorch 给出的一个 Resnet 模型的演示如下:

model = torchvision.models.resnet18(pretrained=True)
model.eval()
example = torch.rand(1, 3, 224, 224)
traced_script_module = torch.jit.trace(model, example)
traced_script_module.save("app/src/main/assets/model.pt")

但是,我不确定在我的 NLP 模型中使用什么作为“示例”输入。

我在 fastai 教程中使用的模型和 python 链接在这里:模型

这是用于创建我的模型的 Python(使用 Fastai 库)。它与上面的模型链接相同,但采用简化形式。

from fastai.text import *
path = untar_data('http://files.fast.ai/data/examples/imdb_sample')
path.ls()
#: [PosixPath('/storage/imdb_sample/texts.csv')]
data_lm = TextDataBunch.from_csv(path, 'texts.csv')
data = (TextList.from_csv(path, 'texts.csv', cols='text')
                .split_from_df(col=2)
                .label_from_df(cols=0)
                .databunch())
bs=48
path = untar_data('https://s3.amazonaws.com/fast-ai-nlp/imdb')
data_lm = (TextList.from_folder(path)
            .filter_by_folder(include=['train', 'test', 'unsup']) 
            .split_by_rand_pct(0.1)
            .label_for_lm()           
            .databunch(bs=bs))
learn = language_model_learner(data_lm, AWD_LSTM, drop_mult=0.3)
learn.fit_one_cycle(1, 1e-2, moms=(0.8,0.7))
learn.unfreeze()
learn.fit_one_cycle(10, 1e-3, moms=(0.8,0.7))
learn.save_encoder('fine_tuned_enc')
path = untar_data('https://s3.amazonaws.com/fast-ai-nlp/imdb')
data_clas = (TextList.from_folder(path, vocab=data_lm.vocab)
             .split_by_folder(valid='test')
             .label_from_folder(classes=['neg', 'pos'])
             .databunch(bs=bs))
learn = text_classifier_learner(data_clas, AWD_LSTM, drop_mult=0.5)
learn.load_encoder('fine_tuned_enc')
learn.fit_one_cycle(1, 2e-2, moms=(0.8,0.7))
learn.freeze_to(-2)
learn.fit_one_cycle(1, slice(1e-2/(2.6**4),1e-2), moms=(0.8,0.7))
learn.freeze_to(-3)
learn.fit_one_cycle(1, slice(5e-3/(2.6**4),5e-3), moms=(0.8,0.7))
learn.unfreeze()
learn.fit_one_cycle(2, slice(1e-3/(2.6**4),1e-3), moms=(0.8,0.7))

标签: androidpytorchfast-aitorchscript

解决方案


一段时间后,我想出了如何做到这一点。问题是,无论我使用什么形状的输入,Fastai 模型都无法正确跟踪。

最后,我使用了另一个文本分类模型并让它工作。我写了一个关于我是如何做到的教程,以防它可以帮助其他人。

NLP PyTorch 追踪教程

首先使用您首选的云机器提供商(我使用 Paperspace)打开一个新的 Jupyter Python Notebook。

接下来,复制并运行 PyTorch 文本分类教程中的代码。但是换行……</p>

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

用……</p>

device = torch.device("cpu")

注意:当设备设置为 CUDA 时,它会导致跟踪问题,因此我将其强制到 CPU 上。(这会减慢训练速度,但移动设备上的推理运行速度将与 CPU 运行速度相同)

最后,运行下面的代码以正确跟踪模型以使其在 Android 上运行:

data = DataLoader(test_dataset, batch_size=1, collate_fn=generate_batch)
for text, offsets, cls in data:
        text, offsets, cls = text.to(device), offsets.to(device), cls.to(device)
example = text, offsets
traced_script_module = torch.jit.trace(model, example)
traced_script_module.save("model.pt")

此外,如果您希望在进行预测时在 Android 上使用词汇表的 CSV 副本,请在之后运行以下代码:

import pandas as pd
vocab = train_dataset.get_vocab()
df = pd.DataFrame.from_dict(vocab.stoi, orient='index', columns=['token'])
df[:30]
df.to_csv('out.csv')

这个模型应该可以在使用 PyTorch API 的 Android 上正常工作。


推荐阅读