磐创AI分享
作者 | Abid Ali Awan 编译 | VK 来源 | Towards Data Science
介绍
埃维语和丰贝语是尼日尔-刚果语,属于一组相关语言,通常称为Gbe。
丰贝语是贝宁的主要语言(约410万人讲),而多哥和加纳东南部约有450万人使用埃维语作为第一语言,另有100万人使用埃维语作为第二语言。
它们是与声调语言密切相关的语言,并且都包含变音符号,这使得它们难以学习、理解和翻译。有关更多信息,请访问Zindi:https://zindi.africa/competitions/ai4d-takwimu-lab-machine-translation-challenge。
目标
这项挑战的目标是创建一个机器翻译系统,能够将法语文本转换为埃维语和丰贝语。
我将使用相同的模型来训练和转换这两个数据集,以缓解处理能力和内存问题。
Simple Transformers
该库基于HuggingFace的Transformers库。Simple Transformers可以让你快速训练和评估Transformer模型。
初始化模型、训练模型和评估模型只需要3行代码。有关更多信息,请访问GitHub Repo:https://github.com/ThilinaRajapakse/simpletransformers。
支持
- 序列分类
- token分类(NER)
- 问答
- 语言模型微调
- 语言模型训练
- 语言生成
- T5模型
- Seq2Seq任务
- 多模态分类
- 对话人工智能。
- 文本表示生成。
安装和加载库
代码语言:javascript复制!pip install simpletransformers
!pip install fsspec==2021.5.0
import logging
import pandas as pd
from sklearn.model_selection import train_test_split
from simpletransformers.seq2seq import Seq2SeqModel,Seq2SeqArgs
logging.basicConfig(level=logging.INFO)
transformers_logger = logging.getLogger("transformers")
transformers_logger.setLevel(logging.WARNING)
数据
我只使用了35k个样本,这样我的GPU就不会耗尽内存,而且我使用的是原始数据,没有进行预处理。
代码语言:javascript复制df = pd.read_csv("Fon_and_ewe/Train.csv")[
0:35000
] # 更改训练数据目录
test = pd.read_csv(
"Fon_and_ewe/Test.csv"
) # 更改测试数据目录
Clean = False # 清理文本
清理函数在英文翻译中很有用,但在这种情况下,如果我们清理数据,结果会很差。所以,我们要把它关掉。
代码语言:javascript复制if Clean:
# 每个字母转换为小写
df["Target"] = df["Target"].apply(lambda x: str(x).lower())
df["French"] = df["French"].apply(lambda x: str(x).lower())
# 去掉句子中的撇号
df["Target"] = df["Target"].apply(lambda x: re.sub("'", "", x))
df["French"] = df["French"].apply(lambda x: re.sub("'", "", x))
exclude = set(string.punctuation)
# 去掉所有标点符号
df["Target"] = df["Target"].apply(
lambda x: "".join(ch for ch in x if ch not in exclude)
)
df["French"] = df["French"].apply(
lambda x: "".join(ch for ch in x if ch not in exclude)
)
# 从句子中删除数字
digit = str.maketrans("", "", string.digits)
df["Target"] = df["Target"].apply(lambda x: x.translate(digit))
df["French"] = df["French"].apply(lambda x: x.translate(digit))
基于语言将训练和测试数据划分为两个数据帧。
代码语言:javascript复制Fon = df[df.Target_Language=="Fon"]
Ewe = df[df.Target_Language=="Ewe"]
Fon_test = test[test.Target_Language=="Fon"]
Ewe_test = test[test.Target_Language=="Ewe"]
训练丰贝语
使用简单的转换器seq2seq,我下载了 Helsinki-NLP/opus-mt-en-mul ,它在我们的案例中工作得最好,并使用特定的Seq2SeqArg设置模型参数。
参数:
- num_train_epochs = 30
- batch_size = 32
- max_length = 120
- src_lang =”fr”
- tgt_lang =”fon”
- overwrite_output_dir = True
训练/评估分离
代码语言:javascript复制train_data = Fon[["French","Target"]]
train_data = train_data.rename(columns={"French":"input_text","Target":"target_text"})
train_df, eval_df = train_test_split(train_data, test_size=0.2, random_state=42)
参数
我尝试了多个参数,得出了最好的结果。
代码语言:javascript复制model_args = Seq2SeqArgs()
model_args.num_train_epochs = 30
model_args.no_save = True
model_args.evaluate_generated_text = False
model_args.evaluate_during_training = False
model_args.evaluate_during_training_verbose = True
model_args.rag_embed_batch_size = 32
model_args.max_length = 120
model_args.src_lang ="fr"
model_args.tgt_lang ="fon"
model_args.overwrite_output_dir = True
初始化模型
代码语言:javascript复制model_fon = Seq2SeqModel(
encoder_decoder_type="marian",
encoder_decoder_name="Helsinki-NLP/opus-mt-en-mul",
args=model_args,
use_cuda=True,
)
评价指标
代码语言:javascript复制def count_matches(labels, preds):
print(labels)
print(preds)
return sum(
[
1 if label == pred else 0
for label, pred in zip(labels, preds)
]
)
训练模型
代码语言:javascript复制model_fon.train_model(
train_df, eval_data=eval_df, matches=count_matches
)
单一预测
模型运行准确。
代码语言:javascript复制# 预测
print(
model_fon.predict(
Fon_test["French"].values[25]
)
)
代码语言:javascript复制Generating outputs: 0%| | 0/24 [00:00<?, ?it/s]
/usr/local/lib/python3.7/dist-packages/transformers/tokenization_utils_base.py:3260: FutureWarning: `prepare_seq2seq_batch` is deprecated and will be removed in version 5 of