Exemplo n.º 1
0
    def build_embedding(self, lang, embedding_codes: List[str]) -> None:

        self.tic = time.time()
        self.embedding_name: str = "-".join(embedding_codes)
        self.lang = lang

        embedding_types: List[TokenEmbeddings] = []

        for code in embedding_codes:

            code = code.lower()
            assert code in [
                "bpe",
                "bert",
                "flair",
                "ft",
                "char",
                "ohe",
                "elmo",
            ], f"{code} - Invalid embedding code"

            if code == "ohe":
                embedding_types.append(OneHotEmbeddings(corpus=self.corpus))
            elif code == "ft":
                embedding_types.append(WordEmbeddings(self.lang))
            elif code == "bpe":
                embedding_types.append(BytePairEmbeddings(self.lang))
            elif code == "bert":
                embedding_types.append(
                    TransformerWordEmbeddings(
                        model=self.huggingface_ref[self.lang],
                        pooling_operation="first",
                        layers="-1",
                        fine_tune=False,
                    )
                )
            elif code == "char":
                embedding_types.append(CharacterEmbeddings())
            elif code == "flair":
                embedding_types.append(FlairEmbeddings(f"{self.lang}-forward"))
                embedding_types.append(FlairEmbeddings(f"{self.lang}-backward"))
            elif code == "elmo":
                embedding_types.append(
                    ELMoEmbeddings(model="large", embedding_mode="all")
                )

        self.embedding: StackedEmbeddings = StackedEmbeddings(
            embeddings=embedding_types
        )

        self.tagger: SequenceTagger = SequenceTagger(
            hidden_size=256,
            embeddings=self.embedding,
            tag_dictionary=self.tag_dictionary,
            tag_type=self.tag_type,
            use_crf=True,
        )

        self.trainer: ModelTrainer = ModelTrainer(self.tagger, self.corpus)
Exemplo n.º 2
0
def train_sequence_labeling_model(data_folder, proposed_tags_vocabulary_size):
    # define columns
    columns = {0: 'text', 1: 'pos', 2: 'is_separator', 3: 'proposed_tags'}
    # init a corpus using column format, data folder and the names of the train and test files
    # 1. get the corpus
    corpus: Corpus = ColumnCorpus(data_folder, columns,
                                  train_file='train',
                                  test_file='test',
                                  dev_file=None)
    log.info(corpus)
    # 2. what tag do we want to predict
    tag_type = 'pos'
    # 3. make the tag dictionary from the corpus
    tag_dictionary = corpus.make_tag_dictionary(tag_type=tag_type)
    log.info(tag_dictionary)
    # 4. initialize embeddings
    local_model_path = use_scratch_dir_if_available('resources/polish_FastText_embeddings')
    embedding_types: List[TokenEmbeddings] = [
        FlairEmbeddings('pl-forward', chars_per_chunk=64),
        FlairEmbeddings('pl-backward', chars_per_chunk=64),
        OneHotEmbeddings(corpus=corpus, field='is_separator', embedding_length=3, min_freq=3),
        OneHotEmbeddings(corpus=corpus, field='proposed_tags',
                         embedding_length=math.ceil((proposed_tags_vocabulary_size + 1)**0.25),
                         min_freq=3),
        WordEmbeddings(local_model_path) if os.path.exists(local_model_path) else WordEmbeddings('pl')
    ]
    embeddings: StackedEmbeddings = StackedEmbeddings(embeddings=embedding_types)
    # 5. initialize sequence tagger
    tagger: SequenceTagger = SequenceTagger(hidden_size=256,
                                            embeddings=embeddings,
                                            tag_dictionary=tag_dictionary,
                                            tag_type=tag_type,
                                            use_crf=False,
                                            rnn_layers=2)
    # 6. initialize trainer
    trainer: ModelTrainer = ModelTrainer(tagger, corpus)
    # 7. start training
    trainer.train(use_scratch_dir_if_available('resources_pol_eval/taggers/example-pos/'),
                  learning_rate=0.1,
                  mini_batch_size=32,
                  embeddings_storage_mode='gpu',
                  max_epochs=sys.maxsize,
                  monitor_test=True)
    # 8. plot weight traces (optional)
    plotter = Plotter()
    plotter.plot_weights(use_scratch_dir_if_available('resources_pol_eval/taggers/example-pos/weights.txt'))
