TV Script Generation

In this project, you'll generate your own Simpsons TV scripts using RNNs. You'll be using part of the Simpsons dataset of scripts from 27 seasons. The Neural Network you'll build will generate a new TV script for a scene at Moe's Tavern.

Get the Data

The data is already provided for you. You'll be using a subset of the original dataset. It consists of only the scenes in Moe's Tavern. This doesn't include other versions of the tavern, like "Moe's Cavern", "Flaming Moe's", "Uncle Moe's Family Feed-Bag", etc..


In [1]:
"""
DON'T MODIFY ANYTHING IN THIS CELL
"""
import helper

data_dir = './data/simpsons/moes_tavern_lines.txt'
text = helper.load_data(data_dir)
# Ignore notice, since we don't use it for analysing the data
text = text[81:]

Explore the Data

Play around with view_sentence_range to view different parts of the data.


In [2]:
view_sentence_range = (1000, 1050)

"""
DON'T MODIFY ANYTHING IN THIS CELL
"""
import numpy as np

print('Dataset Stats')
print('Roughly the number of unique words: {}'.format(len({word: None for word in text.split()})))
scenes = text.split('\n\n')
print('Number of scenes: {}'.format(len(scenes)))
sentence_count_scene = [scene.count('\n') for scene in scenes]
print('Average number of sentences in each scene: {}'.format(np.average(sentence_count_scene)))

sentences = [sentence for scene in scenes for sentence in scene.split('\n')]
print('Number of lines: {}'.format(len(sentences)))
word_count_sentence = [len(sentence.split()) for sentence in sentences]
print('Average number of words in each line: {}'.format(np.average(word_count_sentence)))

print()
print('The sentences {} to {}:'.format(*view_sentence_range))
print('\n'.join(text.split('\n')[view_sentence_range[0]:view_sentence_range[1]]))


Dataset Stats
Roughly the number of unique words: 11492
Number of scenes: 262
Average number of sentences in each scene: 15.248091603053435
Number of lines: 4257
Average number of words in each line: 11.50434578341555

The sentences 1000 to 1050:
Duffman: (PARTY VOICE) Are you ready to get Duffed?
Lenny_Leonard: Hey, it's Duffman! The guy in a costume that creates awareness of Duff!
Duffman: Duffman wants to party down with the man who sent in ten thousand Duff labels to bring me here today. I've got a bottomless mug of new "Duff Extra Cold" for... (READS CARD) BARNEY GUMBEL!
Cheerleaders: (CHEERS AND:) Chug! Chug! Chug! Chug!
Barney_Gumble: (STRAINING) I can't! I'm the designated driver!
Duffman: (PERFUNCTORY, BRUSQUE) Ehhh... That's swell. Duff wholeheartedly supports the designated driver program... Now, who wants to party?!
Moe_Szyslak: Face it, Homer, the car is gone. Barney ain't never comin' back.
Barney_Gumble: (SHAKY) All I remember about the last two months is giving a guest lecture at Villanova. (BEAT) Or maybe it was a streetcorner.
Homer_Simpson: (QUIET ANGER) So you lost my car, eh? Well, that's just grand. I ought to punch you in the nose, but I have to pick up my kids at school.


Moe_Szyslak: (COVERING) Uh, that's a parasol.
Homer_Simpson: Well, Moe, this is it. Today's the day I get my new air conditioner.
Moe_Szyslak: Congratulations. Who's the little chick?
Lisa_Simpson: I'm Lisa!
Homer_Simpson: (TO MOE, PROUDLY) She has a gift.
Lisa_Simpson: You have thirteen pickled eggs in this jar! (CUTE) And one cockroach!
Moe_Szyslak: (DISPLEASED CHUCKLE) Who are you, sweetheart, the health inspector?
Man_At_Bar: No, but I am.
Moe_Szyslak: Uh... here, have a margarita.


Homer_Simpson: But you can't leave! We're scammin' an old lady at my house and I need a place to hide out.
Moe_Szyslak: Ah, sorry Homer, I've been planning this vacation for years. I'm finally gonna see Easter Island.
Homer_Simpson: Oh, right. With the giant heads.
Moe_Szyslak: With the what now?
Lenny_Leonard: Hey, you seen Apu lately? He looks terrible.
Carl_Carlson: Yeah, rumor has it Marge threw him out.
Barney_Gumble: Aw, tough break. She's a beautiful lady.
Moe_Szyslak: You got that straight, Barn.
Barney_Gumble: (RAISING GLASSES) To Marge!
Homer_Simpson: Moe, what do you recommend for severe depression?
Moe_Szyslak: Booze, booze and more booze.
Lenny_Leonard: Ha! Nothin' like a depressant to chase the blues away.
Lenny_Leonard: Yeah, you got that... / Oh yeah. / Uh-huh.
Apu_Nahasapeemapetilon: Oof, Manjula and I have not seen each other in twenty years. Two people cannot fall in love sight-unseen.
Moe_Szyslak: Hey, hold on there! I'm countin' on that.
Apu_Nahasapeemapetilon: Well, just twenty-four hours of freedom left...
Homer_Simpson: (CHECKING WATCH, CHIPPER) Actually, it's more like twelve. No, I'm so stupid, seven. It's seven hours. You have seven hours. (SHOWING APU WATCH) See? Seven.
Apu_Nahasapeemapetilon: (SAD MOAN, THEN SINGING DIRGE-LIKE) "WELL, I'M HOT BLOODED / CHECK IT AND SEE / I'VE GOT A FEVER OF A HUNDRED AND THREE..."
Homer_Simpson: C'mon. You shouldn't be spending your last hours of bachelorhood in a dump like this.
Homer_Simpson: You should be livin' like there's no tomorrow. And I know just the place.
Homer_Simpson: Ahh. Is this the life, or what?
Jasper_Beardly: (REACHING FOR A SWITCH) You want me to turn on the bubbles?


Moe_Szyslak: Geez, this hot-rod is souped up six ways from Sunday. Never had you figured for a gear-head, Homer.
Homer_Simpson: (CASUAL) Oh, yeah. I'm a real expert.
Moe_Szyslak: What is that? A six-barrel Hollye carb?
Homer_Simpson: You betcha.

Implement Preprocessing Functions

The first thing to do to any dataset is preprocessing. Implement the following preprocessing functions below:

  • Lookup Table
  • Tokenize Punctuation

Lookup Table

