磐创AI分享
作者 | Abid Ali Awan 编译 | VK 来源 | Towards Data Science
埃维语和丰贝语是尼日尔-刚果语,属于一组相关语言,通常称为Gbe。
丰贝语是贝宁的主要语言(约410万人讲),而多哥和加纳东南部约有450万人使用埃维语作为第一语言,另有100万人使用埃维语作为第二语言。
它们是与声调语言密切相关的语言,并且都包含变音符号,这使得它们难以学习、理解和翻译。有关更多信息,请访问Zindi:https://zindi.africa/competitions/ai4d-takwimu-lab-machine-translation-challenge。
这项挑战的目标是创建一个机器翻译系统,能够将法语文本转换为埃维语和丰贝语。
我将使用相同的模型来训练和转换这两个数据集,以缓解处理能力和内存问题。
该库基于HuggingFace的Transformers库。Simple Transformers可以让你快速训练和评估Transformer模型。
初始化模型、训练模型和评估模型只需要3行代码。有关更多信息,请访问GitHub Repo:https://github.com/ThilinaRajapakse/simpletransformers。
支持
!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就不会耗尽内存,而且我使用的是原始数据,没有进行预处理。
df = pd.read_csv("Fon_and_ewe/Train.csv")[
0:35000
] # 更改训练数据目录
test = pd.read_csv(
"Fon_and_ewe/Test.csv"
) # 更改测试数据目录
Clean = False # 清理文本
清理函数在英文翻译中很有用,但在这种情况下,如果我们清理数据,结果会很差。所以,我们要把它关掉。
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))
基于语言将训练和测试数据划分为两个数据帧。
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设置模型参数。
参数:
训练/评估分离
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)
参数
我尝试了多个参数,得出了最好的结果。
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
初始化模型
model_fon = Seq2SeqModel(
encoder_decoder_type="marian",
encoder_decoder_name="Helsinki-NLP/opus-mt-en-mul",
args=model_args,
use_cuda=True,
)
评价指标
def count_matches(labels, preds):
print(labels)
print(preds)
return sum(
[
1 if label == pred else 0
for label, pred in zip(labels, preds)
]
)
训练模型
model_fon.train_model(
train_df, eval_data=eval_df, matches=count_matches
)
单一预测
模型运行准确。
# 预测
print(
model_fon.predict(
Fon_test["French"].values[25]
)
)
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 🤗 Transformers. Use the regular `__call__` method to prepare your inputs and the tokenizer under the `with_target_tokenizer` context manager to prepare your targets. See the documentation of your specific tokenizer for more details
FutureWarning,
['Dɔnkpá', 'ɖokpó sɔ́', 'élɔ́ mɛ̀', 'xojlawemajlakpà', 'kɔkɔ́kɔ́ɖɔ́', 'gɔn ɛ́', 'ɖagbe', 'yi atín', 'gbɔ̀n gbɔ̀n', 'ɖokpo', 'hălù', 'ɔ́, alo wŭ', 'asì - asɔ ɔ́', 'nyì lanmὲ', 'ɖù nù nùsáwŭ', 'nu e', 'Ffrika wá', 'é ɔ́, ɖò hŭn yì', 'wàn', 'ɖo ɛ̀', 'ɖĕbŭ', 'wè', 'é nyɔ́ nú mì', 'ɖe jijɔ']
Hosted on
预测丰贝语测试数据并保存
Fon_test["Target"] = model_fon.predict(list(Fon_test["French"].values))
Fon_test[["ID","Target"]].to_csv("Fon.csv",index=False)
保存模型
import torch
torch.save(model_fon , 'model_fon.pkl')
使用简单的转换器seq2seq,我下载了 Helsinki-NLP/opus-mt-en-mul ,它在我们的案例中工作得最好,并使用特定的Seq2SeqArg设置模型参数。
参数:
train_data = Ewe[["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.20, random_state=42)
模型参数
我尝试了多个参数,得出了最好的结果。
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 ="ewe"
model_args.overwrite_output_dir = True
初始化埃维语模型
model_ewe = Seq2SeqModel(
encoder_decoder_type="marian",
encoder_decoder_name="Helsinki-NLP/opus-mt-en-mul",
args=model_args,
use_cuda=True,
)
训练模式
model_ewe.train_model(
train_df, eval_data=eval_df, matches=count_matches
)
预测和保存
Ewe_test["Target"]=model_ewe.predict(list(Ewe_test["French"].values))
Ewe_test[["ID","Target"]].to_csv("Ewe.csv",index=False)
保存模型
torch.save(model_ewe , 'model_ewe.pkl')
将机器翻译和预测翻译结合起来
ewe = pd.read_csv('Ewe.csv')
fon = pd.read_csv('Fon.csv')
fr_to_targ_lang_sub = pd.concat([ewe, fon])
fr_to_targ_lang_sub.head()
ID | Target | |
---|---|---|
0 | ID_AAAAhgRX | eƒe vɔvɔ̃ hã |
1 | ID_AChdWHyF | nyigba gbɔgbɔ |
2 | ID_AHBSoUNL | ele abe esia ene… » » Basa |
3 | ID_AHycIkQv | xlẽa nu vɔ̃ sɔgbɔ |
4 | ID_AIWTdKBT | ɖeka be akpɔ akplasi kple adzreɖeɖeame ɖe ta, … |
创建提交文件
fr_to_targ_lang_sub.to_csv(
"submission.csv", index=False
)
结果
本次比赛的误差指标为Rouge评分,即Rouge-N(N-gram)评分和F分数。
机器翻译在NLP世界中被低估了,因为谷歌翻译和其他巨头使翻译变得完美,但他们并没有提供所有的语言,一些低资源语言甚至没有做到这一点。
这是一个有趣的旅程,因为我开始使用seq2seq模型时注意到了Transformer,然后偶然发现了 Helsinki NLP语言模型。我的内存和GPU有限,导致在处理海量数据时有很多限制,所以我也没有提高我的分数。
在花了一个月的时间后,我偶然发现了一些Simple Transformer,这些Transformer是为使微调变得简单和容易而设计的。
最后,我对这个结果感到高兴,同时使用有效和快速的方法来有效地训练和预测来自非洲的低资源语言。
代码可在GitHub(https://github.com/kingabzpro/French-to-Fongbe-and-Ewe-MT)和Deepnote(https://deepnote.com/publish/e019ab02-6596-4ab8-a99f-fb27d5d7445f)上获得。