Exemplo n.º 3
0
def EmbeddingFactory(parameters, corpus):
    from flair.embeddings import FlairEmbeddings, StackedEmbeddings, \
        WordEmbeddings, OneHotEmbeddings, CharacterEmbeddings, TransformerWordEmbeddings

    stack = []
    for emb in parameters.embedding.split():
        if any((spec in emb) for spec in ("bert", "gpt", "xlnet")):
            stack.append(
                TransformerWordEmbeddings(model=pretrainedstr(
                    emb, parameters.language),
                                          fine_tune=parameters.tune_embedding))
        elif emb == "flair":
            stack += [
                FlairEmbeddings(f"{parameters.language}-forward",
                                fine_tune=parameters.tune_embedding),
                FlairEmbeddings(f"{parameters.language}-backward",
                                fine_tune=parameters.tune_embedding)
            ]
        elif emb == "pos":
            stack.append(
                OneHotEmbeddings(corpus,
                                 field="pos",
                                 embedding_length=parameters.pos_embedding_dim,
                                 min_freq=1))
        elif emb == "fasttext":
            stack.append(WordEmbeddings(parameters.language))
        elif emb == "word":
            stack.append(
                OneHotEmbeddings(
                    corpus,
                    field="text",
                    embedding_length=parameters.word_embedding_dim,
                    min_freq=parameters.word_minfreq))
        elif emb == "char":
            stack.append(
                CharacterEmbeddings(
                    char_embedding_dim=parameters.char_embedding_dim,
                    hidden_size_char=parameters.char_bilstm_dim))
        else:
            raise NotImplementedError()
    return StackedEmbeddings(stack)
Exemplo n.º 4
0
def train_sequence_labeling_model(data_folder, proposed_tags_vocabulary_size,
                                  skf_split_no):
    """
    Trains the sequence labeling model (by default model uses one RNN layer).
    Model is trained to predict part of speech tag and takes into account information about:
    - text (plain text made of tokens that together form a sentence),
    - occurrence of separator before token,
    - proposed tags for given token.
    It is trained with use of Stacked Embeddings used to combine different embeddings together. Words are embedded
    using a concatenation of two vector embeddings:
    - Flair Embeddings - contextual string embeddings that capture latent syntactic-semantic
      information that goes beyond standard word embeddings. Key differences are: (1) they are trained without any
      explicit notion of words and thus fundamentally model words as sequences of characters. And (2) they are
      contextualized by their surrounding text, meaning that the same word will have different embeddings depending on
      its contextual use.
      There are forward (that goes through the given on input plain text form left to right) and backward model (that
      goes through the given on input plain text form right to left) used for part of speech (pos) tag training.
    - One Hot Embeddings - embeddings that encode each word in a vocabulary as a one-hot vector, followed by an
      embedding layer. These embeddings thus do not encode any prior knowledge as do most other embeddings. They also
      differ in that they require to see a Corpus during instantiation, so they can build up a vocabulary consisting of
      the most common words seen in the corpus, plus an UNK token for all rare words.
      There are two One Hot Embeddings used in training:
      - first to embed information about occurrence of separator before token,
      - second to embed information about concatenated with a ';' proposed tags.
    Model and training logs are saved in resources/taggers/example-pos directory.
    This is the method where internal states of forward and backward Flair models are taken at the end of each token
    and, supplemented by information about occurrence of separator before token and proposed tags for given token used
    to train model for one of stratified 10 fold cross validation splits.

    :param data_folder: folder where files with column corpus split are stored. Those columns are used to initialize
    ColumnCorpus object
    :param proposed_tags_vocabulary_size: number of proposed tags
    :param skf_split_no: number that indicates one of stratified 10 fold cross validation splits (from range 1 to 10)
    used to train the model
    """
    # define columns
    columns = {0: 'text', 1: 'pos', 2: 'is_separator', 3: 'proposed_tags'}
    # init a corpus using column format, data folder and the names of the train and test files
    # 1. get the corpus
    corpus: Corpus = ColumnCorpus(data_folder,
                                  columns,
                                  train_file='train_' + str(skf_split_no),
                                  test_file='test_' + str(skf_split_no),
                                  dev_file=None)
    log.info(corpus)
    # 2. what tag do we want to predict
    tag_type = 'pos'
    # 3. make the tag dictionary from the corpus
    tag_dictionary = corpus.make_tag_dictionary(tag_type=tag_type)
    log.info(tag_dictionary)
    # 4. initialize embeddings
    embedding_types: List[TokenEmbeddings] = [
        FlairEmbeddings('pl-forward', chars_per_chunk=64),
        FlairEmbeddings('pl-backward', chars_per_chunk=64),
        OneHotEmbeddings(corpus=corpus,
                         field='is_separator',
                         embedding_length=3,
                         min_freq=3),
        OneHotEmbeddings(corpus=corpus,
                         field='proposed_tags',
                         embedding_length=math.ceil(
                             (proposed_tags_vocabulary_size + 1)**0.25),
                         min_freq=3)
    ]
    embeddings: StackedEmbeddings = StackedEmbeddings(
        embeddings=embedding_types)
    # 5. initialize sequence tagger
    tagger: SequenceTagger = SequenceTagger(hidden_size=256,
                                            embeddings=embeddings,
                                            tag_dictionary=tag_dictionary,
                                            tag_type=tag_type,
                                            use_crf=False,
                                            rnn_layers=1)
    # 6. initialize trainer
    trainer: ModelTrainer = ModelTrainer(tagger, corpus)
    # 7. start training
    trainer.train(
        use_scratch_dir_if_available('resources/taggers/example-pos/it-' +
                                     str(skf_split_no)),
        learning_rate=0.1,
        mini_batch_size=32,
        embeddings_storage_mode='gpu',
        max_epochs=sys.maxsize,
        monitor_test=True)
    # 8. plot weight traces (optional)
    plotter = Plotter()
    plotter.plot_weights(
        use_scratch_dir_if_available('resources/taggers/example-pos/it-' +
                                     str(skf_split_no) + '/weights.txt'))
