# Buggy code
def generate_text(
    self,
    prefix: str = "\n",
    number_of_characters: int = 1000,
    temperature: float = 1.0,
    break_on_suffix=None,
) -> Tuple[str, float]:
    if prefix == "":
        prefix = "\n"

    with torch.no_grad():
        characters = []

        idx2item = self.dictionary.idx2item

        # initial hidden state
        hidden = self.init_hidden(1)

        if len(prefix) > 1:
            char_tensors = []
            for character in prefix[:-1]:
                char_tensors.append(
                    torch.tensor(self.dictionary.get_idx_for_item(character))
                    .unsqueeze(0)
                    .unsqueeze(0)
                )

            input = torch.cat(char_tensors).to(flair.device)

            prediction, _, hidden = self.forward(input, hidden)

        input = (
            torch.tensor(self.dictionary.get_idx_for_item(prefix[-1]))
            .unsqueeze(0)
            .unsqueeze(0)
        )

        log_prob = 0.0

        for i in range(number_of_characters):
            input = input.to(flair.device)

            # get predicted weights
            prediction, _, hidden = self.forward(input, hidden)
            prediction = prediction.squeeze().detach()
            decoder_output = prediction

            # divide by temperature
            prediction = prediction.div(temperature)

            # to prevent overflow problem with small temperature values, substract largest value from all
            # this makes a vector in which the largest value is 0
            max = torch.max(prediction)
            prediction -= max

            # compute word weights with exponential function
            word_weights = prediction.exp().cpu()

            # try sampling multinomial distribution for next character
            try:
                word_idx = torch.multinomial(word_weights, 1)[0]
            except:
                word_idx = torch.tensor(0)

            # print(word_idx)
            prob = decoder_output[word_idx]
            log_prob += prob

            input = word_idx.detach().unsqueeze(0).unsqueeze(0)
            word = idx2item[word_idx].decode("UTF-8")
            characters.append(word)

            if break_on_suffix is not None:
                if "".join(characters).endswith(break_on_suffix):
                    break

        text = prefix + "".join(characters)

        log_prob = log_prob.item()
        log_prob /= len(characters)

        if not self.is_forward_lm:
            text = text[::-1]

        text = text.encode("utf-8")

        return text, log_prob


# Traceback (AttributeError)
2019-09-17 11:47:41,099 read text file with 4 lines
2019-09-17 11:47:41,107 read text file with 4 lines
2019-09-17 11:47:41,205 read text file with 78280 lines
2019-09-17 11:47:41,265 shuffled
2019-09-17 11:48:08,470 Sequence length is 100
2019-09-17 11:48:08,502 Split 1  - (11:48:08)
2019-09-17 11:48:13,678 | split   1 /  1 |   100/  359 batches | ms/batch 51.60 | loss  1.50 | ppl     4.48
2019-09-17 11:48:18,817 | split   1 /  1 |   200/  359 batches | ms/batch 51.39 | loss  1.30 | ppl     3.67
2019-09-17 11:48:23,978 | split   1 /  1 |   300/  359 batches | ms/batch 51.60 | loss  1.24 | ppl     3.44
2019-09-17 11:48:27,022 18 seconds for train split 1
Traceback (most recent call last):
File "main.py", line 192, in <module>
main()
File "main.py", line 188, in main
fine_tune()
File "main.py", line 180, in fine_tune
flair_stuff.fine_tune(corpus_dir, stored_dir, model_name=model_name)
File "/home/nolan/code/lang_model_builder/flair_stuff.py", line 314, in fine_tune
checkpoint=True)
File "/home/nolan/anaconda2/envs/py37/lib/python3.7/site-packages/flair/trainers/language_model_trainer.py", line 428, in train
val_loss = self.evaluate(val_data, mini_batch_size, sequence_length)
File "/home/nolan/anaconda2/envs/py37/lib/python3.7/site-packages/flair/trainers/language_model_trainer.py", line 511, in evaluate
return total_loss.item() / len(data_source)
AttributeError: 'int' object has no attribute 'item'

# Fixed code
def generate_text(
    self,
    prefix: str = "\n",
    number_of_characters: int = 1000,
    temperature: float = 1.0,
    break_on_suffix=None,
) -> Tuple[str, float]:
    if prefix == "":
        prefix = "\n"

    with torch.no_grad():
        characters = []

        idx2item = self.dictionary.idx2item

        # initial hidden state
        hidden = self.init_hidden(1)

        if len(prefix) > 1:
            char_tensors = []
            for character in prefix[:-1]:
                char_tensors.append(
                    torch.tensor(self.dictionary.get_idx_for_item(character))
                    .unsqueeze(0)
                    .unsqueeze(0)
                )

            input = torch.cat(char_tensors).to(flair.device)

            prediction, _, hidden = self.forward(input, hidden)

        input = (
            torch.tensor(self.dictionary.get_idx_for_item(prefix[-1]))
            .unsqueeze(0)
            .unsqueeze(0)
        )

        log_prob = 0.0

        for i in range(number_of_characters):
            input = input.to(flair.device)

            # get predicted weights
            prediction, _, hidden = self.forward(input, hidden)
            prediction = prediction.squeeze().detach()
            decoder_output = prediction

            # divide by temperature
            prediction = prediction.div(temperature)

            # to prevent overflow problem with small temperature values, substract largest value from all
            # this makes a vector in which the largest value is 0
            max = torch.max(prediction)
            prediction -= max

            # compute word weights with exponential function
            word_weights = prediction.exp().cpu()

            # try sampling multinomial distribution for next character
            try:
                word_idx = torch.multinomial(word_weights, 1)[0]
            except:
                word_idx = torch.tensor(0)

            # print(word_idx)
            prob = decoder_output[word_idx]
            log_prob += prob

            input = word_idx.detach().unsqueeze(0).unsqueeze(0)
            word = idx2item[word_idx].decode("UTF-8")
            characters.append(word)

            if break_on_suffix is not None:
                if "".join(characters).endswith(break_on_suffix):
                    break

        text = prefix + "".join(characters)

        log_prob = log_prob.item()
        log_prob /= len(characters)

        if not self.is_forward_lm:
            text = text[::-1]

        return text, log_prob