240 lines
6.9 KiB
Python
240 lines
6.9 KiB
Python
# Copyright (c) 2017-present, Facebook, Inc.
|
|
# All rights reserved.
|
|
#
|
|
# This source code is licensed under the MIT license found in the
|
|
# LICENSE file in the root directory of this source tree.
|
|
|
|
from __future__ import absolute_import
|
|
from __future__ import division
|
|
from __future__ import print_function
|
|
from __future__ import unicode_literals
|
|
|
|
import multiprocessing
|
|
|
|
# This script represents a collection of integration tests
|
|
# Each integration test comes with a full set of parameters,
|
|
# a dataset, and expected metrics.
|
|
# These configurations can be used by various fastText APIs
|
|
# to confirm some level of correctness.
|
|
|
|
|
|
def max_thread():
|
|
return multiprocessing.cpu_count() - 1
|
|
|
|
|
|
def check_supervised_configuration(configuration, verbose=1):
|
|
configuration["args"]["verbose"] = verbose
|
|
configuration["quant_args"]["verbose"] = verbose
|
|
return configuration
|
|
|
|
|
|
def check_supervised_configurations(configurations, verbose=1):
|
|
for i in range(len(configurations)):
|
|
configurations[i] = check_supervised_configuration(
|
|
configurations[i], verbose=verbose
|
|
)
|
|
return configurations
|
|
|
|
|
|
def flickr_job(thread=None):
|
|
if thread is None:
|
|
thread = max_thread()
|
|
config = {}
|
|
config["dataset"] = "YFCC100M"
|
|
config["args"] = {
|
|
"dim": 256,
|
|
"wordNgrams": 2,
|
|
"minCount": 10,
|
|
"bucket": 10000000,
|
|
"epoch": 20,
|
|
"loss": "hs",
|
|
"minCountLabel": 100,
|
|
"thread": thread
|
|
}
|
|
config["args"]["input"] = "YFCC100M/train"
|
|
config["quant_args"] = {
|
|
"dsub": 2,
|
|
"lr": 0.1,
|
|
"epoch": 5,
|
|
"cutoff": 100000,
|
|
"qnorm": True,
|
|
"retrain": True,
|
|
"qout": True
|
|
}
|
|
config["quant_args"]["input"] = config["args"]["input"]
|
|
config["test"] = {
|
|
"n": 647224,
|
|
"p1": 0.470,
|
|
"r1": 0.071,
|
|
"size": 12060039727,
|
|
"data": "YFCC100M/test",
|
|
}
|
|
# One quant example (to illustrate slack): 0.344, 0.0528, 64506972
|
|
config["quant_test"] = {
|
|
"n": 647224,
|
|
"p1": 0.300,
|
|
"r1": 0.0450,
|
|
"size": 70000000,
|
|
"data": "YFCC100M/test",
|
|
}
|
|
return config
|
|
|
|
|
|
def langid_job1(thread=None):
|
|
if thread is None:
|
|
thread = max_thread()
|
|
config = {}
|
|
config["dataset"] = "langid"
|
|
config["args"] = {"dim": 16, "minn": 2, "maxn": 4, "thread": thread}
|
|
config["args"]["input"] = "langid.train"
|
|
config["quant_args"] = {"qnorm": True, "cutoff": 50000, "retrain": True}
|
|
config["quant_args"]["input"] = config["args"]["input"]
|
|
config["test"] = {
|
|
"n": 10000,
|
|
"p1": 0.985,
|
|
"r1": 0.985,
|
|
"size": 368132610,
|
|
"data": "langid.valid",
|
|
}
|
|
# One quant example (to illustrate slack): 0.984 0.984 932793
|
|
config["quant_test"] = {
|
|
"p1": 0.97,
|
|
"r1": 0.97,
|
|
"size": 1000000,
|
|
}
|
|
config["quant_test"]["n"] = config["test"]["n"]
|
|
config["quant_test"]["data"] = config["test"]["data"]
|
|
return config
|
|
|
|
|
|
def langid_job2(thread=None):
|
|
if thread is None:
|
|
thread = max_thread()
|
|
config = langid_job1(thread).copy()
|
|
config["args"]["loss"] = "hs"
|
|
return config
|
|
|
|
|
|
def cooking_job1(thread=None):
|
|
if thread is None:
|
|
thread = max_thread()
|
|
config = {}
|
|
config["dataset"] = "cooking"
|
|
config["args"] = {
|
|
"epoch": 25,
|
|
"lr": 1.0,
|
|
"wordNgrams": 2,
|
|
"minCount": 1,
|
|
"thread": thread,
|
|
}
|
|
config["args"]["input"] = "cooking.train"
|
|
config["quant_args"] = {"qnorm": True, "cutoff": 50000, "retrain": True}
|
|
config["quant_args"]["input"] = config["args"]["input"]
|
|
config["test"] = {
|
|
"n": 3000,
|
|
"p1": 0.59,
|
|
"r1": 0.25,
|
|
"size": 804047585,
|
|
"data": "cooking.valid",
|
|
}
|
|
# One quant example (to illustrate slack): 0.602 0.26 3439172
|
|
config["quant_test"] = {
|
|
"p1": 0.55,
|
|
"r1": 0.20,
|
|
"size": 4000000,
|
|
}
|
|
config["quant_test"]["n"] = config["test"]["n"]
|
|
config["quant_test"]["data"] = config["test"]["data"]
|
|
return config
|
|
|
|
|
|
def cooking_job2(thread=None):
|
|
if thread is None:
|
|
thread = max_thread()
|
|
config = cooking_job1(thread).copy()
|
|
config["args"]["loss"] = "hs"
|
|
return config
|
|
|
|
|
|
# Supervised models
|
|
# See https://fasttext.cc/docs/en/supervised-models.html
|
|
def get_supervised_models(thread=None, verbose=1):
|
|
if thread is None:
|
|
thread = max_thread()
|
|
sup_job_dataset = [
|
|
"ag_news", "sogou_news", "dbpedia", "yelp_review_polarity",
|
|
"yelp_review_full", "yahoo_answers", "amazon_review_full",
|
|
"amazon_review_polarity"
|
|
]
|
|
|
|
sup_params = {
|
|
"dim": 10,
|
|
"wordNgrams": 2,
|
|
"minCount": 1,
|
|
"bucket": 10000000,
|
|
"epoch": 5,
|
|
"thread": thread,
|
|
"verbose": 1,
|
|
}
|
|
quant_params = {
|
|
"retrain": True,
|
|
"cutoff": 100000,
|
|
"qnorm": True,
|
|
"verbose": 1,
|
|
}
|
|
sup_job_lr = [0.25, 0.5, 0.5, 0.1, 0.1, 0.1, 0.05, 0.05]
|
|
|
|
sup_job_n = [7600, 60000, 70000, 38000, 50000, 60000, 650000, 400000]
|
|
|
|
sup_job_p1 = [0.915, 0.968, 0.983, 0.956, 0.638, 0.723, 0.600, 0.940]
|
|
sup_job_r1 = [0.915, 0.968, 0.983, 0.956, 0.638, 0.723, 0.600, 0.940]
|
|
sup_job_size = [
|
|
405607193, 421445471, 447481878, 427867393, 431292576, 517549567,
|
|
483742593, 493604598
|
|
]
|
|
|
|
sup_job_quant_p1 = [0.918, 0.965, 0.983, 0.950, 0.625, 0.707, 0.58, 0.920]
|
|
sup_job_quant_r1 = [0.918, 0.965, 0.983, 0.950, 0.625, 0.707, 0.58, 0.920]
|
|
sup_job_quant_size = [
|
|
1600000, 1500000, 1700000, 1600000, 1600000, 1700000, 1600000, 1600000
|
|
]
|
|
|
|
configurations = []
|
|
for i in range(len(sup_job_dataset)):
|
|
configuration = {}
|
|
configuration["dataset"] = sup_job_dataset[i]
|
|
args = sup_params.copy()
|
|
quant_args = quant_params.copy()
|
|
args["lr"] = sup_job_lr[i]
|
|
args["input"] = sup_job_dataset[i] + ".train"
|
|
quant_args["lr"] = sup_job_lr[i]
|
|
quant_args["input"] = sup_job_dataset[i] + ".train"
|
|
configuration["args"] = args
|
|
configuration["quant_args"] = quant_args
|
|
test = {
|
|
"n": sup_job_n[i],
|
|
"p1": sup_job_p1[i],
|
|
"r1": sup_job_r1[i],
|
|
"size": sup_job_size[i],
|
|
"data": sup_job_dataset[i] + ".test",
|
|
}
|
|
quant_test = {
|
|
"n": sup_job_n[i],
|
|
"p1": sup_job_quant_p1[i],
|
|
"r1": sup_job_quant_r1[i],
|
|
"size": sup_job_quant_size[i],
|
|
"data": sup_job_dataset[i] + ".test",
|
|
}
|
|
configuration["test"] = test
|
|
configuration["quant_test"] = quant_test
|
|
configurations.append(configuration)
|
|
configurations.append(flickr_job())
|
|
configurations.append(langid_job1())
|
|
configurations.append(langid_job2())
|
|
configurations.append(cooking_job1())
|
|
configurations.append(cooking_job2())
|
|
configurations = check_supervised_configurations(
|
|
configurations, verbose=verbose
|
|
)
|
|
return configurations
|