To create a word embedding, you first need to transform the words to ids. In this function, create two dictionaries:

  • Dictionary to go from the words to an id, we'll call vocab_to_int
  • Dictionary to go from the id to word, we'll call int_to_vocab

Return these dictionaries in the following tuple (vocab_to_int, int_to_vocab)


In [3]:
import numpy as np
import problem_unittests as tests

def create_lookup_tables(text):
    """
    Create lookup tables for vocabulary
    :param text: The text of tv scripts split into words
    :return: A tuple of dicts (vocab_to_int, int_to_vocab)
    """
    # TODO: Implement Function
    vocab_to_int = {word: i for i, word in enumerate(set(text))}
    int_to_vocab = dict(enumerate(vocab_to_int))
    return vocab_to_int, int_to_vocab


"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
tests.test_create_lookup_tables(create_lookup_tables)


Tests Passed

Tokenize Punctuation

We'll be splitting the script into a word array using spaces as delimiters. However, punctuations like periods and exclamation marks make it hard for the neural network to distinguish between the word "bye" and "bye!".

Implement the function token_lookup to return a dict that will be used to tokenize symbols like "!" into "||Exclamation_Mark||". Create a dictionary for the following symbols where the symbol is the key and value is the token:

  • Period ( . )
  • Comma ( , )
  • Quotation Mark ( " )
  • Semicolon ( ; )
  • Exclamation mark ( ! )
  • Question mark ( ? )
  • Left Parentheses ( ( )
  • Right Parentheses ( ) )
  • Dash ( -- )
  • Return ( \n )

This dictionary will be used to token the symbols and add the delimiter (space) around it. This separates the symbols as it's own word, making it easier for the neural network to predict on the next word. Make sure you don't use a token that could be confused as a word. Instead of using the token "dash", try using something like "||dash||".


In [4]:
def token_lookup():
    """
    Generate a dict to turn punctuation into a token.
    :return: Tokenize dictionary where the key is the punctuation and the value is the token
    """
    # TODO: Implement Function
    punctuation = {
        '.': '||period||',
        ',': '||comma||',
        '"': '||quotation_mark||',
        ';': '||semicolon||',
        '!': '||exclamation_point||',
        '?': '||question_mark||',
        '(': '||left_parenthesis||',
        ')': '||right_parenthesis||',
        '--': '||emdash||',
        "\n": '||line_break||'
    }
    return punctuation

"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
tests.test_tokenize(token_lookup)


Tests Passed

Preprocess all the data and save it

Running the code cell below will preprocess all the data and save it to file.


In [5]:
"""
DON'T MODIFY ANYTHING IN THIS CELL
"""
# Preprocess Training, Validation, and Testing Data
helper.preprocess_and_save_data(data_dir, token_lookup, create_lookup_tables)

Check Point

This is your first checkpoint. If you ever decide to come back to this notebook or have to restart the notebook, you can start from here. The preprocessed data has been saved to disk.


In [6]:
"""
DON'T MODIFY ANYTHING IN THIS CELL
"""
import helper
import numpy as np
import problem_unittests as tests

int_text, vocab_to_int, int_to_vocab, token_dict = helper.load_preprocess()

Build the Neural Network

You'll build the components necessary to build a RNN by implementing the following functions below:

  • get_inputs
  • get_init_cell
  • get_embed
  • build_rnn
  • build_nn
  • get_batches

Check the Version of TensorFlow and Access to GPU


In [7]:
"""
DON'T MODIFY ANYTHING IN THIS CELL
"""
from distutils.version import LooseVersion
import warnings
import tensorflow as tf

# Check TensorFlow Version
assert LooseVersion(tf.__version__) >= LooseVersion('1.0'), 'Please use TensorFlow version 1.0 or newer'
print('TensorFlow Version: {}'.format(tf.__version__))

# Check for a GPU
if not tf.test.gpu_device_name():
    warnings.warn('No GPU found. Please use a GPU to train your neural network.')
else:
    print('Default GPU Device: {}'.format(tf.test.gpu_device_name()))


TensorFlow Version: 1.0.0
Default GPU Device: /gpu:0

Input

Implement the get_inputs() function to create TF Placeholders for the Neural Network. It should create the following placeholders:

  • Input text placeholder named "input" using the TF Placeholder name parameter.
  • Targets placeholder
  • Learning Rate placeholder

Return the placeholders in the following the tuple (Input, Targets, LearingRate)


In [8]:
def get_inputs():
    """
    Create TF Placeholders for input, targets, and learning rate.
    :return: Tuple (input, targets, learning rate)
    """
    # TODO: Implement Function
    inputs = tf.placeholder(tf.int32, shape=(None, None), name="input")
    targets = tf.placeholder(tf.int32, shape=(None, None), name="targets")
    learning_rate = tf.placeholder(tf.float32, name="learning_rate")
    return inputs, targets, learning_rate


"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
tests.test_get_inputs(get_inputs)


Tests Passed

Build RNN Cell and Initialize

Stack one or more BasicLSTMCells in a MultiRNNCell.

  • The Rnn size should be set using rnn_size
  • Initalize Cell State using the MultiRNNCell's zero_state() function
    • Apply the name "initial_state" to the initial state using tf.identity()

Return the cell and initial state in the following tuple (Cell, InitialState)


In [9]:
def get_init_cell(batch_size, rnn_size):
    """
    Create an RNN Cell and initialize it.
    :param batch_size: Size of batches
    :param rnn_size: Size of RNNs
    :return: Tuple (cell, initialize state)
    """
    # TODO: Implement Function
    layer_count = 3
    
    lstm = tf.contrib.rnn.BasicLSTMCell(rnn_size)
    stacked_lstm = tf.contrib.rnn.MultiRNNCell([lstm] * layer_count)
    initial_state = stacked_lstm.zero_state(batch_size, tf.float32)
    initial_state = tf.identity(initial_state, name="initial_state")
    
    return stacked_lstm, initial_state


"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
tests.test_get_init_cell(get_init_cell)


Tests Passed

Word Embedding

Apply embedding to input_data using TensorFlow. Return the embedded sequence.


In [10]:
def get_embed(input_data, vocab_size, embed_dim):
    """
    Create embedding for <input_data>.
    :param input_data: TF placeholder for text input.
    :param vocab_size: Number of words in vocabulary.
    :param embed_dim: Number of embedding dimensions
    :return: Embedded input.
    """
    # TODO: Implement Function
    embedding = tf.Variable(tf.truncated_normal([vocab_size, embed_dim], -1.0, 1.0))
    embed = tf.nn.embedding_lookup(embedding, input_data)
    return embed


"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
tests.test_get_embed(get_embed)


Tests Passed

Build RNN

You created a RNN Cell in the get_init_cell() function. Time to use the cell to create a RNN.

Return the outputs and final_state state in the following tuple (Outputs, FinalState)


In [11]:
def build_rnn(cell, inputs):
    """
    Create a RNN using a RNN Cell
    :param cell: RNN Cell
    :param inputs: Input text data
    :return: Tuple (Outputs, Final State)
    """
    # TODO: Implement Function
    outputs, state = tf.nn.dynamic_rnn(cell, inputs, dtype=tf.float32)
    state = tf.identity(state, name="final_state")
    return outputs, state


"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
tests.test_build_rnn(build_rnn)


Tests Passed

Build the Neural Network

Apply the functions you implemented above to:

  • Apply embedding to input_data using your get_embed(input_data, vocab_size, embed_dim) function.
  • Build RNN using cell and your build_rnn(cell, inputs) function.
  • Apply a fully connected layer with a linear activation and vocab_size as the number of outputs.

Return the logits and final state in the following tuple (Logits, FinalState)


In [12]:
def build_nn(cell, rnn_size, input_data, vocab_size):
    """
    Build part of the neural network
    :param cell: RNN cell
    :param rnn_size: Size of rnns
    :param input_data: Input data
    :param vocab_size: Vocabulary size
    :return: Tuple (Logits, FinalState)
    """
    # TODO: Implement Function
    embedding = get_embed(input_data, vocab_size, rnn_size)
    outputs, state = build_rnn(cell, embedding)
    
    logits = tf.layers.dense(inputs=outputs, units=vocab_size)
    
    return logits, state


"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
tests.test_build_nn(build_nn)


Tests Passed

Batches

Implement get_batches to create batches of input and targets using int_text. The batches should be a Numpy array with the shape (number of batches, 2, batch size, sequence length). Each batch contains two elements:

  • The first element is a single batch of input with the shape [batch size, sequence length]
  • The second element is a single batch of targets with the shape [batch size, sequence length]

If you can't fill the last batch with enough data, drop the last batch.

For exmple, get_batches([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], 2, 3) would return a Numpy array of the following:

[
  # First Batch
  [
    # Batch of Input
    [[ 1  2  3], [ 7  8  9]],
    # Batch of targets
    [[ 2  3  4], [ 8  9 10]]
  ],

  # Second Batch
  [
    # Batch of Input
    [[ 4  5  6], [10 11 12]],
    # Batch of targets
    [[ 5  6  7], [11 12 13]]
  ]
]

In [13]:
def get_batches(int_text, batch_size, seq_length):
    """
    Return batches of input and target
    :param int_text: Text with the words replaced by their ids
    :param batch_size: The size of batch
    :param seq_length: The length of sequence
    :return: Batches as a Numpy array
    """
    # TODO: Implement Function
    number_of_batches = len(int_text) // (batch_size * seq_length)
    if len(int_text) % number_of_batches <= 1: #if we don't have at least one extra element to predict
        number_of_batches -= 1
   
    batches = np.empty(shape=(number_of_batches, 2, batch_size, seq_length))

    for batch_number in range(number_of_batches):
        base_index = batch_number * seq_length
        inputs = np.array([])
        targets = np.array([])
        for sequence_number in range(batch_size):
            start_index = base_index + (sequence_number * seq_length)
            end_index = start_index + seq_length
            sequence = int_text[start_index:end_index]
            target = int_text[(start_index + 1):(end_index + 1)]
            
            batches[batch_number, 0, sequence_number] = sequence
            batches[batch_number, 1, sequence_number] = target
    
    return batches


"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
tests.test_get_batches(get_batches)


Tests Passed

Neural Network Training

Hyperparameters

Tune the following parameters:

  • Set num_epochs to the number of epochs.
  • Set batch_size to the batch size.
  • Set rnn_size to the size of the RNNs.
  • Set seq_length to the length of sequence.
  • Set learning_rate to the learning rate.
  • Set show_every_n_batches to the number of batches the neural network should print progress.

In [14]:
# Number of Epochs
num_epochs = 8192
# Sequence Length
seq_length = 32
# Batch Size
batch_size = int(len(int_text) / seq_length // 2) #maximize the batch size to not waste data
# RNN Size
rnn_size = 128
# Learning Rate
learning_rate = 0.001
# Show stats for every n number of batches
show_every_n_batches = 20

"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
save_dir = './save'

Build the Graph

Build the graph using the neural network you implemented.


In [15]:
"""
DON'T MODIFY ANYTHING IN THIS CELL
"""
from tensorflow.contrib import seq2seq

train_graph = tf.Graph()
with train_graph.as_default():
    vocab_size = len(int_to_vocab)
    input_text, targets, lr = get_inputs()
    input_data_shape = tf.shape(input_text)
    cell, initial_state = get_init_cell(input_data_shape[0], rnn_size)
    logits, final_state = build_nn(cell, rnn_size, input_text, vocab_size)

    # Probabilities for generating words
    probs = tf.nn.softmax(logits, name='probs')

    # Loss function
    cost = seq2seq.sequence_loss(
        logits,
        targets,
        tf.ones([input_data_shape[0], input_data_shape[1]]))

    # Optimizer
    optimizer = tf.train.AdamOptimizer(lr)

    # Gradient Clipping
    gradients = optimizer.compute_gradients(cost)
    capped_gradients = [(tf.clip_by_value(grad, -1., 1.), var) for grad, var in gradients]
    train_op = optimizer.apply_gradients(capped_gradients)

Train

Train the neural network on the preprocessed data. If you have a hard time getting a good loss, check the forms to see if anyone is having the same problem.


In [16]:
"""
DON'T MODIFY ANYTHING IN THIS CELL
"""
batches = get_batches(int_text, batch_size, seq_length)

with tf.Session(graph=train_graph) as sess:
    sess.run(tf.global_variables_initializer())

    for epoch_i in range(num_epochs):
        state = sess.run(initial_state, {input_text: batches[0][0]})

        for batch_i, (x, y) in enumerate(batches):
            feed = {
                input_text: x,
                targets: y,
                initial_state: state,
                lr: learning_rate}
            train_loss, state, _ = sess.run([cost, final_state, train_op], feed)

            # Show every <show_every_n_batches> batches
            if (epoch_i * len(batches) + batch_i) % show_every_n_batches == 0:
                print('Epoch {:>3} Batch {:>4}/{}   train_loss = {:.3f}'.format(
                    epoch_i,
                    batch_i,
                    len(batches),
                    train_loss))

    # Save Model
    saver = tf.train.Saver()
    saver.save(sess, save_dir)
    print('Model Trained and Saved')


Epoch   0 Batch    0/1   train_loss = 8.824
Epoch  20 Batch    0/1   train_loss = 6.430
Epoch  40 Batch    0/1   train_loss = 5.841
Epoch  60 Batch    0/1   train_loss = 5.794
Epoch  80 Batch    0/1   train_loss = 5.786
Epoch 100 Batch    0/1   train_loss = 5.783
Epoch 120 Batch    0/1   train_loss = 5.781
Epoch 140 Batch    0/1   train_loss = 5.780
Epoch 160 Batch    0/1   train_loss = 5.779
Epoch 180 Batch    0/1   train_loss = 5.779
Epoch 200 Batch    0/1   train_loss = 5.778
Epoch 220 Batch    0/1   train_loss = 5.777
Epoch 240 Batch    0/1   train_loss = 5.776
Epoch 260 Batch    0/1   train_loss = 5.773
Epoch 280 Batch    0/1   train_loss = 5.772
Epoch 300 Batch    0/1   train_loss = 5.765
Epoch 320 Batch    0/1   train_loss = 5.760
Epoch 340 Batch    0/1   train_loss = 5.757
Epoch 360 Batch    0/1   train_loss = 5.753
Epoch 380 Batch    0/1   train_loss = 5.750
Epoch 400 Batch    0/1   train_loss = 5.752
Epoch 420 Batch    0/1   train_loss = 5.743
Epoch 440 Batch    0/1   train_loss = 5.740
Epoch 460 Batch    0/1   train_loss = 5.736
Epoch 480 Batch    0/1   train_loss = 5.732
Epoch 500 Batch    0/1   train_loss = 5.730
Epoch 520 Batch    0/1   train_loss = 5.724
Epoch 540 Batch    0/1   train_loss = 5.719
Epoch 560 Batch    0/1   train_loss = 5.715
Epoch 580 Batch    0/1   train_loss = 5.708
Epoch 600 Batch    0/1   train_loss = 5.703
Epoch 620 Batch    0/1   train_loss = 5.702
Epoch 640 Batch    0/1   train_loss = 5.695
Epoch 660 Batch    0/1   train_loss = 5.699
Epoch 680 Batch    0/1   train_loss = 5.689
Epoch 700 Batch    0/1   train_loss = 5.688
Epoch 720 Batch    0/1   train_loss = 5.685
Epoch 740 Batch    0/1   train_loss = 5.678
Epoch 760 Batch    0/1   train_loss = 5.676
Epoch 780 Batch    0/1   train_loss = 5.669
Epoch 800 Batch    0/1   train_loss = 5.666
Epoch 820 Batch    0/1   train_loss = 5.661
Epoch 840 Batch    0/1   train_loss = 5.671
Epoch 860 Batch    0/1   train_loss = 5.658
Epoch 880 Batch    0/1   train_loss = 5.653
Epoch 900 Batch    0/1   train_loss = 5.653
Epoch 920 Batch    0/1   train_loss = 5.648
Epoch 940 Batch    0/1   train_loss = 5.645
Epoch 960 Batch    0/1   train_loss = 5.643
Epoch 980 Batch    0/1   train_loss = 5.639
Epoch 1000 Batch    0/1   train_loss = 5.637
Epoch 1020 Batch    0/1   train_loss = 5.635
Epoch 1040 Batch    0/1   train_loss = 5.635
Epoch 1060 Batch    0/1   train_loss = 5.630
Epoch 1080 Batch    0/1   train_loss = 5.629
Epoch 1100 Batch    0/1   train_loss = 5.627
Epoch 1120 Batch    0/1   train_loss = 5.623
Epoch 1140 Batch    0/1   train_loss = 5.619
Epoch 1160 Batch    0/1   train_loss = 5.617
Epoch 1180 Batch    0/1   train_loss = 5.615
Epoch 1200 Batch    0/1   train_loss = 5.615
Epoch 1220 Batch    0/1   train_loss = 5.610
Epoch 1240 Batch    0/1   train_loss = 5.607
Epoch 1260 Batch    0/1   train_loss = 5.605
Epoch 1280 Batch    0/1   train_loss = 5.603
Epoch 1300 Batch    0/1   train_loss = 5.594
Epoch 1320 Batch    0/1   train_loss = 5.579
Epoch 1340 Batch    0/1   train_loss = 5.582
Epoch 1360 Batch    0/1   train_loss = 5.527
Epoch 1380 Batch    0/1   train_loss = 5.495
Epoch 1400 Batch    0/1   train_loss = 5.464
Epoch 1420 Batch    0/1   train_loss = 5.436
Epoch 1440 Batch    0/1   train_loss = 5.405
Epoch 1460 Batch    0/1   train_loss = 5.378
Epoch 1480 Batch    0/1   train_loss = 5.345
Epoch 1500 Batch    0/1   train_loss = 5.310
Epoch 1520 Batch    0/1   train_loss = 5.274
Epoch 1540 Batch    0/1   train_loss = 5.234
Epoch 1560 Batch    0/1   train_loss = 5.174
Epoch 1580 Batch    0/1   train_loss = 5.106
Epoch 1600 Batch    0/1   train_loss = 5.079
Epoch 1620 Batch    0/1   train_loss = 4.953
Epoch 1640 Batch    0/1   train_loss = 4.866
Epoch 1660 Batch    0/1   train_loss = 4.778
Epoch 1680 Batch    0/1   train_loss = 4.699
Epoch 1700 Batch    0/1   train_loss = 4.621
Epoch 1720 Batch    0/1   train_loss = 4.545
Epoch 1740 Batch    0/1   train_loss = 4.469
Epoch 1760 Batch    0/1   train_loss = 4.394
Epoch 1780 Batch    0/1   train_loss = 4.334
Epoch 1800 Batch    0/1   train_loss = 4.264
Epoch 1820 Batch    0/1   train_loss = 4.200
Epoch 1840 Batch    0/1   train_loss = 4.128
Epoch 1860 Batch    0/1   train_loss = 4.051
Epoch 1880 Batch    0/1   train_loss = 3.996
Epoch 1900 Batch    0/1   train_loss = 3.935
Epoch 1920 Batch    0/1   train_loss = 3.890
Epoch 1940 Batch    0/1   train_loss = 3.818
Epoch 1960 Batch    0/1   train_loss = 3.759
Epoch 1980 Batch    0/1   train_loss = 3.720
Epoch 2000 Batch    0/1   train_loss = 3.654
Epoch 2020 Batch    0/1   train_loss = 3.610
Epoch 2040 Batch    0/1   train_loss = 3.585
Epoch 2060 Batch    0/1   train_loss = 3.506
Epoch 2080 Batch    0/1   train_loss = 3.447
Epoch 2100 Batch    0/1   train_loss = 3.392
Epoch 2120 Batch    0/1   train_loss = 3.358
Epoch 2140 Batch    0/1   train_loss = 3.310
Epoch 2160 Batch    0/1   train_loss = 3.257
Epoch 2180 Batch    0/1   train_loss = 3.202
Epoch 2200 Batch    0/1   train_loss = 3.143
Epoch 2220 Batch    0/1   train_loss = 3.137
Epoch 2240 Batch    0/1   train_loss = 3.039
Epoch 2260 Batch    0/1   train_loss = 2.994
Epoch 2280 Batch    0/1   train_loss = 2.942
Epoch 2300 Batch    0/1   train_loss = 2.911
Epoch 2320 Batch    0/1   train_loss = 2.856
Epoch 2340 Batch    0/1   train_loss = 2.830
Epoch 2360 Batch    0/1   train_loss = 2.781
Epoch 2380 Batch    0/1   train_loss = 2.712
Epoch 2400 Batch    0/1   train_loss = 2.664
Epoch 2420 Batch    0/1   train_loss = 2.640
Epoch 2440 Batch    0/1   train_loss = 2.582
Epoch 2460 Batch    0/1   train_loss = 2.529
Epoch 2480 Batch    0/1   train_loss = 2.490
Epoch 2500 Batch    0/1   train_loss = 2.472
Epoch 2520 Batch    0/1   train_loss = 2.409
Epoch 2540 Batch    0/1   train_loss = 2.374
Epoch 2560 Batch    0/1   train_loss = 2.329
Epoch 2580 Batch    0/1   train_loss = 2.293
Epoch 2600 Batch    0/1   train_loss = 2.289
Epoch 2620 Batch    0/1   train_loss = 2.206
Epoch 2640 Batch    0/1   train_loss = 2.182
Epoch 2660 Batch    0/1   train_loss = 2.175
Epoch 2680 Batch    0/1   train_loss = 2.097
Epoch 2700 Batch    0/1   train_loss = 2.073
Epoch 2720 Batch    0/1   train_loss = 2.059
Epoch 2740 Batch    0/1   train_loss = 2.001
Epoch 2760 Batch    0/1   train_loss = 1.967
Epoch 2780 Batch    0/1   train_loss = 2.006
Epoch 2800 Batch    0/1   train_loss = 1.908
Epoch 2820 Batch    0/1   train_loss = 1.915
Epoch 2840 Batch    0/1   train_loss = 1.848
Epoch 2860 Batch    0/1   train_loss = 1.817
Epoch 2880 Batch    0/1   train_loss = 1.789
Epoch 2900 Batch    0/1   train_loss = 1.758
Epoch 2920 Batch    0/1   train_loss = 1.764
Epoch 2940 Batch    0/1   train_loss = 1.756
Epoch 2960 Batch    0/1   train_loss = 1.680
Epoch 2980 Batch    0/1   train_loss = 1.666
Epoch 3000 Batch    0/1   train_loss = 1.639
Epoch 3020 Batch    0/1   train_loss = 1.620
Epoch 3040 Batch    0/1   train_loss = 1.648
Epoch 3060 Batch    0/1   train_loss = 1.576
Epoch 3080 Batch    0/1   train_loss = 1.539
Epoch 3100 Batch    0/1   train_loss = 1.524
Epoch 3120 Batch    0/1   train_loss = 1.543
Epoch 3140 Batch    0/1   train_loss = 1.467
Epoch 3160 Batch    0/1   train_loss = 1.448
Epoch 3180 Batch    0/1   train_loss = 1.470
Epoch 3200 Batch    0/1   train_loss = 1.401
Epoch 3220 Batch    0/1   train_loss = 1.417
Epoch 3240 Batch    0/1   train_loss = 1.421
Epoch 3260 Batch    0/1   train_loss = 1.340
Epoch 3280 Batch    0/1   train_loss = 1.324
Epoch 3300 Batch    0/1   train_loss = 1.394
Epoch 3320 Batch    0/1   train_loss = 1.284
Epoch 3340 Batch    0/1   train_loss = 1.279
Epoch 3360 Batch    0/1   train_loss = 1.322
Epoch 3380 Batch    0/1   train_loss = 1.238
Epoch 3400 Batch    0/1   train_loss = 1.215
Epoch 3420 Batch    0/1   train_loss = 1.211
Epoch 3440 Batch    0/1   train_loss = 1.272
Epoch 3460 Batch    0/1   train_loss = 1.165
Epoch 3480 Batch    0/1   train_loss = 1.164
Epoch 3500 Batch    0/1   train_loss = 1.141
Epoch 3520 Batch    0/1   train_loss = 1.122
Epoch 3540 Batch    0/1   train_loss = 1.136
Epoch 3560 Batch    0/1   train_loss = 1.093
Epoch 3580 Batch    0/1   train_loss = 1.102
Epoch 3600 Batch    0/1   train_loss = 1.057
Epoch 3620 Batch    0/1   train_loss = 1.065
Epoch 3640 Batch    0/1   train_loss = 1.016
Epoch 3660 Batch    0/1   train_loss = 1.026
Epoch 3680 Batch    0/1   train_loss = 0.989
Epoch 3700 Batch    0/1   train_loss = 0.986
Epoch 3720 Batch    0/1   train_loss = 0.962
Epoch 3740 Batch    0/1   train_loss = 0.993
Epoch 3760 Batch    0/1   train_loss = 0.938
Epoch 3780 Batch    0/1   train_loss = 0.943
Epoch 3800 Batch    0/1   train_loss = 0.944
Epoch 3820 Batch    0/1   train_loss = 0.894
Epoch 3840 Batch    0/1   train_loss = 0.926
Epoch 3860 Batch    0/1   train_loss = 0.874
Epoch 3880 Batch    0/1   train_loss = 0.866
Epoch 3900 Batch    0/1   train_loss = 0.914
Epoch 3920 Batch    0/1   train_loss = 0.869
Epoch 3940 Batch    0/1   train_loss = 0.832
Epoch 3960 Batch    0/1   train_loss = 0.835
Epoch 3980 Batch    0/1   train_loss = 0.834
Epoch 4000 Batch    0/1   train_loss = 0.793
Epoch 4020 Batch    0/1   train_loss = 0.814
Epoch 4040 Batch    0/1   train_loss = 0.770
Epoch 4060 Batch    0/1   train_loss = 0.794
Epoch 4080 Batch    0/1   train_loss = 0.780
Epoch 4100 Batch    0/1   train_loss = 0.744
Epoch 4120 Batch    0/1   train_loss = 0.729
Epoch 4140 Batch    0/1   train_loss = 0.747
Epoch 4160 Batch    0/1   train_loss = 0.711
Epoch 4180 Batch    0/1   train_loss = 0.741
Epoch 4200 Batch    0/1   train_loss = 0.695
Epoch 4220 Batch    0/1   train_loss = 0.775
Epoch 4240 Batch    0/1   train_loss = 0.683
Epoch 4260 Batch    0/1   train_loss = 0.697
Epoch 4280 Batch    0/1   train_loss = 0.664
Epoch 4300 Batch    0/1   train_loss = 0.647
Epoch 4320 Batch    0/1   train_loss = 0.660
Epoch 4340 Batch    0/1   train_loss = 0.631
Epoch 4360 Batch    0/1   train_loss = 0.635
Epoch 4380 Batch    0/1   train_loss = 0.639
Epoch 4400 Batch    0/1   train_loss = 0.638
Epoch 4420 Batch    0/1   train_loss = 0.597
Epoch 4440 Batch    0/1   train_loss = 0.618
Epoch 4460 Batch    0/1   train_loss = 0.587
Epoch 4480 Batch    0/1   train_loss = 0.584
Epoch 4500 Batch    0/1   train_loss = 0.586
Epoch 4520 Batch    0/1   train_loss = 0.555
Epoch 4540 Batch    0/1   train_loss = 0.632
Epoch 4560 Batch    0/1   train_loss = 0.553
Epoch 4580 Batch    0/1   train_loss = 0.545
Epoch 4600 Batch    0/1   train_loss = 0.536
Epoch 4620 Batch    0/1   train_loss = 0.524
Epoch 4640 Batch    0/1   train_loss = 0.645
Epoch 4660 Batch    0/1   train_loss = 0.518
Epoch 4680 Batch    0/1   train_loss = 0.499
Epoch 4700 Batch    0/1   train_loss = 0.548
Epoch 4720 Batch    0/1   train_loss = 0.501
Epoch 4740 Batch    0/1   train_loss = 0.481
Epoch 4760 Batch    0/1   train_loss = 0.490
Epoch 4780 Batch    0/1   train_loss = 0.470
Epoch 4800 Batch    0/1   train_loss = 0.521
Epoch 4820 Batch    0/1   train_loss = 0.465
Epoch 4840 Batch    0/1   train_loss = 0.448
Epoch 4860 Batch    0/1   train_loss = 0.599
Epoch 4880 Batch    0/1   train_loss = 0.461
Epoch 4900 Batch    0/1   train_loss = 0.435
Epoch 4920 Batch    0/1   train_loss = 0.433
Epoch 4940 Batch    0/1   train_loss = 0.426
Epoch 4960 Batch    0/1   train_loss = 0.527
Epoch 4980 Batch    0/1   train_loss = 0.434
Epoch 5000 Batch    0/1   train_loss = 0.408
Epoch 5020 Batch    0/1   train_loss = 0.409
Epoch 5040 Batch    0/1   train_loss = 0.396
Epoch 5060 Batch    0/1   train_loss = 0.438
Epoch 5080 Batch    0/1   train_loss = 0.395
Epoch 5100 Batch    0/1   train_loss = 0.379
Epoch 5120 Batch    0/1   train_loss = 0.477
Epoch 5140 Batch    0/1   train_loss = 0.385
Epoch 5160 Batch    0/1   train_loss = 0.367
Epoch 5180 Batch    0/1   train_loss = 0.361
Epoch 5200 Batch    0/1   train_loss = 0.372
Epoch 5220 Batch    0/1   train_loss = 0.352
Epoch 5240 Batch    0/1   train_loss = 0.440
Epoch 5260 Batch    0/1   train_loss = 0.384
Epoch 5280 Batch    0/1   train_loss = 0.345
Epoch 5300 Batch    0/1   train_loss = 0.334
Epoch 5320 Batch    0/1   train_loss = 0.336
Epoch 5340 Batch    0/1   train_loss = 0.335
Epoch 5360 Batch    0/1   train_loss = 0.321
Epoch 5380 Batch    0/1   train_loss = 0.579
Epoch 5400 Batch    0/1   train_loss = 0.351
Epoch 5420 Batch    0/1   train_loss = 0.317
Epoch 5440 Batch    0/1   train_loss = 0.306
Epoch 5460 Batch    0/1   train_loss = 0.307
Epoch 5480 Batch    0/1   train_loss = 0.301
Epoch 5500 Batch    0/1   train_loss = 0.355
Epoch 5520 Batch    0/1   train_loss = 0.304
Epoch 5540 Batch    0/1   train_loss = 0.290
Epoch 5560 Batch    0/1   train_loss = 0.284
Epoch 5580 Batch    0/1   train_loss = 0.282
Epoch 5600 Batch    0/1   train_loss = 0.882
Epoch 5620 Batch    0/1   train_loss = 0.418
Epoch 5640 Batch    0/1   train_loss = 0.294
Epoch 5660 Batch    0/1   train_loss = 0.276
Epoch 5680 Batch    0/1   train_loss = 0.268
Epoch 5700 Batch    0/1   train_loss = 0.263
Epoch 5720 Batch    0/1   train_loss = 0.260
Epoch 5740 Batch    0/1   train_loss = 0.256
Epoch 5760 Batch    0/1   train_loss = 0.255
Epoch 5780 Batch    0/1   train_loss = 0.249
Epoch 5800 Batch    0/1   train_loss = 0.393
Epoch 5820 Batch    0/1   train_loss = 0.286
Epoch 5840 Batch    0/1   train_loss = 0.251
Epoch 5860 Batch    0/1   train_loss = 0.240
Epoch 5880 Batch    0/1   train_loss = 0.236
Epoch 5900 Batch    0/1   train_loss = 0.234
Epoch 5920 Batch    0/1   train_loss = 0.230
Epoch 5940 Batch    0/1   train_loss = 0.228
Epoch 5960 Batch    0/1   train_loss = 0.316
Epoch 5980 Batch    0/1   train_loss = 0.301
Epoch 6000 Batch    0/1   train_loss = 0.234
Epoch 6020 Batch    0/1   train_loss = 0.221
Epoch 6040 Batch    0/1   train_loss = 0.217
Epoch 6060 Batch    0/1   train_loss = 0.213
Epoch 6080 Batch    0/1   train_loss = 0.210
Epoch 6100 Batch    0/1   train_loss = 0.211
Epoch 6120 Batch    0/1   train_loss = 0.206
Epoch 6140 Batch    0/1   train_loss = 0.962
Epoch 6160 Batch    0/1   train_loss = 0.256
Epoch 6180 Batch    0/1   train_loss = 0.212
Epoch 6200 Batch    0/1   train_loss = 0.201
Epoch 6220 Batch    0/1   train_loss = 0.196
Epoch 6240 Batch    0/1   train_loss = 0.193
Epoch 6260 Batch    0/1   train_loss = 0.191
Epoch 6280 Batch    0/1   train_loss = 0.189
Epoch 6300 Batch    0/1   train_loss = 0.186
Epoch 6320 Batch    0/1   train_loss = 0.890
Epoch 6340 Batch    0/1   train_loss = 0.298
Epoch 6360 Batch    0/1   train_loss = 0.203
Epoch 6380 Batch    0/1   train_loss = 0.187
Epoch 6400 Batch    0/1   train_loss = 0.182
Epoch 6420 Batch    0/1   train_loss = 0.178
Epoch 6440 Batch    0/1   train_loss = 0.176
Epoch 6460 Batch    0/1   train_loss = 0.173
Epoch 6480 Batch    0/1   train_loss = 0.172
Epoch 6500 Batch    0/1   train_loss = 0.169
Epoch 6520 Batch    0/1   train_loss = 0.168
Epoch 6540 Batch    0/1   train_loss = 0.167
Epoch 6560 Batch    0/1   train_loss = 0.164
Epoch 6580 Batch    0/1   train_loss = 0.163
Epoch 6600 Batch    0/1   train_loss = 0.161
Epoch 6620 Batch    0/1   train_loss = 0.161
Epoch 6640 Batch    0/1   train_loss = 0.157
Epoch 6660 Batch    0/1   train_loss = 0.161
Epoch 6680 Batch    0/1   train_loss = 0.418
Epoch 6700 Batch    0/1   train_loss = 0.200
Epoch 6720 Batch    0/1   train_loss = 0.167
Epoch 6740 Batch    0/1   train_loss = 0.158
Epoch 6760 Batch    0/1   train_loss = 0.154
Epoch 6780 Batch    0/1   train_loss = 0.151
Epoch 6800 Batch    0/1   train_loss = 0.149
Epoch 6820 Batch    0/1   train_loss = 0.147
Epoch 6840 Batch    0/1   train_loss = 0.146
Epoch 6860 Batch    0/1   train_loss = 0.144
Epoch 6880 Batch    0/1   train_loss = 0.143
Epoch 6900 Batch    0/1   train_loss = 0.141
Epoch 6920 Batch    0/1   train_loss = 0.141
Epoch 6940 Batch    0/1   train_loss = 0.139
Epoch 6960 Batch    0/1   train_loss = 0.137
Epoch 6980 Batch    0/1   train_loss = 0.137
Epoch 7000 Batch    0/1   train_loss = 0.135
Epoch 7020 Batch    0/1   train_loss = 0.133
Epoch 7040 Batch    0/1   train_loss = 0.132
Epoch 7060 Batch    0/1   train_loss = 0.133
Epoch 7080 Batch    0/1   train_loss = 0.130
Epoch 7100 Batch    0/1   train_loss = 0.130
Epoch 7120 Batch    0/1   train_loss = 0.128
Epoch 7140 Batch    0/1   train_loss = 0.127
Epoch 7160 Batch    0/1   train_loss = 0.131
Epoch 7180 Batch    0/1   train_loss = 0.480
Epoch 7200 Batch    0/1   train_loss = 0.188
Epoch 7220 Batch    0/1   train_loss = 0.143
Epoch 7240 Batch    0/1   train_loss = 0.133
Epoch 7260 Batch    0/1   train_loss = 0.129
Epoch 7280 Batch    0/1   train_loss = 0.127
Epoch 7300 Batch    0/1   train_loss = 0.125
Epoch 7320 Batch    0/1   train_loss = 0.123
Epoch 7340 Batch    0/1   train_loss = 0.122
Epoch 7360 Batch    0/1   train_loss = 0.121
Epoch 7380 Batch    0/1   train_loss = 0.120
Epoch 7400 Batch    0/1   train_loss = 0.119
Epoch 7420 Batch    0/1   train_loss = 0.118
Epoch 7440 Batch    0/1   train_loss = 0.117
Epoch 7460 Batch    0/1   train_loss = 0.116
Epoch 7480 Batch    0/1   train_loss = 0.115
Epoch 7500 Batch    0/1   train_loss = 0.114
Epoch 7520 Batch    0/1   train_loss = 0.114
Epoch 7540 Batch    0/1   train_loss = 0.113
Epoch 7560 Batch    0/1   train_loss = 0.112
Epoch 7580 Batch    0/1   train_loss = 0.111
Epoch 7600 Batch    0/1   train_loss = 0.110
Epoch 7620 Batch    0/1   train_loss = 0.110
Epoch 7640 Batch    0/1   train_loss = 0.109
Epoch 7660 Batch    0/1   train_loss = 0.108
Epoch 7680 Batch    0/1   train_loss = 0.108
Epoch 7700 Batch    0/1   train_loss = 0.109
Epoch 7720 Batch    0/1   train_loss = 0.107
Epoch 7740 Batch    0/1   train_loss = 0.106
Epoch 7760 Batch    0/1   train_loss = 0.105
Epoch 7780 Batch    0/1   train_loss = 0.104
Epoch 7800 Batch    0/1   train_loss = 0.104
Epoch 7820 Batch    0/1   train_loss = 0.103
Epoch 7840 Batch    0/1   train_loss = 0.103
Epoch 7860 Batch    0/1   train_loss = 0.102
Epoch 7880 Batch    0/1   train_loss = 0.102
Epoch 7900 Batch    0/1   train_loss = 0.101
Epoch 7920 Batch    0/1   train_loss = 0.101
Epoch 7940 Batch    0/1   train_loss = 0.100
Epoch 7960 Batch    0/1   train_loss = 0.100
Epoch 7980 Batch    0/1   train_loss = 0.099
Epoch 8000 Batch    0/1   train_loss = 0.098
Epoch 8020 Batch    0/1   train_loss = 0.098
Epoch 8040 Batch    0/1   train_loss = 1.791
Epoch 8060 Batch    0/1   train_loss = 0.398
Epoch 8080 Batch    0/1   train_loss = 0.154
Epoch 8100 Batch    0/1   train_loss = 0.120
Epoch 8120 Batch    0/1   train_loss = 0.111
Epoch 8140 Batch    0/1   train_loss = 0.108
Epoch 8160 Batch    0/1   train_loss = 0.105
Epoch 8180 Batch    0/1   train_loss = 0.104
Model Trained and Saved

Save Parameters

Save seq_length and save_dir for generating a new TV script.


In [17]:
"""
DON'T MODIFY ANYTHING IN THIS CELL
"""
# Save parameters for checkpoint
helper.save_params((seq_length, save_dir))

Checkpoint


In [18]:
"""
DON'T MODIFY ANYTHING IN THIS CELL
"""
import tensorflow as tf
import numpy as np
import helper
import problem_unittests as tests

_, vocab_to_int, int_to_vocab, token_dict = helper.load_preprocess()
seq_length, load_dir = helper.load_params()

Implement Generate Functions

Get Tensors

Get tensors from loaded_graph using the function get_tensor_by_name(). Get the tensors using the following names:

  • "input:0"
  • "initial_state:0"
  • "final_state:0"
  • "probs:0"

Return the tensors in the following tuple (InputTensor, InitialStateTensor, FinalStateTensor, ProbsTensor)


In [19]:
def get_tensors(loaded_graph):
    """
    Get input, initial state, final state, and probabilities tensor from <loaded_graph>
    :param loaded_graph: TensorFlow graph loaded from file
    :return: Tuple (InputTensor, InitialStateTensor, FinalStateTensor, ProbsTensor)
    """
    # TODO: Implement Function
    inputs = loaded_graph.get_tensor_by_name('input:0')
    initial_state = loaded_graph.get_tensor_by_name('initial_state:0')
    final_state = loaded_graph.get_tensor_by_name('final_state:0')
    probs = loaded_graph.get_tensor_by_name('probs:0')
    return inputs, initial_state, final_state, probs


"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
tests.test_get_tensors(get_tensors)


Tests Passed

Choose Word

Implement the pick_word() function to select the next word using probabilities.


In [20]:
def pick_word(probabilities, int_to_vocab):
    """
    Pick the next word in the generated text
    :param probabilities: Probabilites of the next word
    :param int_to_vocab: Dictionary of word ids as the keys and words as the values
    :return: String of the predicted word
    """
    # TODO: Implement Function
    weighted_index = np.searchsorted(np.cumsum(probabilities), np.random.rand())
    return int_to_vocab[int(weighted_index)]


"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
tests.test_pick_word(pick_word)


Tests Passed

Generate TV Script

This will generate the TV script for you. Set gen_length to the length of TV script you want to generate.


In [22]:
gen_length = 200
# homer_simpson, moe_szyslak, or Barney_Gumble
prime_word = 'moe_szyslak'

"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
loaded_graph = tf.Graph()
with tf.Session(graph=loaded_graph) as sess:
    # Load saved model
    loader = tf.train.import_meta_graph(load_dir + '.meta')
    loader.restore(sess, load_dir)

    # Get Tensors from loaded model
    input_text, initial_state, final_state, probs = get_tensors(loaded_graph)

    # Sentences generation setup
    gen_sentences = [prime_word + ':']
    prev_state = sess.run(initial_state, {input_text: np.array([[1]])})

    # Generate sentences
    for n in range(gen_length):
        # Dynamic Input
        dyn_input = [[vocab_to_int[word] for word in gen_sentences[-seq_length:]]]
        dyn_seq_length = len(dyn_input[0])

        # Get Prediction
        probabilities, prev_state = sess.run(
            [probs, final_state],
            {input_text: dyn_input, initial_state: prev_state})
        
        pred_word = pick_word(probabilities[dyn_seq_length-1], int_to_vocab)

        gen_sentences.append(pred_word)
    
    # Remove tokens
    tv_script = ' '.join(gen_sentences)
    for key, token in token_dict.items():
        ending = ' ' if key in ['\n', '(', '"'] else ''
        tv_script = tv_script.replace(' ' + token.lower(), key)
    tv_script = tv_script.replace('\n ', '\n')
    tv_script = tv_script.replace('( ', '(')
        
    print(tv_script)


moe_szyslak:(into phone) moe's tavern. where the elite meet to drink.
bart_simpson: eh, yeah, hello, is mike there? last name, rotch.
moe_szyslak: okay, who you should about me, here, life-threatening,, and uh... ball's on...
moe_szyslak:(scornfully) aw, barney have moe?
homer_simpson:(to barney) they couldn't hit it the secret. back. to it, this is is?
homer_simpson: gimme it!
professor_jonathan_frink: moe it, didn't you ever take the bad or you're this.
moe_szyslak: now, what., no. there's better past.
homer_simpson: i girl ya from only bart thing germany. beer, you gotta put us in a lot reynolds face) they homer...! tv_father:(points at homer) he makes me happen?
krusty_the_clown: don't you care so mr.
homer_simpson: moe, i want i want two your" box," let's can the beat. yeah. you'll talk, and couldn't have the punch to

The TV Script is Nonsensical

It's ok if the TV script doesn't make any sense. We trained on less than a megabyte of text. In order to get good results, you'll have to use a smaller vocabulary or get more data. Luckly there's more data! As we mentioned in the begging of this project, this is a subset of another dataset. We didn't have you train on all the data, because that would take too long. However, you are free to train your neural network on all the data. After you complete the project, of course.

Submitting This Project

When submitting this project, make sure to run all the cells before saving the notebook. Save the notebook file as "dlnd_tv_script_generation.ipynb" and save it as a HTML file under "File" -> "Download as". Include the "helper.py" and "problem_unittests.py" files in your submission.