Exemplo n.º 5
0
        return sum(p.numel() for p in model.parameters() if p.requires_grad)
    else:
        return sum(p.numel() for p in model.parameters()
                   if not p.requires_grad)


if args.pretrained_model is None:
    tag_dictionary = corpus.make_tag_dictionary(tag_type=tag_type)
    log.info(str(tag_dictionary.idx2item))

    embedding_types: List[TokenEmbeddings] = [
        get_embeddings(name) for name in args.embeddings
    ]
    if args.maca_tags:
        embedding_types.append(
            OneHotEmbeddings(corpus=corpus, field='tags', embedding_length=20))
    if args.space:
        embedding_types.append(
            OneHotEmbeddings(corpus=corpus,
                             field='space_before',
                             embedding_length=2))
    if args.maca_tags2:
        embedding_types.append(
            MoreHotEmbeddings(corpus=corpus, field='tags',
                              embedding_length=20))

    embeddings: StackedEmbeddings = StackedEmbeddings(
        embeddings=embedding_types)

    log.info(f'Embeddings size: {embeddings.embedding_length}')
    log.info(f'Embeddings size: {embeddings}')
Exemplo n.º 6
0
    def train(self, cuda_safe=True, positional=True, tags=False, seg=False):
        if cuda_safe:
            # Prevent CUDA Launch Failure random error, but slower:
            import torch
            torch.backends.cudnn.enabled = False
            # Or:
            # os.environ['CUDA_LAUNCH_BLOCKING'] = '1'

        # 1. get the corpus
        # this is the folder in which train, test and dev files reside
        data_folder = "tagger" + os.sep

        # init a corpus using column format, data folder and the names of the train, dev and test files

        # define columns
        columns = {0: "text", 1: "super", 2: "pos"}
        suff = ""
        if positional:
            columns[1] = "super"
            columns[2] = "pos"
        if tags:
            columns[3] = "morph"
            suff = "_morph"
        if seg:
            columns[1] = "seg"
            del columns[2]
            self.make_seg_data()
            suff = "_seg"
        else:
            self.make_pos_data(tags=tags)

        corpus: Corpus = ColumnCorpus(
            data_folder, columns,
            train_file=lang_prefix + "_train"+suff+".txt",
            test_file=lang_prefix + "_test"+suff+".txt",
            dev_file=lang_prefix + "_dev"+suff+".txt",
        )

        # 2. what tag do we want to predict?
        tag_type = 'pos' if not tags else "morph"
        if seg:
            tag_type = "seg"

        # 3. make the tag dictionary from the corpus
        tag_dictionary = corpus.make_tag_dictionary(tag_type=tag_type)
        print(tag_dictionary)

        # 4. initialize embeddings
        # Set language specific transformer embeddings here
        embeddings: TransformerWordEmbeddings = TransformerWordEmbeddings('onlplab/alephbert-base',)  # AlephBERT for Hebrew
        if positional:
            positions: OneHotEmbeddings = OneHotEmbeddings(corpus=corpus, field="super", embedding_length=5)
            if tags:
                tag_emb: OneHotEmbeddings = OneHotEmbeddings(corpus=corpus, field="pos", embedding_length=17)
                stacked: StackedEmbeddings = StackedEmbeddings([embeddings,positions,tag_emb])
            else:
                stacked: StackedEmbeddings = StackedEmbeddings([embeddings, positions])
        elif not seg:
            if tags:
                tag_emb: OneHotEmbeddings = OneHotEmbeddings(corpus=corpus, field="pos", embedding_length=17)
                stacked: StackedEmbeddings = StackedEmbeddings([embeddings,tag_emb])
            else:
                stacked = embeddings
        else:
            stacked = embeddings

        # 5. initialize sequence tagger
        tagger: SequenceTagger = SequenceTagger(hidden_size=256,
                                                embeddings=stacked,
                                                tag_dictionary=tag_dictionary,
                                                tag_type=tag_type,
                                                use_crf=True,
                                                use_rnn=True)

        # 6. initialize trainer
        from flair.trainers import ModelTrainer

        trainer: ModelTrainer = ModelTrainer(tagger, corpus)

        # 7. start training
        trainer.train(script_dir + "pos-dependencies" + os.sep + 'flair_tagger',
                      learning_rate=0.1,
                      mini_batch_size=15,
                      max_epochs=150)
