Make biclasifier head a hyperparameter.

This commit is contained in:
Piotr Czapla
2018-12-09 00:39:27 +01:00
parent 591393b96c
commit 2338618563
3 changed files with 24 additions and 9 deletions
+7 -3
View File
@@ -30,18 +30,22 @@ def bilm_learner(data:DataBunch, bptt:int=70, emb_sz:int=400, nh:int=1150, nl:in
def bilm_text_classifier_learner(data: DataBunch, bptt: int = 70, max_len: int = 70 * 20, emb_sz: int = 400,
nh: int = 1150, nl: int = 3,
lin_ftrs: Collection[int] = None, ps: Collection[float] = None, pad_token: int = 1,
drop_mult: float = 1., qrnn: bool = False, **kwargs) -> 'TextClassifierLearner':
drop_mult: float = 1., qrnn: bool = False, bicls_head:str='BiPoolingLinearClassifier', **kwargs) -> 'TextClassifierLearner':
"Create a RNN classifier."
dps = default_dropout['classifier'] * drop_mult
if lin_ftrs is None: lin_ftrs = [50]
if ps is None: ps = [0.1]
ds = data.train_ds
vocab_size, n_class = len(data.vocab.itos), data.c
layers = [emb_sz * 3] + lin_ftrs + [n_class]
if bicls_head == 'BiPoolingLinearClassifier':
count = 3*2
else:
count = 3
layers = [emb_sz * count] + lin_ftrs + [n_class]
ps = [dps[4]] + ps
model = get_birnn_classifier(bptt, max_len, n_class, vocab_size, emb_sz, nh, nl, pad_token,
layers, ps, input_p=dps[0], weight_p=dps[1], embed_p=dps[2], hidden_p=dps[3],
qrnn=qrnn)
qrnn=qrnn, bicls_head=bicls_head)
learn = RNNLearner(data, model, bptt, split_func=birnn_classifier_split, **kwargs)
return learn
+6 -2
View File
@@ -138,14 +138,18 @@ def get_bilm(vocab_sz:int, emb_sz:int, n_hid:int, n_layers:int, pad_token:int, t
def get_birnn_classifier(bptt:int, max_seq:int, n_class:int, vocab_sz:int, emb_sz:int, n_hid:int, n_layers:int,
pad_token:int, layers:Collection[int], drops:Collection[float], bidir:bool=False, qrnn:bool=False,
hidden_p:float=0.2, input_p:float=0.6, embed_p:float=0.1, weight_p:float=0.5)->nn.Module:
hidden_p:float=0.2, input_p:float=0.6, embed_p:float=0.1, weight_p:float=0.5, bicls_head:str='BiPoolingLinearClassifier')->nn.Module:
"Create a RNN classifier model."
fwd_rnn_enc = MultiBatchRNNCore(bptt, max_seq, vocab_sz, emb_sz, n_hid, n_layers, pad_token=pad_token, bidir=bidir,
qrnn=qrnn, hidden_p=hidden_p, input_p=input_p, embed_p=embed_p, weight_p=weight_p)
bwd_rnn_enc = MultiBatchRNNCore(bptt, max_seq, vocab_sz, emb_sz, n_hid, n_layers, pad_token=pad_token, bidir=bidir,
qrnn=qrnn, hidden_p=hidden_p, input_p=input_p, embed_p=embed_p, weight_p=weight_p)
model = SequentialRNN(BiLMModel(fwd_rnn_enc, bwd_rnn_enc), BiPoolingLinearClassifier(layers, drops))
head = BiPoolingLinearClassifier
if bicls_head == 'BiPoolingLinearClassifier': head = BiPoolingLinearClassifier
elif bicls_head == 'AvgPoolingLinearClassifier': head = AvgPoolingLinearClassifier
model = SequentialRNN(BiLMModel(fwd_rnn_enc, bwd_rnn_enc), head(layers, drops))
model.reset()
return model
+11 -4
View File
@@ -44,6 +44,8 @@ class CLSHyperParams(LMHyperParams):
# dir_path -> data/imdb/
use_test_for_validation=False
bicls_head:str = 'BiPoolingLinearClassifier'
def __post_init__(self, *args, **kwargs):
super().__post_init__(*args, **kwargs)
self.dataset_dir=self.dataset_path
@@ -92,7 +94,10 @@ class CLSHyperParams(LMHyperParams):
fastai.text.learner.default_dropout['language'] = dps or self.dps
trn_args=dict(drop_mult=self.drop_mult, bptt=self.bptt, clip=self.clip,)
trn_args.update(kwargs)
classifier_learner = bilm_text_classifier_learner if self.bidir else text_classifier_learner
classifier_learner = text_classifier_learner
if self.bidir:
classifier_learner = bilm_text_classifier_learner
trn_args['bicls_head'] = self.bicls_head
learn = classifier_learner(data_clas, pad_token=PAD_TOKEN_ID,
path=self.model_dir.parent, model_dir=self.model_dir.name,
qrnn=self.qrnn, emb_sz=self.emb_sz, nh=self.nh, nl=self.nl, **trn_args)
@@ -116,7 +121,6 @@ class CLSHyperParams(LMHyperParams):
lm_val_df = lm_trn_df[:val_len]
if use_test_for_validation:
val_len = max(int(len(tst_df) * 0.1), 2)
val_df = tst_df
cls_cache = 'notst'
else:
@@ -126,8 +130,11 @@ class CLSHyperParams(LMHyperParams):
cls_cache = '.'
if self.tokenizer is Tokenizers.SUBWORD:
#TODO Fix me to make sure it trains correct dictionary
args = get_sentencepiece(self.dataset_path, self.dataset_path / 'train.csv', self.name, vocab_size=self.max_vocab)
args = get_sentencepiece(self.dataset_path, self.dataset_path / 'train.csv',
self.name, vocab_size=self.max_vocab, pre_rules=[], post_rules=[])
if self.tokenizer is Tokenizers.SUBWORD:
args = get_sentencepiece(self.dataset_path, self.dataset_path / 'train.csv',
self.name, vocab_size=self.max_vocab, pre_rules=[], post_rules=[])
elif self.tokenizer is Tokenizers.MOSES:
args = dict(tokenizer=Tokenizer(tok_func=MosesTokenizerFunc, lang='en', pre_rules=[], post_rules=[]))
elif self.tokenizer is Tokenizers.MOSES_FA: