Welcome to the second assignment of course 4. In this assignment you will explore summarization using the transformer model. Yes, you will implement the transformer decoder from scratch, but we will slowly walk you through it. There are many hints in this notebook so feel free to use them as needed.
Before submitting your assignment to the AutoGrader, please make sure you are not doing the following:
print
statement(s) in the assignment.If you do any of the following, you will get something like, Grader not found
(or similarly unexpected) error upon submitting your assignment. Before asking for help/debugging the errors in your assignment, check for these first. If this is the case, and you don’t remember the changes you have made, you can get a fresh copy of the assignment by following these instructions.
Summarization is an important task in natural language processing and could be useful for a consumer enterprise. For example, bots can be used to scrape articles, summarize them, and then you can use sentiment analysis to identify the sentiment about certain stocks. Anyways who wants to read an article or a long email today, when you can build a transformer to summarize text for you. Let’s get started, by completing this assignment you will learn to:
As you can tell, this model is slightly different than the ones you have already implemented. This is heavily based on attention and does not rely on sequences, which allows for parallel computing.
import sys
import os
import w2_tests
import numpy as np
import textwrap
wrapper = textwrap.TextWrapper(width=70)
import trax
from trax import layers as tl
from trax.fastmath import numpy as jnp
# to print the entire np array
np.set_printoptions(threshold=sys.maxsize)
!pip list|grep trax
trax 1.3.9
[33mWARNING: You are using pip version 21.2.4; however, version 22.2 is available.
You should consider upgrading via the '/opt/conda/bin/python3 -m pip install --upgrade pip' command.[0m
Trax makes it easy to work with Tensorflow’s datasets:
# This will download the dataset if no data_dir is specified.
# Downloading and processing can take bit of time,
# so we have the data already in 'data/' for you
# Importing CNN/DailyMail articles dataset
train_stream_fn = trax.data.TFDS('cnn_dailymail',
data_dir='data/',
keys=('article', 'highlights'),
train=True)
# This should be much faster as the data is downloaded already.
eval_stream_fn = trax.data.TFDS('cnn_dailymail',
data_dir='data/',
keys=('article', 'highlights'),
train=False)
WARNING:absl:No GPU/TPU found, falling back to CPU. (Set TF_CPP_MIN_LOG_LEVEL=0 and rerun for more info.)
WARNING:tensorflow:AutoGraph could not transform <function TFDS.<locals>.select_from at 0x7f45795353b0> and will run it as-is.
Please report this to the TensorFlow team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output.
Cause: module 'gast' has no attribute 'Constant'
To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert
WARNING:tensorflow:AutoGraph could not transform <function TFDS.<locals>.select_from at 0x7f45795353b0> and will run it as-is.
Please report this to the TensorFlow team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output.
Cause: module 'gast' has no attribute 'Constant'
To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert
WARNING: AutoGraph could not transform <function TFDS.<locals>.select_from at 0x7f45795353b0> and will run it as-is.
Please report this to the TensorFlow team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output.
Cause: module 'gast' has no attribute 'Constant'
To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert
WARNING:tensorflow:AutoGraph could not transform <function TFDS.<locals>.select_from at 0x7f4579515a70> and will run it as-is.
Please report this to the TensorFlow team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output.
Cause: module 'gast' has no attribute 'Constant'
To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert
WARNING:tensorflow:AutoGraph could not transform <function TFDS.<locals>.select_from at 0x7f4579515a70> and will run it as-is.
Please report this to the TensorFlow team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output.
Cause: module 'gast' has no attribute 'Constant'
To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert
WARNING: AutoGraph could not transform <function TFDS.<locals>.select_from at 0x7f4579515a70> and will run it as-is.
Please report this to the TensorFlow team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output.
Cause: module 'gast' has no attribute 'Constant'
To silence this warning, decorate the function with @tf.autograph.experimental.do_not_convert
Just like in the previous assignment, the cell above loads in the encoder for you. Given any data set, you have to be able to map words to their indices, and indices to their words. The inputs and outputs to your Trax models are usually tensors of numbers where each number corresponds to a word. If you were to process your data manually, you would have to make use of the following:
Since you have already implemented these in previous assignments of the specialization, we will provide you with helper functions that will do this for you. Run the cell below to get the following functions:
def tokenize(input_str, EOS=1):
"""Input str to features dict, ready for inference"""
# Use the trax.data.tokenize method. It takes streams and returns streams,
# we get around it by making a 1-element stream with `iter`.
inputs = next(trax.data.tokenize(iter([input_str]),
vocab_dir='vocab_dir/',
vocab_file='summarize32k.subword.subwords'))
# Mark the end of the sentence with EOS
return list(inputs) + [EOS]
def detokenize(integers):
"""List of ints to str"""
s = trax.data.detokenize(integers,
vocab_dir='vocab_dir/',
vocab_file='summarize32k.subword.subwords')
return wrapper.fill(s)
This week you will use a language model – Transformer Decoder – to solve an input-output problem. As you know, language models only predict the next word, they have no notion of inputs. To create a single input suitable for a language model, we concatenate inputs with targets putting a separator in between. We also need to create a mask – with 0s at inputs and 1s at targets – so that the model is not penalized for mis-predicting the article and only focuses on the summary. See the preprocess function below for how this is done.
# Special tokens
SEP = 0 # Padding or separator token
EOS = 1 # End of sentence token
# Concatenate tokenized inputs and targets using 0 as separator.
def preprocess(stream):
for (article, summary) in stream:
joint = np.array(list(article) + [EOS, SEP] + list(summary) + [EOS])
mask = [0] * (len(list(article)) + 2) + [1] * (len(list(summary)) + 1) # Accounting for EOS and SEP
yield joint, joint, np.array(mask)
# You can combine a few data preprocessing steps into a pipeline like this.
input_pipeline = trax.data.Serial(
# Tokenizes
trax.data.Tokenize(vocab_dir='vocab_dir/',
vocab_file='summarize32k.subword.subwords'),
# Uses function defined above
preprocess,
# Filters out examples longer than 2048
trax.data.FilterByLength(2048)
)
# Apply preprocessing to data streams.
train_stream = input_pipeline(train_stream_fn())
eval_stream = input_pipeline(eval_stream_fn())
train_input, train_target, train_mask = next(train_stream)
assert sum((train_input - train_target)**2) == 0 # They are the same in Language Model (LM).
# prints mask, 0s on article, 1s on summary
print(f'Single example mask:\n\n {train_mask}')
Single example mask:
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1]
# prints: [Example][<EOS>][<pad>][Example Summary][<EOS>]
print(f'Single example:\n\n {detokenize(train_input)}')
Single example:
QPR chairman Tony Fernandes has insisted his club can afford not to
win promotion to the Premier League, despite debts of £177.1 million.
Rangers face Derby County in the Championship play-off final at
Wembley on May 24, with Harry Redknapp's side hoping to secure the
£120m pay packet of Premier League promotion. But, should QPR return
to the top tier at the first attempt, they could be forced to pay out
more than half of that in fines under the Football League's Financial
Fair Play regulations. We're ready: Queens Park Rangers chairman Tony
Fernandes says his club doesn't have to win promotion . Off to
Wembley: Rangers won their way through to the play-off final after
extra-time against Wigan . Based on last year's accounts, Rangers
would have to pay £62.1m if they are promoted because their £65.4m
losses were so far in excess of the £8m allowed by the Football
League. Should Redknapp's side stay in the Championship, however, they
would be subjected to a transfer embargo. QPR have tried to reduce
their wage bill by selling high-earners such as Christopher Samba and
sending the likes of Loic Remy and Adel Taarabt out on loan. Improved:
Businessman Fernandes says QPR are in a better financial position than
two years ago . Winner: QPR striker Charlie Austin finds the net to
snatch the victory in the play-off second leg . Fernandes told
talkSPORT: 'Yes, we can (afford not to go up). I'm an accountant by
background - although I may not seem it! 'We've told the fans, whether
we go up or we don't, we're here for the long term. 'We know what
culture we want at the club and we will continue the journey whether
we're in the Championship or the Premier League. 'We are a much
smarter, much wiser group of people than we were two years ago.'
Relief: QPR's bid to reduce their wage bills included off-loading
players such as Christopher Samba . Major break: Loic Remy (right)
went on loan to Newcastle and scored 14 goals for Alan Pardew's side
.<EOS><pad>QueensPark Rangers have debts of £177.1 million . The club
is also set to be hit with fines under Financial Fair Play rules . But
chairman Tony Fernandes says they can survive without winning
promotion to the Premier League this season . QPR take on Derby in the
play-off final at Wembley on May 24 .<EOS>
As in the previous week, we use bucketing to create batches of data.
# Bucketing to create batched generators.
# Buckets are defined in terms of boundaries and batch sizes.
# Batch_sizes[i] determines the batch size for items with length < boundaries[i]
# So below, we'll take a batch of 16 sentences of length < 128 , 8 of length < 256,
# 4 of length < 512. And so on.
boundaries = [128, 256, 512, 1024]
batch_sizes = [16, 8, 4, 2, 1]
# Create the streams.
train_batch_stream = trax.data.BucketByLength(
boundaries, batch_sizes)(train_stream)
eval_batch_stream = trax.data.BucketByLength(
boundaries, batch_sizes)(eval_stream)
# Every execution will result in generation of a different article
# Try running this cell multiple times to see how the length of the examples affects the batch size
input_batch, _, mask_batch = next(train_batch_stream)
# Shape of the input_batch
input_batch.shape
(1, 1618)
# print corresponding integer values
print(input_batch[0])
[ 1680 11703 6133 12461 5485 213 1698 1320 306 527 5323 10366
6623 4 78 2613 2 4874 809 518 373 101 186 501
25765 1423 7 5 1098 2284 412 103 18766 5 320 1798
213 7322 6682 132 256 74 635 1492 3 9 12758 1205
28 16233 11085 2137 542 28 5955 700 145 213 1859 14183
1807 2 28 194 102 28 14131 809 5323 10366 6623 4
7 5 548 1973 947 1343 441 101 186 6531 809 518
1120 3 20900 18250 58 6857 132 2 28 14380 1019 213
296 7 5 1080 2694 2684 2 793 213 205 6 655
782 2684 3513 27 9293 8560 100 285 148 19181 400 25
8409 2860 1133 27634 4 56 4303 2 1480 1353 22793 2741
2935 1019 213 422 527 19101 1019 119 2006 7 5 17203
2 229 36 44 1913 691 17362 320 552 28 2439 979
2 3531 558 22756 186 16130 2 186 17082 866 6827 5314
186 7740 132 1320 773 4617 27634 391 127 28 1602 2613
691 1423 7 5 3913 3973 2734 1133 27634 4 129 39
19 179 246 186 39 952 89 5306 186 2762 6352 27634
391 214 17362 2 213 7989 7 5 1602 127 2 4195
285 106 163 2443 669 27634 4 49 86 1151 4194 691
3444 1338 27634 391 3840 213 566 289 3 9 15402 6682
379 321 36 2663 2269 1019 213 5323 10366 6623 4 11177
5 2 35 41 1841 329 711 102 213 1299 527 28
19796 279 18597 330 260 10966 21 1740 320 17201 4 213
418 2984 6401 7322 6682 285 1977 78 754 112 3 597
2780 965 699 821 9979 4 18462 213 10621 627 412 669
27634 4 28 21822 6616 478 1287 78 13379 101 1133 27634
4 9 1146 566 1028 12522 156 132 9493 114 15863 16
824 6479 7070 114 1258 4617 27634 391 9979 4 127 132
28 1602 2 4195 285 22 1113 1320 699 19717 12366 320
4413 13243 5358 1204 412 110 412 669 27634 4 89 3594
132 213 1320 1882 320 4684 2603 186 4182 2022 132 2984
6401 4172 27634 391 5674 2 213 257 366 1763 50 669
27634 4 444 291 320 213 1320 266 132 1098 19101 1019
213 2984 6401 2780 2022 4617 27634 391 276 3283 751 17984
1091 8963 20917 4 18345 279 127 132 28 1602 1133 27634
4 129 62 3857 213 1171 1019 4426 4212 1019 213 1646
527 213 3740 2 18130 5 2 186 54 2513 4617 27634
391 18345 279 127 3 5323 10366 6623 4 229 28 407
3620 12518 132 1698 1423 186 28 548 6106 340 1019 101
8549 691 1973 320 2984 6401 78 213 1168 2327 2 141
95 2719 1059 8 4598 65 15261 12 320 213 10739 3
1888 194 2 2659 527 6672 147 213 947 132 213 306
640 316 12055 19544 1600 3 1162 11177 5 132 72 390
379 7284 12467 1838 213 1610 2613 1606 213 15626 17 5067
527 28 2498 16233 11085 2137 2 1248 12187 2540 239 103
3 9 910 527 213 14131 6603 558 64 213 5363 527
213 2137 2 412 110 412 3778 527 329 3020 1542 3
348 518 705 101 25 831 320 1151 6531 2 1248 329
132 1839 1785 2 176 36 99 6 984 6 292 966
2 3513 27 9293 8560 100 831 3 4439 78 213 12467
2 213 14131 1472 320 18 1841 132 213 179 605 527
213 2137 3 9 1080 2694 2684 127 103 5435 213 12758
1353 284 236 691 28 1718 6133 17445 4 3 25783 692
127 213 1973 947 14131 1681 43 1472 320 18 46 1768
691 28 6133 17445 4 3 6857 132 793 3513 27 9293
8560 100 285 2182 3687 39 1151 1526 64 78 213 1199
527 213 947 17445 4 2 1779 149 213 4026 527 546
7728 8 137 15062 20462 12 527 14362 189 132 28 2993
2522 10924 6709 7633 3 25783 692 127 41 43 233 163
16963 19614 17 23201 14 809 213 1610 3 7284 576 1838
163 872 1098 4701 1606 28 1917 5908 1400 1599 2754 1494
320 1151 213 548 4322 527 213 150 6 488 1384 474
2 1005 691 28 8467 4949 527 5805 1083 64 527 25895
17 3778 3 1423 7 5 1098 1901 379 34 484 2
3604 10433 8627 5193 473 2 213 1299 527 213 19796 279
260 18733 93 21764 587 2 973 28 846 1602 132 1480
22 16613 17 320 16075 14276 151 669 27634 4 2461 1017
27634 391 320 17201 4 213 584 809 2984 6401 3 9
184 10 59 3 303 676 9900 213 18733 93 21764 587
28 1255 8409 260 186 23 8175 28 14066 527 61 320
281 65 446 1019 215 971 320 213 1154 527 8627 5193
473 3 9 303 676 127 8627 5193 473 2366 28 6133
12461 872 213 19796 279 12970 2734 132 389 460 3 405
260 43 2663 2269 1019 213 421 12461 527 13510 12433 13582
79 6493 132 4792 285 1343 1513 101 2 213 387 10621
627 527 213 4792 24649 285 1343 668 186 213 460 12461
527 213 208 6 1869 13559 2775 9170 1973 132 1480 705
101 710 3 34 560 2 28 17445 4 6603 558 61
28 6683 2137 132 5323 10366 6623 4 2 4874 635 101
186 2281 26523 4 44 74 286 469 3 1320 564 831
285 28 1361 22918 4 6133 17445 4 1838 213 1320 606
527 2669 7552 163 1353 1478 1019 285 1287 1133 27634 4
1135 527 213 13139 5 1478 1019 8409 2860 132 1423 95
213 220 2593 76 176 1361 6133 17445 5 1779 18 576
160 132 247 2860 9420 809 518 6102 121 1056 254 426
591 76 18 413 1838 2669 7552 163 4617 27634 391 3513
27 9293 8560 100 831 2613 3 9 72 506 313 936
213 1633 15666 78 10621 627 1449 6932 132 2669 7552 163
171 1083 320 213 257 366 2 186 36 527 105 3198
213 201 213 104 171 213 1287 1133 27634 4 13888 997
22918 4 535 6118 320 213 489 214 213 1320 205 169
18 196 8352 4241 2 186 1435 525 44 1050 2 132
2669 7552 163 74 132 19796 4438 28 4617 27634 391 8539
47 3186 78 2 1661 2907 809 213 2556 751 2 1113
132 28 14607 10 394 5656 3 397 439 1151 936 213
2860 98 12366 23 3101 285 213 2984 6401 584 39 1151
2603 186 1098 39 1151 8058 3 13868 5 320 2984 6401
186 213 2605 201 1435 13463 320 19583 1098 11658 2 186
2245 5170 7689 1435 16112 1133 27634 4 56 39 934 1151
36 527 213 94 1181 6682 320 962 273 412 28 18130
4 186 2040 213 2022 166 527 213 22270 18243 4 8358
527 1098 4617 27634 391 3837 13595 3 1096 16087 75 527
119 262 793 14607 78 2613 3 1225 1085 527 1423 379
342 2 213 5323 10366 6623 4 19181 400 1606 213 1901
285 1320 1882 882 132 20333 213 1272 527 213 296 10909
4183 17274 4 132 213 438 18733 93 3 449 606 803
19796 4438 28 2 4872 1423 4562 72 8125 214 18597 330
4206 2 186 2669 7552 163 3 512 8058 1098 239 2984
6401 838 2 17362 1435 2162 320 1151 7310 78 54 1085
527 213 438 18733 93 186 1698 1423 3 3513 27 9293
8560 100 831 28 1081 7086 1343 150 101 78 2102 132
7622 3717 6345 8945 132 1698 1423 2 2685 9265 1059 8
21556 15261 12 1077 527 2984 6401 1133 27634 4 25355 114
124 33 962 18 28 8409 260 413 64 186 476 948
129 7 165 416 320 1124 186 17201 4 97 584 22137
27634 391 14607 404 1098 16973 19835 4 12444 250 127 2613
1133 27634 4 312 67 17664 6 582 20077 535 191 97
2548 527 3234 2 33 7 183 540 320 245 105 809
31 1032 4172 27634 391 9 503 285 213 17445 5 1435
11713 3061 229 669 27634 4 19 913 78 2780 965 18417
5 186 1098 1631 4617 27634 391 131 969 3 26481 45
1435 669 27634 4 94 6754 27634 391 7511 1772 111 213
2780 5317 186 213 956 527 31 678 2 131 127 3
12444 250 2 1779 16022 1248 2363 1631 171 213 6682 132
11435 132 645 2 127 1098 1631 38 95 213 175 39
1151 4823 1423 1019 2166 215 2685 97 2860 2 176 647
77 25 116 12302 400 181 11080 627 3 207 7 371
43 2005 2685 2754 215 1320 3885 23 78 213 7719 527
8409 535 320 6909 236 501 2860 10 1 0 184 10
59 3 25374 4 465 18130 5 39 882 8058 6682 1098
16346 27439 6774 1628 1423 7 5 1255 7989 16613 17 28
901 669 27634 4 5306 27634 391 6352 214 8155 16346 27439
6774 1628 1162 8409 10621 627 1205 5323 10366 6623 4 2
4874 44 74 286 101 16346 27439 6774 1628 9 2860 1689
2514 2685 1098 809 213 6682 132 754 2104 1]
Things to notice:
<EOS>
tag of the article.<pad>
tag.<pad>
tag) the corresponding values are of the words that are used for the summary of the article.<EOS>
tag for the summary.<pad>
tags which are appended to maintain consistent length (If you don’t see them then it would mean it is already of max length)# print the article and its summary
print('Article:\n\n', detokenize(input_batch[0]))
Article:
Another suspected suicide bombing struck the southern Russian city of
Volgograd on Monday, killing at least 14 people and further
highlighting Russia's security challenges as it prepares to host the
Winter Olympics in less than six weeks. The explosion hit a trolleybus
near a busy market during the morning rush hour, a day after a blast
at Volgograd's main train station killed 17 people and wounded at
least 35. Vladmir Markin, a spokesman for the country's federal
investigation agency, told the state-run news agency RIA Novosti that
both explosions were terrorist attacks. "This strike, which was
cynically planned for the period of preparations for New Year's
celebrations, is one more attempt by terrorists to open a domestic
front, sow panic and chaos, and trigger religious strife and conflicts
in Russian society," said a statement Monday by Russia's Foreign
Affairs Ministry. "We will not back down and will continue our tough
and consistent offensive" against terrorists, the ministry's statement
said, adding that such an enemy "can only be stopped by joint efforts"
involving the international community. The approaching Olympics . No
one claimed responsibility for the Volgograd blasts, but they occurred
several months after the leader of a Chechen separatist group pledged
violence to disrupt the 2014 Sochi Winter Olympics that begin on
February 7. International Olympic Committee President Thomas Bach
condemned the bombings as "a despicable attack on innocent people.
"The entire international movement joins me in utterly condemning this
cowardly act," Bach said in a statement, adding that he wrote Russian
President Vladimir Putin to express condolences as well as "our
confidence in the Russian authorities to deliver safe and secure Games
in Sochi." Meanwhile, the United States offered its "full support to
the Russian government in security preparations for the Sochi Olympic
Games," National Security Council spokeswoman Caitlin Hayden said in a
statement. "We would welcome the opportunity for closer cooperation
for the safety of the athletes, spectators, and other participants,"
Hayden said. Volgograd is a major rail hub in southern Russia and a
main transit point for people traveling by train to Sochi on the Black
Sea, just over 400 miles (645 kilometers) to the southwest. Each day,
thousands of passengers use the station in the city once called
Stalingrad. Two blasts in two days . Video footage from the scene
Monday showed the twisted shell of a blue trolleybus, with debris
spread around it. The impact of the blast blew out the roof of the
bus, as well as windows of several nearby houses. At least 28 people
were reported to be wounded, with several in serious condition,
including one 6-month-old child, RIA Novosti reported. Based on the
footage, the blast appeared to have occurred in the back half of the
bus. The federal investigation agency said it believes the explosion
was set off by a male suicide bomber. Investigators said the train
station blast Sunday also appeared to have been caused by a suicide
bomber. Markin told RIA Novosti that DNA testing will be carried out
on the remains of the station bomber, who used the equivalent of 22
pounds (10 kilograms) of TNT in a device containing shrapnel.
Investigators said they also found an unexploded grenade at the scene.
Video taken from an outside security camera showed a huge fireball
inside what appears to be the main entrance of the three-story stone
building, followed by a steady trail of smoke coming out of shattered
windows. Russia's security challenge . In July, Doku Umarov, the
leader of the Chechen group Caucasus Emirate, released a video
statement in which he vowed to unleash "maximum force" to disrupt the
games at Sochi. The U.S. State Department considers the Caucasus
Emirate a foreign terrorist group and has authorized a reward of up to
$5 million for information leading to the location of Umarov. The
State Department said Umarov organized a suicide bombing outside the
Chechen Interior Ministry in May 2009. His group also claimed
responsibility for the 2011 bombing of Domodedovo Airport in Moscow
that killed 36 people, the 2010 bombings of the Moscow subway that
killed 40 and the 2009 bombing of the high-speed Nevsky Express train
in which 28 people died. In October, a bomber blew up a passenger bus
in Volgograd, killing six people and wounding more than 30 others.
Russian media reported that a female Islamist suicide bomber from the
Russian region of Dagestan was responsible for that attack. "Most of
the militants responsible for terrorist attacks in Russia over the
last decade -- including female suicide bombers who have taken part in
20 attacks claiming at least 780 lives since June 2000 -- have come
from Dagestan," RIA Novosti reported Monday. The two young men behind
the Boston Marathon bombings lived briefly in Dagestan before coming
to the United States, and one of them visited the area the year before
the attack. "Radical Islamist groups tied to the war against the
Russian state now have much deeper roots, and are far more active, in
Dagestan than in Chechnya," Rajan Menon, senior fellow at the Atlantic
Council, wrote in a CNN.com column. What might be behind the attacks?
Putin has maintained that the Sochi games will be safe and security
will be tight. Visitors to Sochi and the surrounding area are
subjected to rigorous security checks, and vehicle license plates are
monitored. "This will probably be one of the most difficult Olympics
to actually go as a spectator and watch the Games because of the
myriad layers of security," Republican Rep. Michael Grimm of New York
told CNN on Monday. Other parts of Russia . However, the Volgograd
explosions showed the challenge that Russian authorities face in
policing the rest of the country amid ongoing unrest in the North
Caucasus. That region includes Chechnya, where Russia fought two wars
against separatist movements, and Dagestan. With tight security around
Sochi itself, terrorists are believed to be focusing on other parts of
the North Caucasus and southern Russia. RIA Novosti reported a car
bomb killed three people on Friday in Pyatigorsk in southern Russia,
about 160 miles (270 kilometers) east of Sochi. "Rarely do you
actually have a terrorist group come out and say, 'We're going to try
and disrupt these games,'" CNN national security analyst Fran Townsend
said Monday. "When al Qaeda-related affinity groups make these sort of
statements, you've got to take them at their word." The fact that the
bombers are targeting transportation is "not lost on Olympic Committee
organizers and security officials," she added. Athletes are "most
vulnerable" when moving between the Olympic Village and the sites of
their events, she said. Townsend, who coordinated with Greek officials
before the Olympics in Athens in 2004, said security officials all
over the world will be asking Russia for detailed information about
these attacks, including whether there were any indications or
warnings. They'll also ask about what information Russian intelligence
has on the capabilities of terrorist groups to pull off further
attacks.<EOS><pad>U.S. legislator says spectators will face tight
Olympics security . Russia's foreign ministry vowed a continued
"tough" offensive against terrorism . Two terrorist bombings hit
Volgograd, killing more than 30 people . The attacks raised concerns
about security at the Olympics in February .<EOS>
You can see that the data has the following structure:
<EOS>
-> <pad>
-> [Article Summary] -> <EOS>
-> (possibly) multiple <pad>
The loss is taken only on the summary using cross_entropy as loss function.
Now that we have given you the data generator and have handled the preprocessing for you, it is time for you to build your own model. We saved you some time because we know you have already preprocessed data before in this specialization, so we would rather you spend your time doing the next steps.
You will be implementing the attention from scratch and then using it in your transformer model. Concretely, you will understand how attention works, how you use it to connect the encoder and the decoder.
Now you will implement dot product attention which takes in a query, key, value, and a mask. It returns the output.
Here are some helper functions that will help you create tensors and display useful information:
create_tensor
creates a jax numpy array
from a list of lists.display_tensor
prints out the shape and the actual tensor.def create_tensor(t):
"""Create tensor from list of lists"""
return jnp.array(t)
def display_tensor(t, name):
"""Display shape and tensor"""
print(f'{name} shape: {t.shape}\n')
print(f'{t}\n')
Before implementing it yourself, you can play around with a toy example of dot product attention
without the softmax operation. Technically it would not be dot product attention
without the softmax but this is done to avoid giving away too much of the answer and the idea is to display these tensors to give you a sense of how they look like.
The formula for attention is this one:
$$
\text { Attention }(Q, K, V)=\operatorname{softmax}\left(\frac{Q K^{T}}{\sqrt{d_{k}}}+{M}\right) V\tag{1}
$$
$d_{k}$ stands for the dimension of queries and keys.
The query
, key
, value
and mask
vectors are provided for this example.
Notice that the masking is done using very negative values that will yield a similar effect to using $-\infty $.
q = create_tensor([[1, 0, 0], [0, 1, 0]])
display_tensor(q, 'query')
k = create_tensor([[1, 2, 3], [4, 5, 6]])
display_tensor(k, 'key')
v = create_tensor([[0, 1, 0], [1, 0, 1]])
display_tensor(v, 'value')
m = create_tensor([[0, 0], [-1e9, 0]])
display_tensor(m, 'mask')
query shape: (2, 3)
[[1 0 0]
[0 1 0]]
key shape: (2, 3)
[[1 2 3]
[4 5 6]]
value shape: (2, 3)
[[0 1 0]
[1 0 1]]
mask shape: (2, 2)
[[ 0.e+00 0.e+00]
[-1.e+09 0.e+00]]
Expected Output:
>query shape: (2, 3)
[[1 0 0]
[0 1 0]]
key shape: (2, 3)
[[1 2 3]
[4 5 6]]
value shape: (2, 3)
[[0 1 0]
[1 0 1]]
mask shape: (2, 2)
[[ 0.e+00 0.e+00]
[-1.e+09 0.e+00]]
q_dot_k = q @ k.T / jnp.sqrt(3)
display_tensor(q_dot_k, 'query dot key')
query dot key shape: (2, 2)
[[0.57735026 2.309401 ]
[1.1547005 2.8867514 ]]
Expected Output:
>query dot key shape: (2, 2)
[[0.57735026 2.309401 ]
[1.1547005 2.8867514 ]]
masked = q_dot_k + m
display_tensor(masked, 'masked query dot key')
masked query dot key shape: (2, 2)
[[ 5.7735026e-01 2.3094010e+00]
[-1.0000000e+09 2.8867514e+00]]
Expected Output:
>masked query dot key shape: (2, 2)
[[ 5.7735026e-01 2.3094010e+00]
[-1.0000000e+09 2.8867514e+00]]
display_tensor(masked @ v, 'masked query dot key dot value')
masked query dot key dot value shape: (2, 3)
[[ 2.3094010e+00 5.7735026e-01 2.3094010e+00]
[ 2.8867514e+00 -1.0000000e+09 2.8867514e+00]]
Expected Output:
>masked query dot key dot value shape: (2, 3)
[[ 2.3094010e+00 5.7735026e-01 2.3094010e+00]
[ 2.8867514e+00 -1.0000000e+09 2.8867514e+00]]
In order to use the previous dummy tensors to test some of the graded functions, a batch dimension should be added to them so they mimic the shape of real-life examples. The mask is also replaced by a version of it that resembles the one that is used by trax:
q_with_batch = q[None,:]
display_tensor(q_with_batch, 'query with batch dim')
k_with_batch = k[None,:]
display_tensor(k_with_batch, 'key with batch dim')
v_with_batch = v[None,:]
display_tensor(v_with_batch, 'value with batch dim')
m_bool = create_tensor([[True, True], [False, True]])
display_tensor(m_bool, 'boolean mask')
query with batch dim shape: (1, 2, 3)
[[[1 0 0]
[0 1 0]]]
key with batch dim shape: (1, 2, 3)
[[[1 2 3]
[4 5 6]]]
value with batch dim shape: (1, 2, 3)
[[[0 1 0]
[1 0 1]]]
boolean mask shape: (2, 2)
[[ True True]
[False True]]
Expected Output:
>query with batch dim shape: (1, 2, 3)
[[[1 0 0]
[0 1 0]]]
key with batch dim shape: (1, 2, 3)
[[[1 2 3]
[4 5 6]]]
value with batch dim shape: (1, 2, 3)
[[[0 1 0]
[1 0 1]]]
boolean mask shape: (2, 2)
[[ True True]
[False True]]
Instructions: Implement the dot product attention. Concretely, implement the following equation
$$
\text { Attention }(Q, K, V)=\operatorname{softmax}\left(\frac{Q K^{T}}{\sqrt{d_{k}}}+{M}\right) V\tag{1}
$$
$Q$ - query, $K$ - key, $V$ - values, $M$ - mask, ${d_k}$ - depth/dimension of the queries and keys (used for scaling down)
You can implement this formula either by trax
numpy (trax.math.numpy) or regular numpy
but it is recommended to use jnp
.
Something to take into consideration is that within trax, the masks are tensors of True/False
values not 0’s and $-\infty$ as in the previous example. Within the graded function don’t think of applying the mask by summing up matrices, instead use jnp.where()
and treat the mask as a tensor of boolean values with False
for values that need to be masked and True for the ones that don’t.
Also take into account that the real tensors are far more complex than the toy ones you just played with. Because of this avoid using shortened operations such as @
for dot product or .T
for transposing. Use jnp.matmul()
and jnp.swapaxes()
instead.
This is the self-attention block for the transformer decoder. Good luck!
# UNQ_C1
# GRADED FUNCTION: DotProductAttention
def DotProductAttention(query, key, value, mask):
"""Dot product self-attention.
Args:
query (jax.interpreters.xla.DeviceArray): array of query representations with shape (L_q by d)
key (jax.interpreters.xla.DeviceArray): array of key representations with shape (L_k by d)
value (jax.interpreters.xla.DeviceArray): array of value representations with shape (L_k by d) where L_v = L_k
mask (jax.interpreters.xla.DeviceArray): attention-mask, gates attention with shape (L_q by L_k)
Returns:
jax.interpreters.xla.DeviceArray: Self-attention array for q, k, v arrays. (L_q by L_k)
"""
assert query.shape[-1] == key.shape[-1] == value.shape[-1], "Embedding dimensions of q, k, v aren't all the same"
### START CODE HERE (REPLACE INSTANCES OF 'None' WITH YOUR CODE) ###
# Save depth/dimension of the query embedding for scaling down the dot product
depth = key.shape[-1]
# Calculate scaled query key dot product according to formula above
dots = jnp.matmul(query, jnp.swapaxes(key, -1, -2)) / jnp.sqrt(depth)
# Apply the mask
if mask is not None: # You do not need to replace the 'None' on this line
dots = jnp.where(mask, dots, jnp.full_like(dots, -1e9))
# Softmax formula implementation
# Use trax.fastmath.logsumexp of masked_qkT to avoid underflow by division by large numbers
# Note: softmax = None
logsumexp = trax.fastmath.logsumexp(dots, axis = -1, keepdims = True)
# Take exponential of dots minus logsumexp to get softmax
# Use jnp.exp()
dots = jnp.exp(dots - logsumexp)
# Multiply dots by value to get self-attention
# Use jnp.matmul()
attention = jnp.matmul(dots, value)
## END CODE HERE ###
return attention
DotProductAttention(q_with_batch, k_with_batch, v_with_batch, m_bool)
DeviceArray([[[0.8496746 , 0.15032545, 0.8496746 ],
[1. , 0. , 1. ]]], dtype=float32)
Expected Output:
>DeviceArray([[[0.8496746 , 0.15032545, 0.8496746 ],
[1. , 0. , 1. ]]], dtype=float32)
# UNIT TEST
# test DotProductAttention
w2_tests.test_DotProductAttention(DotProductAttention)
[92m All tests passed
Now you are going to implement causal attention: multi-headed attention with a mask to attend only to words that occurred before.
In the image above, a word can see everything that is before it, but not what is after it. To implement causal attention, you will have to transform vectors and do many reshapes. You will need to implement the functions below.
Implement the following functions that will be needed for Causal Attention:
False
values above the diagonal and True
values below and calls DotProductAttention which implements dot product self attention.Next there are some toy tensors which may serve to give you an idea of the data shapes and opperations involved in Causal Attention. They are also useful to test out your functions!
tensor2d = create_tensor(q)
display_tensor(tensor2d, 'query matrix (2D tensor)')
tensor4d2b = create_tensor([[q, q], [q, q]])
display_tensor(tensor4d2b, 'batch of two (multi-head) collections of query matrices (4D tensor)')
tensor3dc = create_tensor([jnp.concatenate([q, q], axis = -1)])
display_tensor(tensor3dc, 'one batch of concatenated heads of query matrices (3d tensor)')
tensor3dc3b = create_tensor([jnp.concatenate([q, q], axis = -1), jnp.concatenate([q, q], axis = -1), jnp.concatenate([q, q], axis = -1)])
display_tensor(tensor3dc3b, 'three batches of concatenated heads of query matrices (3d tensor)')
query matrix (2D tensor) shape: (2, 3)
[[1 0 0]
[0 1 0]]
batch of two (multi-head) collections of query matrices (4D tensor) shape: (2, 2, 2, 3)
[[[[1 0 0]
[0 1 0]]
[[1 0 0]
[0 1 0]]]
[[[1 0 0]
[0 1 0]]
[[1 0 0]
[0 1 0]]]]
one batch of concatenated heads of query matrices (3d tensor) shape: (1, 2, 6)
[[[1 0 0 1 0 0]
[0 1 0 0 1 0]]]
three batches of concatenated heads of query matrices (3d tensor) shape: (3, 2, 6)
[[[1 0 0 1 0 0]
[0 1 0 0 1 0]]
[[1 0 0 1 0 0]
[0 1 0 0 1 0]]
[[1 0 0 1 0 0]
[0 1 0 0 1 0]]]
It is important to know that the following 3 functions would normally be defined within the CausalAttention
function further below.
However this makes these functions harder to test. Because of this, these functions are shown individually using a closure
(when necessary) that simulates them being inside of the CausalAttention
function. This is done because they rely on some variables that can be accessed from within CausalAttention
.
compute_attention_heads : Gets an input $x$ of dimension (n_batch, seqlen, n_heads $\times$ d_head) and splits the last (depth) dimension and stacks it to the zeroth dimension to allow matrix multiplication (n_batch $\times$ n_heads, seqlen, d_head).
For the closures you only have to fill the inner function.
# UNQ_C2
# GRADED FUNCTION: compute_attention_heads_closure
def compute_attention_heads_closure(n_heads, d_head):
""" Function that simulates environment inside CausalAttention function.
Args:
d_head (int): dimensionality of heads
n_heads (int): number of attention heads
Returns:
function: compute_attention_heads function
"""
def compute_attention_heads(x):
""" Compute the attention heads.
Args:
x (jax.interpreters.xla.DeviceArray): tensor with shape (n_batch, seqlen, n_heads X d_head).
Returns:
jax.interpreters.xla.DeviceArray: reshaped tensor with shape (n_batch X n_heads, seqlen, d_head).
"""
### START CODE HERE ###
# (REPLACE INSTANCES OF 'None' WITH YOUR CODE)
# Size of the x's batch dimension
batch_size = x.shape[0]
# Length of the sequence
# Should be size of x's first dimension without counting the batch dim
seqlen = x.shape[1]
# Reshape x using jnp.reshape()
# n_batch, seqlen, n_heads*d_head -> n_batch, seqlen, n_heads, d_head
x = jnp.reshape(x, (batch_size, seqlen, n_heads, d_head))
# Transpose x using jnp.transpose()
# n_batch, seqlen, n_heads, d_head -> n_batch, n_heads, seqlen, d_head
# Note that the values within the tuple are the indexes of the dimensions of x and you must rearrange them
x = jnp.transpose(x, (0, 2, 1, 3))
# Reshape x using jnp.reshape()
# n_batch, n_heads, seqlen, d_head -> n_batch*n_heads, seqlen, d_head
x = jnp.reshape(x, (batch_size * n_heads, seqlen, d_head))
### END CODE HERE ###
return x
return compute_attention_heads
display_tensor(tensor3dc3b, "input tensor")
result_cah = compute_attention_heads_closure(2,3)(tensor3dc3b)
display_tensor(result_cah, "output tensor")
input tensor shape: (3, 2, 6)
[[[1 0 0 1 0 0]
[0 1 0 0 1 0]]
[[1 0 0 1 0 0]
[0 1 0 0 1 0]]
[[1 0 0 1 0 0]
[0 1 0 0 1 0]]]
output tensor shape: (6, 2, 3)
[[[1 0 0]
[0 1 0]]
[[1 0 0]
[0 1 0]]
[[1 0 0]
[0 1 0]]
[[1 0 0]
[0 1 0]]
[[1 0 0]
[0 1 0]]
[[1 0 0]
[0 1 0]]]
Expected Output:
>input tensor shape: (3, 2, 6)
[[[1 0 0 1 0 0]
[0 1 0 0 1 0]]
[[1 0 0 1 0 0]
[0 1 0 0 1 0]]
[[1 0 0 1 0 0]
[0 1 0 0 1 0]]]
output tensor shape: (6, 2, 3)
[[[1 0 0]
[0 1 0]]
[[1 0 0]
[0 1 0]]
[[1 0 0]
[0 1 0]]
[[1 0 0]
[0 1 0]]
[[1 0 0]
[0 1 0]]
[[1 0 0]
[0 1 0]]]
# UNIT TEST
# test compute_attention_heads_closure
w2_tests.test_compute_attention_heads_closure(compute_attention_heads_closure)
[92m All tests passed
dot_product_self_attention : Creates a mask matrix with False
values above the diagonal and True
values below and calls DotProductAttention which implements dot product self attention.
# UNQ_C3
# GRADED FUNCTION: dot_product_self_attention
def dot_product_self_attention(q, k, v):
""" Masked dot product self attention.
Args:
q (jax.interpreters.xla.DeviceArray): queries.
k (jax.interpreters.xla.DeviceArray): keys.
v (jax.interpreters.xla.DeviceArray): values.
Returns:
jax.interpreters.xla.DeviceArray: masked dot product self attention tensor.
"""
### START CODE HERE (REPLACE INSTANCES OF 'None' with your code) ###
# Hint: mask size should be equal to L_q. Remember that q has shape (batch_size, L_q, d)
mask_size = q.shape[1]
# Creates a matrix with ones below the diagonal and 0s above. It should have shape (1, mask_size, mask_size)
# Notice that 1's and 0's get casted to True/False by setting dtype to jnp.bool_
# Use jnp.tril() - Lower triangle of an array and jnp.ones()
mask = jnp.tril(jnp.ones((1, mask_size, mask_size), dtype = jnp.bool_), k = 0)
### END CODE HERE ###
return DotProductAttention(q, k, v, mask)
dot_product_self_attention(q_with_batch, k_with_batch, v_with_batch)
DeviceArray([[[0. , 1. , 0. ],
[0.8496746 , 0.15032543, 0.8496746 ]]], dtype=float32)
Expected Output:
>DeviceArray([[[0. , 1. , 0. ],
[0.8496746 , 0.15032543, 0.8496746 ]]], dtype=float32)
# UNIT TEST
# test dot_product_self_attention
w2_tests.test_dot_product_self_attention(dot_product_self_attention)
[92m All tests passed
compute_attention_output : Undoes compute_attention_heads by splitting first (vertical) dimension and stacking in the last (depth) dimension (n_batch, seqlen, n_heads $\times$ d_head). These operations concatenate (stack/merge) the heads.
# UNQ_C4
# GRADED FUNCTION: compute_attention_output_closure
def compute_attention_output_closure(n_heads, d_head):
""" Function that simulates environment inside CausalAttention function.
Args:
d_head (int): dimensionality of heads
n_heads (int): number of attention heads
Returns:
function: compute_attention_output function
"""
def compute_attention_output(x):
""" Compute the attention output.
Args:
x (jax.interpreters.xla.DeviceArray): tensor with shape (n_batch X n_heads, seqlen, d_head).
Returns:
jax.interpreters.xla.DeviceArray: reshaped tensor with shape (n_batch, seqlen, n_heads X d_head).
"""
### START CODE HERE (REPLACE INSTANCES OF 'None' WITH YOUR CODE) ###
# Length of the sequence
# Should be size of x's first dimension without counting the batch dim
seqlen = x.shape[1]
# Reshape x using jnp.reshape() to shape (n_batch, n_heads, seqlen, d_head)
x = jnp.reshape(x, (-1, n_heads, seqlen, d_head))
# Transpose x using jnp.transpose() to shape (n_batch, seqlen, n_heads, d_head)
x = jnp.transpose(x, (0, 2, 1, 3))
### END CODE HERE ###
# Reshape to allow to concatenate the heads
return jnp.reshape(x, (-1, seqlen, n_heads * d_head))
return compute_attention_output
display_tensor(result_cah, "input tensor")
result_cao = compute_attention_output_closure(2,3)(result_cah)
display_tensor(result_cao, "output tensor")
input tensor shape: (6, 2, 3)
[[[1 0 0]
[0 1 0]]
[[1 0 0]
[0 1 0]]
[[1 0 0]
[0 1 0]]
[[1 0 0]
[0 1 0]]
[[1 0 0]
[0 1 0]]
[[1 0 0]
[0 1 0]]]
output tensor shape: (3, 2, 6)
[[[1 0 0 1 0 0]
[0 1 0 0 1 0]]
[[1 0 0 1 0 0]
[0 1 0 0 1 0]]
[[1 0 0 1 0 0]
[0 1 0 0 1 0]]]
Expected Output:
>input tensor shape: (6, 2, 3)
[[[1 0 0]
[0 1 0]]
[[1 0 0]
[0 1 0]]
[[1 0 0]
[0 1 0]]
[[1 0 0]
[0 1 0]]
[[1 0 0]
[0 1 0]]
[[1 0 0]
[0 1 0]]]
output tensor shape: (3, 2, 6)
[[[1 0 0 1 0 0]
[0 1 0 0 1 0]]
[[1 0 0 1 0 0]
[0 1 0 0 1 0]]
[[1 0 0 1 0 0]
[0 1 0 0 1 0]]]
# UNIT TEST
# test compute_attention_output_closure
w2_tests.test_compute_attention_output_closure(compute_attention_output_closure)
[92m All tests passed
Now it is time for you to put everything together within the CausalAttention
or Masked multi-head attention function:
Instructions: Implement the causal attention. Your model returns the causal attention through a $tl.Serial$ with the following:
d_feature
.Remember that in order for trax to properly handle the functions you just defined, they need to be added as layers using the tl.Fn()
function.
# UNQ_C5
# GRADED FUNCTION: CausalAttention
def CausalAttention(d_feature,
n_heads,
compute_attention_heads_closure=compute_attention_heads_closure,
dot_product_self_attention=dot_product_self_attention,
compute_attention_output_closure=compute_attention_output_closure,
mode='train'):
"""Transformer-style multi-headed causal attention.
Args:
d_feature (int): dimensionality of feature embedding.
n_heads (int): number of attention heads.
compute_attention_heads_closure (function): Closure around compute_attention heads.
dot_product_self_attention (function): dot_product_self_attention function.
compute_attention_output_closure (function): Closure around compute_attention_output.
mode (str): 'train' or 'eval'.
Returns:
trax.layers.combinators.Serial: Multi-headed self-attention model.
"""
assert d_feature % n_heads == 0
d_head = d_feature // n_heads
### START CODE HERE ###
# (REPLACE INSTANCES OF 'None' WITH YOUR CODE)
# HINT: The second argument to tl.Fn() is an uncalled function (without the parentheses)
# Since you are dealing with closures you might need to call the outer
# function with the correct parameters to get the actual uncalled function.
ComputeAttentionHeads = tl.Fn(
'AttnHeads',
compute_attention_heads_closure(n_heads, d_head),
n_out=1
)
return tl.Serial(
tl.Branch( # creates three towers for one input, takes activations and creates queries keys and values
[tl.Dense(d_feature), ComputeAttentionHeads], # queries
[tl.Dense(d_feature), ComputeAttentionHeads], # keys
[tl.Dense(d_feature), ComputeAttentionHeads], # values
),
tl.Fn('DotProductAttn', dot_product_self_attention, n_out=1), # takes QKV
# HINT: The second argument to tl.Fn() is an uncalled function
# Since you are dealing with closures you might need to call the outer
# function with the correct parameters to get the actual uncalled function.
tl.Fn(
'AttnOutput',
compute_attention_output_closure(n_heads, d_head),
n_out=1
), # to allow for parallel
tl.Dense(d_feature)
)
### END CODE HERE ###
# Take a look at the causal attention model
print(CausalAttention(d_feature=512, n_heads=8))
Serial[
Branch_out3[
[Dense_512, AttnHeads]
[Dense_512, AttnHeads]
[Dense_512, AttnHeads]
]
DotProductAttn_in3
AttnOutput
Dense_512
]
Expected Output:
>Serial[
Branch_out3[
[Dense_512, AttnHeads]
[Dense_512, AttnHeads]
[Dense_512, AttnHeads]
]
DotProductAttn_in3
AttnOutput
Dense_512
]
# UNIT TEST
# test CausalAttention
w2_tests.test_CausalAttention(CausalAttention)
[92m All tests passed
Now that you have implemented the causal part of the transformer, you will implement the transformer decoder block. Concretely you will be implementing this image now.
To implement this function, you will have to call the CausalAttention
or Masked multi-head attention function you implemented above. You will have to add a feedforward which consists of:
Finally once you implement the feedforward, you can go ahead and implement the entire block using:
tl.Residual : takes in the tl.LayerNorm(), causal attention block, tl.dropout.
tl.Residual : takes in the feedforward block you will implement.
Instructions: Implement the transformer decoder block. Good luck!
# UNQ_C6
# GRADED FUNCTION: DecoderBlock
def DecoderBlock(d_model, d_ff, n_heads,
dropout, mode, ff_activation):
"""Returns a list of layers that implements a Transformer decoder block.
The input is an activation tensor.
Args:
d_model (int): depth of embedding.
d_ff (int): depth of feed-forward layer.
n_heads (int): number of attention heads.
dropout (float): dropout rate (how much to drop out).
mode (str): 'train' or 'eval'.
ff_activation (function): the non-linearity in feed-forward layer.
Returns:
list: list of trax.layers.combinators.Serial that maps an activation tensor to an activation tensor.
"""
### START CODE HERE (REPLACE INSTANCES OF 'None' WITH YOUR CODE) ###
# Create masked multi-head attention block using CausalAttention function
causal_attention = CausalAttention(
d_model,
n_heads=n_heads,
mode=mode
)
# Create feed-forward block (list) with two dense layers with dropout and input normalized
feed_forward = [
# Normalize layer inputs
tl.LayerNorm(),
# Add first feed forward (dense) layer (don't forget to set the correct value for n_units)
tl.Dense(n_units = d_ff),
# Add activation function passed in as a parameter (you need to call it!)
ff_activation(), # Generally ReLU
# Add dropout with rate and mode specified (i.e., don't use dropout during evaluation)
tl.Dropout(rate = dropout, mode = mode),
# Add second feed forward layer (don't forget to set the correct value for n_units)
tl.Dense(n_units = d_model),
# Add dropout with rate and mode specified (i.e., don't use dropout during evaluation)
tl.Dropout(rate = dropout, mode = mode)
]
# Add list of two Residual blocks: the attention with normalization and dropout and feed-forward blocks
return [
tl.Residual(
# Normalize layer input
tl.LayerNorm(),
# Add causal attention block previously defined (without parentheses)
causal_attention,
# Add dropout with rate and mode specified
tl.Dropout(rate = dropout, mode = mode)
),
tl.Residual(
# Add feed forward block (without parentheses)
feed_forward
),
]
### END CODE HERE ###
# Take a look at the decoder block
print(DecoderBlock(d_model=512, d_ff=2048, n_heads=8, dropout=0.1, mode='train', ff_activation=tl.Relu))
[Serial[
Branch_out2[
None
Serial[
LayerNorm
Serial[
Branch_out3[
[Dense_512, AttnHeads]
[Dense_512, AttnHeads]
[Dense_512, AttnHeads]
]
DotProductAttn_in3
AttnOutput
Dense_512
]
Dropout
]
]
Add_in2
], Serial[
Branch_out2[
None
Serial[
LayerNorm
Dense_2048
Serial[
Relu
]
Dropout
Dense_512
Dropout
]
]
Add_in2
]]
Expected Output:
>[Serial[
Branch_out2[
None
Serial[
LayerNorm
Serial[
Branch_out3[
[Dense_512, AttnHeads]
[Dense_512, AttnHeads]
[Dense_512, AttnHeads]
]
DotProductAttn_in3
AttnOutput
Dense_512
]
Dropout
]
]
Add_in2
], Serial[
Branch_out2[
None
Serial[
LayerNorm
Dense_2048
Serial[
Relu
]
Dropout
Dense_512
Dropout
]
]
Add_in2
]]
# UNIT TEST
# test DecoderBlock
w2_tests.test_DecoderBlock(DecoderBlock)
[92m All tests passed
You will now bring it all together. In this part you will use all the subcomponents you previously built to make the final model. Concretely, here is the image you will be implementing.
Instructions: Previously you coded the decoder block. Now you will code the transformer language model. Here is what you will need.
positional_enconder - a list containing the following layers:
A list of n_layers
decoder blocks.
tl.Serial: takes in the following layers or lists of layers:
Go go go!! You can do it :)
# UNQ_C7
# GRADED FUNCTION: TransformerLM
def TransformerLM(vocab_size=33300,
d_model=512,
d_ff=2048,
n_layers=6,
n_heads=8,
dropout=0.1,
max_len=4096,
mode='train',
ff_activation=tl.Relu):
"""Returns a Transformer language model.
The input to the model is a tensor of tokens. (This model uses only the
decoder part of the overall Transformer.)
Args:
vocab_size (int): vocab size.
d_model (int): depth of embedding.
d_ff (int): depth of feed-forward layer.
n_layers (int): number of decoder layers.
n_heads (int): number of attention heads.
dropout (float): dropout rate (how much to drop out).
max_len (int): maximum symbol length for positional encoding.
mode (str): 'train', 'eval' or 'predict', predict mode is for fast inference.
ff_activation (function): the non-linearity in feed-forward layer.
Returns:
trax.layers.combinators.Serial: A Transformer language model as a layer that maps from a tensor of tokens
to activations over a vocab set.
"""
### START CODE HERE (REPLACE INSTANCES OF 'None' WITH YOUR CODE) ###
# Embedding inputs and positional encoder
positional_encoder = [
# Add embedding layer of dimension (vocab_size, d_model)
tl.Embedding(vocab_size = vocab_size, d_feature = d_model),
# Use dropout with rate and mode specified
tl.Dropout(rate = dropout, mode = mode),
# Add positional encoding layer with maximum input length and mode specified
tl.PositionalEncoding(max_len = max_len, mode = mode)
]
# Create stack (list) of decoder blocks with n_layers with necessary parameters
decoder_blocks = [
DecoderBlock(
d_model = d_model,
d_ff = d_ff,
n_heads = n_heads,
dropout = dropout,
mode = mode,
ff_activation = ff_activation
) for _ in range(n_layers)
]
# Create the complete model as written in the figure
return tl.Serial(
# Use teacher forcing (feed output of previous step to current step)
tl.ShiftRight(1), # Specify the mode!
# Add positional encoder
positional_encoder,
# Add decoder blocks
decoder_blocks,
# Normalize layer
tl.LayerNorm(),
# Add dense layer of vocab_size (since need to select a word to translate to)
# (a.k.a., logits layer. Note: activation already set by ff_activation)
tl.Dense(n_units = vocab_size),
# Get probabilities with Logsoftmax
tl.LogSoftmax()
)
### END CODE HERE ###
# Take a look at the Transformer
print(TransformerLM(n_layers=1))
Serial[
Serial[
ShiftRight(1)
]
Embedding_33300_512
Dropout
PositionalEncoding
Serial[
Branch_out2[
None
Serial[
LayerNorm
Serial[
Branch_out3[
[Dense_512, AttnHeads]
[Dense_512, AttnHeads]
[Dense_512, AttnHeads]
]
DotProductAttn_in3
AttnOutput
Dense_512
]
Dropout
]
]
Add_in2
]
Serial[
Branch_out2[
None
Serial[
LayerNorm
Dense_2048
Serial[
Relu
]
Dropout
Dense_512
Dropout
]
]
Add_in2
]
LayerNorm
Dense_33300
LogSoftmax
]
Expected Output:
>Serial[
Serial[
ShiftRight(1)
]
Embedding_33300_512
Dropout
PositionalEncoding
Serial[
Branch_out2[
None
Serial[
LayerNorm
Serial[
Branch_out3[
[Dense_512, AttnHeads]
[Dense_512, AttnHeads]
[Dense_512, AttnHeads]
]
DotProductAttn_in3
AttnOutput
Dense_512
]
Dropout
]
]
Add_in2
]
Serial[
Branch_out2[
None
Serial[
LayerNorm
Dense_2048
Serial[
Relu
]
Dropout
Dense_512
Dropout
]
]
Add_in2
]
LayerNorm
Dense_33300
LogSoftmax
]
# UNIT TEST
# test TransformerLM
w2_tests.test_TransformerLM(TransformerLM)
[92m All tests passed
Now you are going to train your model. As usual, you have to define the cost function, the optimizer, and decide whether you will be training it on a gpu
or cpu
. In this case, you will train your model on a cpu for a few steps and we will load in a pre-trained model that you can use to predict with your own words.
You will now write a function that takes in your model and trains it. To train your model you have to decide how many times you want to iterate over the entire data set. Each iteration is defined as an epoch
. For each epoch, you have to go over all the data, using your training iterator.
Instructions: Implement the train_model
program below to train the neural network above. Here is a list of things you should do:
Create the train task by calling trax.supervised.training.TrainTask
and pass in the following:
Create the eval task by calling trax.supervised.training.EvalTask
and pass in the following:
Create the training loop by calling trax.supervised.Training.Loop
and pass in the following:
You will be using a cross entropy loss, with Adam optimizer. Please read the Trax documentation to get a full understanding.
The training loop that this function returns can be runned using the run()
method by passing in the desired number of steps.
from trax.supervised import training
# UNQ_C8
# GRADED FUNCTION: train_model
def training_loop(TransformerLM, train_gen, eval_gen, output_dir = "~/model"):
'''
Input:
TransformerLM (trax.layers.combinators.Serial): The model you are building.
train_gen (generator): Training stream of data.
eval_gen (generator): Evaluation stream of data.
output_dir (str): folder to save your file.
Returns:
trax.supervised.training.Loop: Training loop.
'''
output_dir = os.path.expanduser(output_dir) # trainer is an object
lr_schedule = trax.lr.warmup_and_rsqrt_decay(n_warmup_steps=1000, max_value=0.01)
### START CODE HERE (REPLACE INSTANCES OF 'None' WITH YOUR CODE) ###
train_task = training.TrainTask(
labeled_data = train_gen, # The training generator
loss_layer = tl.CrossEntropyLoss(), # Loss function (Don't forget to instantiate!)
optimizer = trax.optimizers.Adam(learning_rate = .01), # Optimizer (Don't forget to set LR to 0.01)
lr_schedule=lr_schedule,
n_steps_per_checkpoint=10
)
eval_task = training.EvalTask(
labeled_data=eval_gen, # The evaluation generator
metrics=[tl.CrossEntropyLoss(), tl.Accuracy()] # CrossEntropyLoss and Accuracy (Don't forget to instantiate both!)
)
### END CODE HERE ###
loop = training.Loop(TransformerLM(d_model=4,
d_ff=16,
n_layers=1,
n_heads=2,
mode='train'),
train_task,
eval_tasks=[eval_task],
output_dir=output_dir)
return loop
Notice that the model will be trained for only 10 steps.
Even with this constraint the model with the original default arguments took a very long time to finish. Because of this some parameters are changed when defining the model that is fed into the training loop in the function above.
# UNIT TEST
# test training_loop
w2_tests.test_training_loop(training_loop, TransformerLM)
[92m All tests passed
# Should take around 1.5 minutes
!rm -f ~/model/model.pkl.gz
loop = training_loop(TransformerLM, train_batch_stream, eval_batch_stream)
loop.run(10)
Step 1: Total number of trainable weights: 316336
Step 1: Ran 1 train steps in 9.46 secs
Step 1: train CrossEntropyLoss | 10.41539764
Step 1: eval CrossEntropyLoss | 10.41524601
Step 1: eval Accuracy | 0.00000000
Step 10: Ran 9 train steps in 58.60 secs
Step 10: train CrossEntropyLoss | 10.41394711
Step 10: eval CrossEntropyLoss | 10.41411877
Step 10: eval Accuracy | 0.00000000
In this part you will evaluate by loading in an almost exact version of the model you coded, but we trained it for you to save you time. Please run the cell below to load in the model.
As you may have already noticed the model that you trained and the pretrained model share the same overall architecture but they have different values for some of the parameters:
Original (pretrained) model:
TransformerLM(vocab_size=33300, d_model=512, d_ff=2048, n_layers=6, n_heads=8,
dropout=0.1, max_len=4096, ff_activation=tl.Relu)
Your model:
TransformerLM(d_model=4, d_ff=16, n_layers=1, n_heads=2)
Only the parameters shown for your model were changed. The others stayed the same.
# THIS STEP COULD TAKE BETWEEN 15 SECONDS TO 15 MINUTES
# Get the model architecture
model = TransformerLM(mode='eval')
# Load the pre-trained weights
model.init_from_file('model.pkl.gz', weights_only=True)
You will now test your input. You are going to implement greedy decoding. This consists of two functions. The first one allows you to identify the next symbol. It gets the argmax of the output of your model and then returns that index.
Instructions: Implement the next symbol function that takes in the cur_output_tokens and the trained model to return the the index of the next word.
# UNQ_C9
def next_symbol(cur_output_tokens, model):
"""Returns the next symbol for a given sentence.
Args:
cur_output_tokens (list): tokenized sentence with EOS and PAD tokens at the end.
model (trax.layers.combinators.Serial): The transformer model.
Returns:
int: tokenized symbol.
"""
### START CODE HERE (REPLACE INSTANCES OF 'None' WITH YOUR CODE) ###
# current output tokens length
token_length = len(cur_output_tokens)
# calculate the minimum power of 2 big enough to store token_length
# HINT: use np.ceil() and np.log2()
# add 1 to token_length so np.log2() doesn't receive 0 when token_length is 0
padded_length = 2**int(np.ceil(np.log2(token_length + 1)))
# Fill cur_output_tokens with 0's until it reaches padded_length
padded = cur_output_tokens + [0] * (padded_length - token_length)
padded_with_batch = np.array(padded)[None, :] # Don't replace this None! This is a way of setting the batch dim
# model expects a tuple containing two padded tensors (with batch)
output, _ = model((padded_with_batch, padded_with_batch))
# HINT: output has shape (1, padded_length, vocab_size)
# To get log_probs you need to index output wih 0 in the first dim
# token_length in the second dim and all of the entries for the last dim.
log_probs = output[0, token_length, :]
### END CODE HERE ###
return int(np.argmax(log_probs))
# Test it out!
sentence_test_nxt_symbl = "I want to fly in the sky."
detokenize([next_symbol(tokenize(sentence_test_nxt_symbl)+[0], model)])
'The'
Expected Output:
>'The'
# UNIT TEST
# test next_symbol
w2_tests.test_next_symbol(next_symbol, TransformerLM)
[92m All tests passed
Now you will implement the greedy_decode algorithm that will call the next_symbol
function. It takes in the input_sentence, the trained model and returns the the decoded sentence.
Instructions: Implement the greedy_decode algorithm.
# UNQ_C10
# Decoding functions.
def greedy_decode(input_sentence, model, next_symbol=next_symbol, tokenize=tokenize, detokenize=detokenize):
"""Greedy decode function.
Args:
input_sentence (string): a sentence or article.
model (trax.layers.combinators.Serial): Transformer model.
Returns:
string: summary of the input.
"""
### START CODE HERE (REPLACE INSTANCES OF 'None' WITH YOUR CODE) ###
# Use tokenize()
cur_output_tokens = tokenize(input_sentence) + [0]
generated_output = []
cur_output = 0
EOS = 1
while cur_output != EOS:
# Get next symbol
cur_output = next_symbol(cur_output_tokens, model)
# Append next symbol to original sentence
cur_output_tokens.append(cur_output)
# Append next symbol to generated sentence
generated_output.append(cur_output)
print(detokenize(generated_output))
### END CODE HERE ###
return detokenize(generated_output)
# Test it out on a sentence!
test_sentence = "It was a sunny day when I went to the market to buy some flowers. But I only found roses, not tulips."
print(wrapper.fill(test_sentence), '\n')
print(greedy_decode(test_sentence, model))
It was a sunny day when I went to the market to buy some flowers. But
I only found roses, not tulips.
:
: I
: I just
: I just found
: I just found ros
: I just found roses
: I just found roses,
: I just found roses, not
: I just found roses, not tu
: I just found roses, not tulips
: I just found roses, not tulips
: I just found roses, not tulips.
: I just found roses, not tulips.<EOS>
: I just found roses, not tulips.<EOS>
Expected Output:
>:
: I
: I just
: I just found
: I just found ros
: I just found roses
: I just found roses,
: I just found roses, not
: I just found roses, not tu
: I just found roses, not tulips
: I just found roses, not tulips
: I just found roses, not tulips.
: I just found roses, not tulips.<EOS>
: I just found roses, not tulips.<EOS>
# Test it out with a whole article!
article = "It’s the posing craze sweeping the U.S. after being brought to fame by skier Lindsey Vonn, soccer star Omar Cummings, baseball player Albert Pujols - and even Republican politician Rick Perry. But now four students at Riverhead High School on Long Island, New York, have been suspended for dropping to a knee and taking up a prayer pose to mimic Denver Broncos quarterback Tim Tebow. Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were all suspended for one day because the ‘Tebowing’ craze was blocking the hallway and presenting a safety hazard to students. Scroll down for video. Banned: Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll (all pictured left) were all suspended for one day by Riverhead High School on Long Island, New York, for their tribute to Broncos quarterback Tim Tebow. Issue: Four of the pupils were suspended for one day because they allegedly did not heed to warnings that the 'Tebowing' craze at the school was blocking the hallway and presenting a safety hazard to students."
print(wrapper.fill(article), '\n')
print(greedy_decode(article, model))
It’s the posing craze sweeping the U.S. after being brought to fame by
skier Lindsey Vonn, soccer star Omar Cummings, baseball player Albert
Pujols - and even Republican politician Rick Perry. But now four
students at Riverhead High School on Long Island, New York, have been
suspended for dropping to a knee and taking up a prayer pose to mimic
Denver Broncos quarterback Tim Tebow. Jordan Fulcoly, Wayne Drexel,
Tyler Carroll and Connor Carroll were all suspended for one day
because the ‘Tebowing’ craze was blocking the hallway and presenting a
safety hazard to students. Scroll down for video. Banned: Jordan
Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll (all pictured
left) were all suspended for one day by Riverhead High School on Long
Island, New York, for their tribute to Broncos quarterback Tim Tebow.
Issue: Four of the pupils were suspended for one day because they
allegedly did not heed to warnings that the 'Tebowing' craze at the
school was blocking the hallway and presenting a safety hazard to
students.
Jordan
Jordan Ful
Jordan Fulcol
Jordan Fulcoly
Jordan Fulcoly,
Jordan Fulcoly, Wayne
Jordan Fulcoly, Wayne Dre
Jordan Fulcoly, Wayne Drexe
Jordan Fulcoly, Wayne Drexel
Jordan Fulcoly, Wayne Drexel,
Jordan Fulcoly, Wayne Drexel, Tyler
Jordan Fulcoly, Wayne Drexel, Tyler Carroll
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day.
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not hee
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warn
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the '
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the 'Te
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the 'Tebow
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the 'Tebowing
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the 'Tebowing'
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the 'Tebowing'
cra
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the 'Tebowing'
craze
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the 'Tebowing'
craze was
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the 'Tebowing'
craze was blocki
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the 'Tebowing'
craze was blocking
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the 'Tebowing'
craze was blocking the
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the 'Tebowing'
craze was blocking the hall
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the 'Tebowing'
craze was blocking the hallway
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the 'Tebowing'
craze was blocking the hallway and
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the 'Tebowing'
craze was blocking the hallway and presenting
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the 'Tebowing'
craze was blocking the hallway and presenting a
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the 'Tebowing'
craze was blocking the hallway and presenting a safety
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the 'Tebowing'
craze was blocking the hallway and presenting a safety hazard
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the 'Tebowing'
craze was blocking the hallway and presenting a safety hazard to
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the 'Tebowing'
craze was blocking the hallway and presenting a safety hazard to
students
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the 'Tebowing'
craze was blocking the hallway and presenting a safety hazard to
students.
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the 'Tebowing'
craze was blocking the hallway and presenting a safety hazard to
students.<EOS>
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the 'Tebowing'
craze was blocking the hallway and presenting a safety hazard to
students.<EOS>
Expected Output:
>Jordan
Jordan Ful
Jordan Fulcol
Jordan Fulcoly
Jordan Fulcoly,
Jordan Fulcoly, Wayne
Jordan Fulcoly, Wayne Dre
Jordan Fulcoly, Wayne Drexe
Jordan Fulcoly, Wayne Drexel
Jordan Fulcoly, Wayne Drexel,
.
.
.
Final summary:
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the 'Tebowing'
craze was blocking the hallway and presenting a safety hazard to
students.<EOS>
# UNIT TEST
# test greedy_decode
w2_tests.test_greedy_decode(greedy_decode)
:
: I
: I just
: I just found
: I just found ros
: I just found roses
: I just found roses,
: I just found roses, not
: I just found roses, not tu
: I just found roses, not tulips
: I just found roses, not tulips
: I just found roses, not tulips.
: I just found roses, not tulips.<EOS>
Jordan
Jordan Ful
Jordan Fulcol
Jordan Fulcoly
Jordan Fulcoly,
Jordan Fulcoly, Wayne
Jordan Fulcoly, Wayne Dre
Jordan Fulcoly, Wayne Drexe
Jordan Fulcoly, Wayne Drexel
Jordan Fulcoly, Wayne Drexel,
Jordan Fulcoly, Wayne Drexel, Tyler
Jordan Fulcoly, Wayne Drexel, Tyler Carroll
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day.
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not hee
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warn
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the '
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the 'Te
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the 'Tebow
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the 'Tebowing
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the 'Tebowing'
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the 'Tebowing'
cra
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the 'Tebowing'
craze
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the 'Tebowing'
craze was
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the 'Tebowing'
craze was blocki
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the 'Tebowing'
craze was blocking
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the 'Tebowing'
craze was blocking the
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the 'Tebowing'
craze was blocking the hall
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the 'Tebowing'
craze was blocking the hallway
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the 'Tebowing'
craze was blocking the hallway and
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the 'Tebowing'
craze was blocking the hallway and presenting
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the 'Tebowing'
craze was blocking the hallway and presenting a
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the 'Tebowing'
craze was blocking the hallway and presenting a safety
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the 'Tebowing'
craze was blocking the hallway and presenting a safety hazard
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the 'Tebowing'
craze was blocking the hallway and presenting a safety hazard to
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the 'Tebowing'
craze was blocking the hallway and presenting a safety hazard to
students
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the 'Tebowing'
craze was blocking the hallway and presenting a safety hazard to
students.
Jordan Fulcoly, Wayne Drexel, Tyler Carroll and Connor Carroll were
suspended for one day. Four students were suspended for one day
because they allegedly did not heed to warnings that the 'Tebowing'
craze was blocking the hallway and presenting a safety hazard to
students.<EOS>
[92m All tests passed
Congratulations on finishing this week’s assignment! You did a lot of work and now you should have a better understanding of the enconder part of Transformers and how Transformers can be used for text summarization.
Keep it up!