Exemplo n.º 7
0
def train_sequence_labeling_model(data_folder, proposed_tags_vocabulary_size,
                                  skf_split_no):
    """
    Trains the sequence labeling model (by default model uses one RNN layer).
    Model is trained to predict part of speech tag and takes into account information about:
    - text (plain text made of tokens that together form a sentence),
    - occurrence of separator before token,
    - proposed tags for given token.
    It is trained with use of Stacked Embeddings used to combine different embeddings together. Words are embedded
    using a concatenation of three vector embeddings:
    - WordEmbeddings - classic word embeddings. That kind of embeddings are static and word-level, meaning that each
      distinct word gets exactly one pre-computed embedding. Here FastText embeddings trained over polish Wikipedia are
      used.
    - CharacterEmbeddings - allow to add character-level word embeddings during model training. These embeddings are
      randomly initialized when the class is being initialized, so they are not meaningful unless they are trained on
      a specific downstream task. For instance, the standard sequence labeling architecture used by Lample et al. (2016)
      is a combination of classic word embeddings with task-trained character features. Normally this would require to
      implement a hierarchical embedding architecture in which character-level embeddings for each word are computed
      using an RNN and then concatenated with word embeddings. In Flair, this is simplified by treating
      CharacterEmbeddings just like any other embedding class. To reproduce the Lample architecture, there is only
      a need to combine them with standard WordEmbeddings in an embedding stack.
    - One Hot Embeddings - embeddings that encode each word in a vocabulary as a one-hot vector, followed by an
      embedding layer. These embeddings thus do not encode any prior knowledge as do most other embeddings. They also
      differ in that they require to see a Corpus during instantiation, so they can build up a vocabulary consisting of
      the most common words seen in the corpus, plus an UNK token for all rare words.
      There are one One Hot Embeddings used in training: to embed information about proposed tags (concatenated
      with a ';') and appearance of separator before each token.
    Model training is based on stratified 10 fold cross validation split indicated by skf_split_no argument.
    Model and training logs are saved in resources_ex_3/taggers/example-pos/it-<skf_split_no> directory (where
    <skf_split_no> is the number of stratified 10 fold cross validation split used to train the model).

    :param data_folder: folder where files with column corpus split are stored. Those columns are used to initialize
    ColumnCorpus object
    :param proposed_tags_vocabulary_size: number of proposed tags
    :param skf_split_no: number that indicates one of stratified 10 fold cross validation splits (from range 1 to 10)
    used to train the model
    """
    # define columns
    columns = {0: 'text', 1: 'pos', 2: 'is_separator', 3: 'proposed_tags'}
    # init a corpus using column format, data folder and the names of the train and test files
    # 1. get the corpus
    corpus: Corpus = ColumnCorpus(data_folder,
                                  columns,
                                  train_file='train_' + str(skf_split_no),
                                  test_file='test_' + str(skf_split_no),
                                  dev_file=None)
    log.info(corpus)
    # 2. what tag do we want to predict
    tag_type = 'pos'
    # 3. make the tag dictionary from the corpus
    tag_dictionary = corpus.make_tag_dictionary(tag_type=tag_type)
    log.info(tag_dictionary)
    # 4. initialize embeddings
    local_model_path = use_scratch_dir_if_available(
        'resources/polish_FastText_embeddings')
    embedding_types: List[TokenEmbeddings] = [
        WordEmbeddings(local_model_path)
        if os.path.exists(local_model_path) else WordEmbeddings('pl'),
        CharacterEmbeddings(
            use_scratch_dir_if_available('resources/polish_letters_dict')),
        OneHotEmbeddings(corpus=corpus,
                         field='is_separator',
                         embedding_length=3,
                         min_freq=3),
        OneHotEmbeddings(corpus=corpus,
                         field='proposed_tags',
                         embedding_length=math.ceil(
                             (proposed_tags_vocabulary_size + 1)**0.25),
                         min_freq=3)
    ]
    embeddings: StackedEmbeddings = StackedEmbeddings(
        embeddings=embedding_types)
    # 5. initialize sequence tagger
    tagger: SequenceTagger = SequenceTagger(hidden_size=256,
                                            embeddings=embeddings,
                                            tag_dictionary=tag_dictionary,
                                            tag_type=tag_type,
                                            use_crf=False,
                                            rnn_layers=1)
    # 6. initialize trainer
    trainer: ModelTrainer = ModelTrainer(tagger, corpus)
    # 7. start training
    trainer.train(
        use_scratch_dir_if_available('resources_ex_3/taggers/example-pos/it-' +
                                     str(skf_split_no)),
        learning_rate=0.1,
        mini_batch_size=32,
        embeddings_storage_mode='gpu',
        max_epochs=sys.maxsize,
        monitor_test=True)
    # 8. plot weight traces (optional)
    plotter = Plotter()
    plotter.plot_weights(
        use_scratch_dir_if_available('resources_ex_3/taggers/example-pos/it-' +
                                     str(skf_split_no) + '/weights.txt'))
Exemplo n.º 8
0
# 3. make the tag dictionary from the corpus

if args.pretrained_model:
    tagger: SequenceTagger = sequence_tagger_class.load(args.pretrained_model)
else:
    tag_dictionary = corpus.make_tag_dictionary(tag_type=tag_type)
    print(tag_dictionary.idx2item)

    # initialize embeddings
    embedding_types: List[TokenEmbeddings] = [
        FlairEmbeddingsEnd('pl-forward', fine_tune=args.fine_tune_flair),
        FlairEmbeddingsEnd('pl-backward', fine_tune=args.fine_tune_flair),
    ]
    if args.tags:
        embedding_types.append(
            OneHotEmbeddings(corpus=cc, field='tags', embedding_length=20))
    if args.poss:
        embedding_types.append(
            OneHotEmbeddings(corpus=cc, field='poss', embedding_length=10))
    if args.space:
        embedding_types.append(
            OneHotEmbeddings(corpus=cc,
                             field='space_before',
                             embedding_length=2))
    if args.year:
        embedding_types.append(
            OneHotEmbeddings(corpus=cc, field='year', embedding_length=2))
    if args.ambig:
        embedding_types.append(
            OneHotEmbeddings(corpus=cc, field='ambiguous', embedding_length=2))
Exemplo n.º 9
0
    column_name_map,
    train_file="train.txt",
    dev_file="dev.txt",
    skip_header=False,
    delimiter='\t',  # tab-separated files
)

stats = corpus.obtain_statistics()
print(stats)

# create the label dictionary
label_dict = corpus.make_label_dictionary()
print(label_dict)

# make a list of word embeddings
embeddings = [OneHotEmbeddings(corpus=corpus)]

# initialize document embedding by passing list of word embeddings
# Can choose between many RNN types (GRU by default, to change use rnn_type parameter)
document_embeddings = DocumentRNNEmbeddings(embeddings,
                                            bidirectional=True,
                                            hidden_size=256)

# create the text classifier
classifier = TextClassifier(document_embeddings, label_dictionary=label_dict)

# initialize the text classifier trainer
trainer = ModelTrainer(classifier, corpus)

# start the training
trainer.train('resources/',