<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Divya Kamat</title>
    <description>The latest articles on DEV Community by Divya Kamat (@divyarkamat).</description>
    <link>https://dev.to/divyarkamat</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F568735%2F4d4328a1-0e3a-4ddc-be20-6ec09e563131.png</url>
      <title>DEV Community: Divya Kamat</title>
      <link>https://dev.to/divyarkamat</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/divyarkamat"/>
    <language>en</language>
    <item>
      <title>Convolutional Sequence to Sequence</title>
      <dc:creator>Divya Kamat</dc:creator>
      <pubDate>Thu, 28 Jan 2021 00:36:51 +0000</pubDate>
      <link>https://dev.to/divyarkamat/convolutional-sequence-to-sequence-4i5l</link>
      <guid>https://dev.to/divyarkamat/convolutional-sequence-to-sequence-4i5l</guid>
      <description>&lt;p&gt;Recurrent neural networks (RNNs) with LSTM or GRU units are the most prevalent tools for NLP researchers, and provide state of the art results on many different NLP tasks, including language modeling (LM), neural machine translation (NMT), sentiment analysis, and so on. However, a major drawback of RNNs is that since each word in the input sequence are processed sequentially, they are slow to train.&lt;/p&gt;

&lt;p&gt;Most recently, Convolutional Neural Networks - traditionally used in solving most of Computer Vision problem, have also found prevalence in tackling problems associated with NLP tasks like Sentence Classification, Text Classification, Sentiment Analysis, Text Summarization, Machine Translation and Answer Relations.&lt;br&gt;
Back in 2017, a team of researchers from Facebook AI research released an interesting paper about &lt;a href="https://arxiv.org/pdf/1705.03122.pdf"&gt;Sequence to Sequence learning with Convolutional neural networks(CNNs)&lt;/a&gt;, where they tried to apply CNNs to problems in Natural Language Processing. &lt;/p&gt;

&lt;p&gt;In this post, I’ll try to summarize this paper on how CNN's are being used in machine translation. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What are Convolutional Neural Networks and their effectiveness for NLP?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;br&gt;Convolutional&amp;nbsp;Neural&amp;nbsp;Networks&amp;nbsp;(CNNs)&amp;nbsp;were&amp;nbsp;originally&amp;nbsp;designed&amp;nbsp;to&amp;nbsp;perform&amp;nbsp;deep&amp;nbsp;learning&amp;nbsp;for&amp;nbsp;computer&amp;nbsp;vision&amp;nbsp;tasks,&amp;nbsp;and&amp;nbsp;have&amp;nbsp;proven&amp;nbsp;highly&amp;nbsp;effective.&amp;nbsp;They&amp;nbsp;use&amp;nbsp;the&amp;nbsp;concept&amp;nbsp;of&amp;nbsp;a&amp;nbsp;“convolution”,&amp;nbsp;a&amp;nbsp;sliding&amp;nbsp;window&amp;nbsp;or&amp;nbsp;“filter”&amp;nbsp;that&amp;nbsp;passes&amp;nbsp;over&amp;nbsp;the&amp;nbsp;image,&amp;nbsp;identifying&amp;nbsp;important&amp;nbsp;features&amp;nbsp;and&amp;nbsp;analyzing&amp;nbsp;them&amp;nbsp;one&amp;nbsp;at&amp;nbsp;a&amp;nbsp;time,&amp;nbsp;then&amp;nbsp;reducing&amp;nbsp;them&amp;nbsp;down&amp;nbsp;to&amp;nbsp;their&amp;nbsp;essential&amp;nbsp;characteristics,&amp;nbsp;and&amp;nbsp;repeating&amp;nbsp;the&amp;nbsp;process.&lt;/p&gt;

&lt;p&gt;Now,&amp;nbsp;lets&amp;nbsp;see&amp;nbsp;how&amp;nbsp;CNN&amp;nbsp;process&amp;nbsp;can&amp;nbsp;be&amp;nbsp;applied&amp;nbsp;to&amp;nbsp;NLP.&lt;/p&gt;

&lt;p&gt;Neural&amp;nbsp;networks&amp;nbsp;can&amp;nbsp;only&amp;nbsp;learn&amp;nbsp;to&amp;nbsp;find&amp;nbsp;patterns&amp;nbsp;in&amp;nbsp;numerical&amp;nbsp;data&amp;nbsp;and&amp;nbsp;so,&amp;nbsp;before&amp;nbsp;we&amp;nbsp;feed&amp;nbsp;a&amp;nbsp;text&amp;nbsp;into&amp;nbsp;a&amp;nbsp;neural&amp;nbsp;network&amp;nbsp;as&amp;nbsp;input,&amp;nbsp;we&amp;nbsp;have&amp;nbsp;to&amp;nbsp;convert&amp;nbsp;each&amp;nbsp;word&amp;nbsp;into&amp;nbsp;a&amp;nbsp;numerical&amp;nbsp;value.&amp;nbsp;It&amp;nbsp;starts&amp;nbsp;with&amp;nbsp;an&amp;nbsp;input&amp;nbsp;sentence&amp;nbsp;broken&amp;nbsp;up&amp;nbsp;into&amp;nbsp;words&amp;nbsp;and&amp;nbsp;transformed&amp;nbsp;to&amp;nbsp;word&amp;nbsp;embeddings&amp;nbsp;-&amp;nbsp;low-dimensional&amp;nbsp;representations&amp;nbsp;generated&amp;nbsp;by&amp;nbsp;models&amp;nbsp;like&amp;nbsp;word2vec&amp;nbsp;or&amp;nbsp;GloVe&amp;nbsp;or&amp;nbsp;by&amp;nbsp;using&amp;nbsp;a&amp;nbsp;custom&amp;nbsp;embedding&amp;nbsp;layer.&amp;nbsp;The&amp;nbsp;text&amp;nbsp;is&amp;nbsp;organized&amp;nbsp;into&amp;nbsp;a&amp;nbsp;matrix,&amp;nbsp;with&amp;nbsp;each&amp;nbsp;row&amp;nbsp;representing&amp;nbsp;a&amp;nbsp;word&amp;nbsp;embedding&amp;nbsp;for&amp;nbsp;the&amp;nbsp;word.&amp;nbsp;The&amp;nbsp;CNN’s&amp;nbsp;convolutional&amp;nbsp;layer&amp;nbsp;“scans”&amp;nbsp;the&amp;nbsp;text&amp;nbsp;like&amp;nbsp;it&amp;nbsp;would&amp;nbsp;an&amp;nbsp;image,&amp;nbsp;breaks&amp;nbsp;it&amp;nbsp;down&amp;nbsp;into&amp;nbsp;feature.&amp;nbsp;&lt;br&gt;The&amp;nbsp;following&amp;nbsp;image&amp;nbsp;illustrates&amp;nbsp;how&amp;nbsp;the&amp;nbsp;convolutional&amp;nbsp;“filter”&amp;nbsp;slides&amp;nbsp;over&amp;nbsp;a&amp;nbsp;sentence,&amp;nbsp;three&amp;nbsp;words&amp;nbsp;at&amp;nbsp;a&amp;nbsp;time.&amp;nbsp;This&amp;nbsp;is&amp;nbsp;called&amp;nbsp;a&amp;nbsp;1D&amp;nbsp;convolution&amp;nbsp;because&amp;nbsp;the&amp;nbsp;kernel&amp;nbsp;is&amp;nbsp;moving&amp;nbsp;in&amp;nbsp;only&amp;nbsp;one&amp;nbsp;dimension.&amp;nbsp;It&amp;nbsp;computes&amp;nbsp;an&amp;nbsp;element-wise&amp;nbsp;product&amp;nbsp;of&amp;nbsp;the&amp;nbsp;weights&amp;nbsp;of&amp;nbsp;each&amp;nbsp;word,&amp;nbsp;multiplied&amp;nbsp;by&amp;nbsp;the&amp;nbsp;weights&amp;nbsp;assigned&amp;nbsp;to&amp;nbsp;the&amp;nbsp;convolutional&amp;nbsp;filter. The&amp;nbsp;resultant&amp;nbsp;output&amp;nbsp;will&amp;nbsp;be&amp;nbsp;a&amp;nbsp;feature&amp;nbsp;vector&amp;nbsp;that&amp;nbsp;contains&amp;nbsp;about&amp;nbsp;as&amp;nbsp;many&amp;nbsp;values&amp;nbsp;as&amp;nbsp;there&amp;nbsp;were&amp;nbsp;in&amp;nbsp;input&amp;nbsp;embeddings,&amp;nbsp;so&amp;nbsp;the&amp;nbsp;input&amp;nbsp;sequence&amp;nbsp;size&amp;nbsp;does&amp;nbsp;matter.&lt;br&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VMkh6ueZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dkamatbloghome.files.wordpress.com/2021/01/download.gif" class="article-body-image-wrapper"&gt;&lt;img class="wp-image-137" src="https://res.cloudinary.com/practicaldev/image/fetch/s--VMkh6ueZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dkamatbloghome.files.wordpress.com/2021/01/download.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A&amp;nbsp;convolutional&amp;nbsp;neural&amp;nbsp;network&amp;nbsp;will&amp;nbsp;include&amp;nbsp;many&amp;nbsp;of&amp;nbsp;these&amp;nbsp;kernels&amp;nbsp;(filters),&amp;nbsp;and,&amp;nbsp;as&amp;nbsp;the&amp;nbsp;network&amp;nbsp;trains,&amp;nbsp;these&amp;nbsp;kernel&amp;nbsp;weights&amp;nbsp;are&amp;nbsp;learned.&amp;nbsp;Each&amp;nbsp;kernel&amp;nbsp;is&amp;nbsp;designed&amp;nbsp;to&amp;nbsp;look&amp;nbsp;at&amp;nbsp;a&amp;nbsp;word,&amp;nbsp;and&amp;nbsp;surrounding&amp;nbsp;word(s)&amp;nbsp;in&amp;nbsp;a&amp;nbsp;sequential&amp;nbsp;window,&amp;nbsp;and&amp;nbsp;output&amp;nbsp;a&amp;nbsp;value&amp;nbsp;that&amp;nbsp;captures&amp;nbsp;something&amp;nbsp;about&amp;nbsp;that&amp;nbsp;phrase.&amp;nbsp;In&amp;nbsp;this&amp;nbsp;way,&amp;nbsp;the&amp;nbsp;convolution&amp;nbsp;operation&amp;nbsp;can&amp;nbsp;be&amp;nbsp;viewed&amp;nbsp;as&amp;nbsp;window-based&amp;nbsp;feature&amp;nbsp;extraction.&lt;/p&gt;

&lt;p&gt;&lt;br&gt;We'll&amp;nbsp;be&amp;nbsp;building&amp;nbsp;a&amp;nbsp;machine&amp;nbsp;learning&amp;nbsp;model&amp;nbsp;to&amp;nbsp;go&amp;nbsp;from&amp;nbsp;once&amp;nbsp;sequence&amp;nbsp;to&amp;nbsp;another,&amp;nbsp;using&amp;nbsp;PyTorch&amp;nbsp;and&amp;nbsp;TorchText.&amp;nbsp;This&amp;nbsp;will&amp;nbsp;be&amp;nbsp;done&amp;nbsp;on&amp;nbsp;German&amp;nbsp;to&amp;nbsp;English&amp;nbsp;translations,&amp;nbsp;but&amp;nbsp;the&amp;nbsp;models&amp;nbsp;can&amp;nbsp;be&amp;nbsp;applied&amp;nbsp;to&amp;nbsp;any&amp;nbsp;problem&amp;nbsp;that&amp;nbsp;involves&amp;nbsp;going&amp;nbsp;from&amp;nbsp;one&amp;nbsp;sequence&amp;nbsp;to&amp;nbsp;another,&amp;nbsp;such&amp;nbsp;as&amp;nbsp;summarization,&amp;nbsp;i.e.&amp;nbsp;going&amp;nbsp;from&amp;nbsp;a&amp;nbsp;sequence&amp;nbsp;to&amp;nbsp;a&amp;nbsp;shorter&amp;nbsp;sequence&amp;nbsp;in&amp;nbsp;the&amp;nbsp;same&amp;nbsp;language.&lt;br&gt;Before&amp;nbsp;we&amp;nbsp;delve&amp;nbsp;deep&amp;nbsp;into&amp;nbsp;the&amp;nbsp;code,&amp;nbsp;lets&amp;nbsp;first&amp;nbsp;understand&amp;nbsp;the&amp;nbsp;model&amp;nbsp;architecture&amp;nbsp;as&amp;nbsp;mentioned&amp;nbsp;in&amp;nbsp;the&amp;nbsp;paper.&lt;br&gt;Lets&amp;nbsp;recall&amp;nbsp;our&amp;nbsp;general&amp;nbsp;RNN&amp;nbsp;based&amp;nbsp;encoder&amp;nbsp;decoder&amp;nbsp;model,&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&lt;br&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RJVdT0Ce--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dkamatbloghome.files.wordpress.com/2021/01/seq2seq1.png" class="article-body-image-wrapper"&gt;&lt;img class="wp-image-141" src="https://res.cloudinary.com/practicaldev/image/fetch/s--RJVdT0Ce--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dkamatbloghome.files.wordpress.com/2021/01/seq2seq1.png" alt=""&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;We&amp;nbsp;use&amp;nbsp;our&amp;nbsp;encoder&amp;nbsp;(green)&amp;nbsp;over&amp;nbsp;the&amp;nbsp;embedded&amp;nbsp;source&amp;nbsp;sequence&amp;nbsp;(yellow)&amp;nbsp;to&amp;nbsp;create&amp;nbsp;a&amp;nbsp;context&amp;nbsp;vector&amp;nbsp;(red).&amp;nbsp;We&amp;nbsp;then&amp;nbsp;use&amp;nbsp;that&amp;nbsp;context&amp;nbsp;vector&amp;nbsp;with&amp;nbsp;the&amp;nbsp;decoder&amp;nbsp;(blue)&amp;nbsp;and&amp;nbsp;a&amp;nbsp;linear&amp;nbsp;layer&amp;nbsp;(purple)&amp;nbsp;to&amp;nbsp;generate&amp;nbsp;the&amp;nbsp;target&amp;nbsp;sentence.&lt;/p&gt;

&lt;h2&gt;How&amp;nbsp;convolutional&amp;nbsp;sequence&amp;nbsp;to&amp;nbsp;sequence&amp;nbsp;model&amp;nbsp;work?&lt;/h2&gt;

&lt;p&gt;An&amp;nbsp;architecture&amp;nbsp;proposed&amp;nbsp;by&amp;nbsp;authors&amp;nbsp;for&amp;nbsp;sequence&amp;nbsp;to&amp;nbsp;sequence modeling&amp;nbsp;is&amp;nbsp;entirely&amp;nbsp;convolutional. Below&amp;nbsp;diagram&amp;nbsp;outlines&amp;nbsp;the&amp;nbsp;structure&amp;nbsp;of&amp;nbsp;convolutional&amp;nbsp;sequence&amp;nbsp;to&amp;nbsp;sequence&amp;nbsp;model.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YWe4i4aq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dkamatbloghome.files.wordpress.com/2021/01/convseq2seq0.png" class="article-body-image-wrapper"&gt;&lt;img class="wp-image-142" src="https://res.cloudinary.com/practicaldev/image/fetch/s--YWe4i4aq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dkamatbloghome.files.wordpress.com/2021/01/convseq2seq0.png" alt=""&gt;&lt;/a&gt;&lt;br&gt;Like&amp;nbsp;any&amp;nbsp;RNN&amp;nbsp;based&amp;nbsp;sequence&amp;nbsp;to&amp;nbsp;sequence&amp;nbsp;structure&amp;nbsp;CNN&amp;nbsp;based&amp;nbsp;model&amp;nbsp;uses&amp;nbsp;encoder&amp;nbsp;decoder&amp;nbsp;architecture,&amp;nbsp;however&amp;nbsp;here&amp;nbsp;both&amp;nbsp;encoder&amp;nbsp;and&amp;nbsp;decoder&amp;nbsp;are&amp;nbsp;composed&amp;nbsp;of&amp;nbsp;stacked&amp;nbsp;convolutional&amp;nbsp;layers&amp;nbsp;with&amp;nbsp;a&amp;nbsp;special&amp;nbsp;type&amp;nbsp;of&amp;nbsp;activation&amp;nbsp;function&amp;nbsp;called&amp;nbsp;Gated&amp;nbsp;Linear&amp;nbsp;Units.&amp;nbsp;In&amp;nbsp;the&amp;nbsp;middle&amp;nbsp;there&amp;nbsp;is&amp;nbsp;a&amp;nbsp;attention&amp;nbsp;function.&amp;nbsp;The&amp;nbsp;encoder&amp;nbsp;extracts&amp;nbsp;features&amp;nbsp;from&amp;nbsp;the&amp;nbsp;source&amp;nbsp;sequence,&amp;nbsp;while&amp;nbsp;decoder&amp;nbsp;learns&amp;nbsp;to&amp;nbsp;estimate&amp;nbsp;the&amp;nbsp;function&amp;nbsp;that&amp;nbsp;maps&amp;nbsp;the&amp;nbsp;encoders&amp;nbsp;hidden&amp;nbsp;state&amp;nbsp;and&amp;nbsp;its&amp;nbsp;previous&amp;nbsp;generated&amp;nbsp;words&amp;nbsp;to&amp;nbsp;the&amp;nbsp;next&amp;nbsp;word.&amp;nbsp;The&amp;nbsp;attention&amp;nbsp;tells&amp;nbsp;the&amp;nbsp;decoder&amp;nbsp;which&amp;nbsp;hidden&amp;nbsp;states&amp;nbsp;of&amp;nbsp;the&amp;nbsp;encoder&amp;nbsp;to&amp;nbsp;focus&amp;nbsp;on.&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;br&gt;A&amp;nbsp;concept&amp;nbsp;of&amp;nbsp;&lt;strong&gt;positional&amp;nbsp;embedding&lt;/strong&gt;,&amp;nbsp;is&amp;nbsp;been&amp;nbsp;introduced&amp;nbsp;in&amp;nbsp;this&amp;nbsp;model.&amp;nbsp;Well,&amp;nbsp;what&amp;nbsp;do&amp;nbsp;we&amp;nbsp;mean&amp;nbsp;by&amp;nbsp;positional&amp;nbsp;embedding?&lt;br&gt;In&amp;nbsp;CNN,&amp;nbsp;we&amp;nbsp;process&amp;nbsp;all&amp;nbsp;the&amp;nbsp;words&amp;nbsp;in&amp;nbsp;a&amp;nbsp;sequence&amp;nbsp;simultaneously,&amp;nbsp;it&amp;nbsp;is&amp;nbsp;impossible&amp;nbsp;to&amp;nbsp;capture&amp;nbsp;the&amp;nbsp;sequence&amp;nbsp;order&amp;nbsp;information&amp;nbsp;like&amp;nbsp;we&amp;nbsp;do&amp;nbsp;in&amp;nbsp;RNNs&amp;nbsp;(a&amp;nbsp;timeseries&amp;nbsp;based&amp;nbsp;model).&amp;nbsp;In&amp;nbsp;order&amp;nbsp;to&amp;nbsp;use&amp;nbsp;the&amp;nbsp;sequence&amp;nbsp;information&amp;nbsp;of&amp;nbsp;the&amp;nbsp;sequence,&amp;nbsp;the&amp;nbsp;absolute&amp;nbsp;position&amp;nbsp;information&amp;nbsp;of&amp;nbsp;the&amp;nbsp;tokens&amp;nbsp;needs&amp;nbsp;to&amp;nbsp;be&amp;nbsp;injected&amp;nbsp;into&amp;nbsp;the&amp;nbsp;model&amp;nbsp;and&amp;nbsp;we&amp;nbsp;need&amp;nbsp;to&amp;nbsp;explicity&amp;nbsp;sent&amp;nbsp;this&amp;nbsp;information&amp;nbsp;to&amp;nbsp;the&amp;nbsp;network.&amp;nbsp;&amp;nbsp;This&amp;nbsp;works&amp;nbsp;just&amp;nbsp;like&amp;nbsp;a&amp;nbsp;regular&amp;nbsp;word&amp;nbsp;embedding&amp;nbsp;but&amp;nbsp;instead&amp;nbsp;of&amp;nbsp;mapping&amp;nbsp;words,&amp;nbsp;it&amp;nbsp;maps&amp;nbsp;the&amp;nbsp;absolute&amp;nbsp;position&amp;nbsp;of&amp;nbsp;a&amp;nbsp;word&amp;nbsp;to&amp;nbsp;a&amp;nbsp;dense&amp;nbsp;vector.&amp;nbsp;The&amp;nbsp;position&amp;nbsp;embeding&amp;nbsp;output&amp;nbsp;will&amp;nbsp;be&amp;nbsp;added&amp;nbsp;on&amp;nbsp;the&amp;nbsp;word&amp;nbsp;embeding.&amp;nbsp;With&amp;nbsp;this&amp;nbsp;additional&amp;nbsp;information,&amp;nbsp;the&amp;nbsp;model&amp;nbsp;knows&amp;nbsp;which&amp;nbsp;part&amp;nbsp;of&amp;nbsp;the&amp;nbsp;context&amp;nbsp;it&amp;nbsp;is&amp;nbsp;handling.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--os_Iq3T7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dkamatbloghome.files.wordpress.com/2021/01/positional_emb.png" class="article-body-image-wrapper"&gt;&lt;img class="wp-image-144" src="https://res.cloudinary.com/practicaldev/image/fetch/s--os_Iq3T7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dkamatbloghome.files.wordpress.com/2021/01/positional_emb.png" alt=""&gt;&lt;/a&gt;&lt;br&gt;The&amp;nbsp;paper&amp;nbsp;also&amp;nbsp;applies&amp;nbsp;residual&amp;nbsp;connection&amp;nbsp;between&amp;nbsp;the&amp;nbsp;blocks&amp;nbsp;in&amp;nbsp;both&amp;nbsp;the&amp;nbsp;encoder&amp;nbsp;and&amp;nbsp;the&amp;nbsp;decoder,&amp;nbsp;which&amp;nbsp;allows&amp;nbsp;for&amp;nbsp;deeper&amp;nbsp;convolutional&amp;nbsp;network.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&lt;br&gt;&lt;strong&gt;&lt;em&gt;Why&amp;nbsp;residual&amp;nbsp;connection?&lt;br&gt;&lt;/em&gt;&lt;/strong&gt;Models&amp;nbsp;with&amp;nbsp;many&amp;nbsp;layers&amp;nbsp;often&amp;nbsp;rely&amp;nbsp;on&amp;nbsp;shortcut&amp;nbsp;or&amp;nbsp;residual&amp;nbsp;connections.&amp;nbsp;When&amp;nbsp;we&amp;nbsp;stack&amp;nbsp;up&amp;nbsp;convolutional&amp;nbsp;layers&amp;nbsp;to&amp;nbsp;form&amp;nbsp;a&amp;nbsp;deeper&amp;nbsp;model,&amp;nbsp;it&amp;nbsp;becomes&amp;nbsp;harder&amp;nbsp;and&amp;nbsp;harder&amp;nbsp;to&amp;nbsp;optimize&amp;nbsp;since&amp;nbsp;the&amp;nbsp;model&amp;nbsp;has&amp;nbsp;a&amp;nbsp;lot&amp;nbsp;of&amp;nbsp;parameters,&amp;nbsp;resulting&amp;nbsp;in&amp;nbsp;poor&amp;nbsp;performance&amp;nbsp;and&amp;nbsp;also&amp;nbsp;the&amp;nbsp;gradient&amp;nbsp;values&amp;nbsp;start&amp;nbsp;exploding&amp;nbsp;and&amp;nbsp;becomes&amp;nbsp;very&amp;nbsp;difficult&amp;nbsp;to&amp;nbsp;handle.&amp;nbsp;This&amp;nbsp;is&amp;nbsp;solved&amp;nbsp;by&amp;nbsp;adding&amp;nbsp;a&amp;nbsp;residual&amp;nbsp;block&amp;nbsp;(skip&amp;nbsp;connections)&amp;nbsp;i.e&amp;nbsp;to&amp;nbsp;add&amp;nbsp;the&amp;nbsp;previous&amp;nbsp;blocks&amp;nbsp;output&amp;nbsp;onto&amp;nbsp;the&amp;nbsp;current&amp;nbsp;block&amp;nbsp;directly.&amp;nbsp;This&amp;nbsp;technique&amp;nbsp;makes&amp;nbsp;the&amp;nbsp;learning&amp;nbsp;process&amp;nbsp;easier&amp;nbsp;and&amp;nbsp;faster,&amp;nbsp;enabling&amp;nbsp;the&amp;nbsp;model&amp;nbsp;to&amp;nbsp;go&amp;nbsp;deeper,&amp;nbsp;also&amp;nbsp;helps&amp;nbsp;improve&amp;nbsp;the&amp;nbsp;accuracy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Encoder
&lt;/h2&gt;

&lt;p&gt;Let's now have a closer look at the Encoder structure.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lHB9KuYp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/bentrevett/pytorch-seq2seq/raw/9479fcb532214ad26fd4bda9fcf081a05e1aaf4e/assets/convseq2seq1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lHB9KuYp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://github.com/bentrevett/pytorch-seq2seq/raw/9479fcb532214ad26fd4bda9fcf081a05e1aaf4e/assets/convseq2seq1.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We take the German sentence add padding at the start  and end of the sentence  and split those into tokens. This is because, the CNN layer is going to reduce the length of the sentence, to maintain same sentence length we add padding.&lt;/li&gt;
&lt;li&gt;We first send it to the embeding layer to get the word embedding, we also need to encode the position of the word, so we will be literally sending the position(index postion of the words) to another similar embeding layer to get the positional embeddings. &lt;/li&gt;
&lt;li&gt;We then do a element wise sum of word embedding and postional embedding, that is going to result in a combined embedding which is a element wise vector (This layer knowns the word and also has encoded even the location of the word) .&lt;/li&gt;
&lt;li&gt;This vector goes into a Fully connected layer because we need to convert it into a particular dimention and also, to help increase capacity and extract information, basically to convert these simple numbers into something which is more complex (like rearranging of features).&lt;/li&gt;
&lt;li&gt;The ouput of each of these FC layer is simultaneously sent to the multiple convolution blocks.&lt;/li&gt;
&lt;li&gt;For each of the information that is going into the convolutional block, we are going to get individual outputs.&lt;/li&gt;
&lt;li&gt;This output is again sent to another fully connected layer, because the output of the convolution need to be converted into the embedding dimension of the encoder.&lt;/li&gt;
&lt;li&gt;The final vector will have the embedding equal to the number of dimension we want.&lt;/li&gt;
&lt;li&gt;We also add a skip connection the output of the final FC layer gets added with the element wise sum of word and position embeding , i.e we are sending the whole word along with the position of the word to the decoder as convolutional layer might loose the positional information.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Finally, from the encoder block we will be sending two outputs to the decoder, one is the conved output and another is combined vector (which is combination of transformed vector and embedding vector)&lt;br&gt;
i.e suppose we have 6 tokens, we will be getting 12 context vectors, 2 context vectors per token, one from conved and another from combined. &lt;/p&gt;

&lt;h2&gt;
  
  
  Convolutional Blocks
&lt;/h2&gt;

&lt;p&gt;Lets now see the convolutional block within encoder architecture&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HPLz8Ya---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/bentrevett/pytorch-seq2seq/9479fcb532214ad26fd4bda9fcf081a05e1aaf4e/assets/convseq2seq2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HPLz8Ya---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/bentrevett/pytorch-seq2seq/9479fcb532214ad26fd4bda9fcf081a05e1aaf4e/assets/convseq2seq2.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;As mentioned earlier we pass the padded input sentence to the CNN block, this is because the CNN layer is going to reduce the length of the sentence, and we need to ensure that the length of the input sentence getting into the convolution block is equal to the length of the sentence going out of the convolution block.&lt;/li&gt;
&lt;li&gt;We will be then convolving the padded output using a kernel size of 3 (odd size)&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The output of this is sent to a special kind of acivation GLU (Gated Linear Unit) activation.&lt;/p&gt;
&lt;h3&gt;
  
  
  How GLU activation works?
&lt;/h3&gt;

&lt;p&gt;The output of convolutional layer i.e input to GLU is split into two halves A and B, half the input (A) would go to sigmoid and we would then do a element wise sum of both. Sigmoid acts as a gate, determining which part of B are relevant to the current context. The larger the values of entry in A the more important that corresponding entry in B is. The gating mechanisn of the models enables to select the effective parts of the input features in preducting the next words. Since the GLU is going to reduce the input to half, we would be doubling the input to the convolution block.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7gU71Zuq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://drive.google.com/uc%3Fexport%3Dview%26id%3D1Uu_ZOvkISyBdB517Ik-FFNebBJeVWItQ" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7gU71Zuq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://drive.google.com/uc%3Fexport%3Dview%26id%3D1Uu_ZOvkISyBdB517Ik-FFNebBJeVWItQ" alt="GLU.PNG"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Then we add a residual connection i.e The output of the combined vector is going to be added as a skip connection to the output of the GLU, this done just to avoid any issues associated with the convolutional layers, this skip connections ensures smooth flow of gradients&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This concludes a single convolutional block. Subsequent blocks take the output of the previous block and perform the same steps. Each block has their own parameters, they are not shared between blocks. The output of the last block goes back to the main encoder - where it is fed through a linear layer to get the conved output and then elementwise summed with the embedding of the token to get the combined output.&lt;/p&gt;

&lt;h2&gt;
  
  
  Decoder
&lt;/h2&gt;

&lt;p&gt;The Decoder is very similar to Encoder, but with few changes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CAv8r_Qm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/bentrevett/pytorch-seq2seq/9479fcb532214ad26fd4bda9fcf081a05e1aaf4e/assets/convseq2seq3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CAv8r_Qm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/bentrevett/pytorch-seq2seq/9479fcb532214ad26fd4bda9fcf081a05e1aaf4e/assets/convseq2seq3.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We will passing the whole output for the prediction, like encoder we will first pass the tokens to the embeding layer to get the word and postional embedding.&lt;/li&gt;
&lt;li&gt;Add both the word and postional embedding using element wise sum, pass it to the fully connected layer, which then goes to the convolutional layer.&lt;/li&gt;
&lt;li&gt;The convolutional layer accepts two additional inputs i.e the encoder conved and encoder combined (this is to feed encoder information into the decoder), we also pass the embedding vector as a residual connection to the convolution layer. Unlike the encoder, the resnet connection or skip connection goes only to the convolution block it doesnot go to the output of the convolution block because we have to use the information to predict the output.&lt;/li&gt;
&lt;li&gt;This goes to two layer linear network (FC layer) to make the final prediction.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Decoder Conv Blocks
&lt;/h2&gt;

&lt;p&gt;Let's now see the decoder convolutional blocks, this is similar to the one within encoder. However there are few changes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gLQk8K4r--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/bentrevett/pytorch-seq2seq/9479fcb532214ad26fd4bda9fcf081a05e1aaf4e/assets/convseq2seq4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gLQk8K4r--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/bentrevett/pytorch-seq2seq/9479fcb532214ad26fd4bda9fcf081a05e1aaf4e/assets/convseq2seq4.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For encoder the input sequence is padded so that the input and output lengths are the same and we would pad the target sentence in the decoder aswell for the same reason. However, for decoder we only pad at the beginning of the sentence, the padding makes sure the target of the decoder is shifted by one word from its input. Since we are processing all the target sequence simultaneously, so we need a method of not only allowing the filter to translate the token that we have to the next stage, but we also need to make sure that the model will not learn to output the next word in the sequence by directly copying the next word, without actually learning how to translate. &lt;/p&gt;

&lt;p&gt;If we don't pad it at the beginning (as shown below), then the model will see the next word while convolving and would literally be copying that to the output, without learning to translate&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RRrklNTV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/bentrevett/pytorch-seq2seq/9479fcb532214ad26fd4bda9fcf081a05e1aaf4e/assets/convseq2seq5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RRrklNTV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/bentrevett/pytorch-seq2seq/9479fcb532214ad26fd4bda9fcf081a05e1aaf4e/assets/convseq2seq5.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Attention
&lt;/h2&gt;

&lt;p&gt;The model also adds a attention in every decoder layer and demonstrate that each attention layer only adds a negligible amount of overhead.The model uses both encoder conved and encoder combined, to figure out where exactly the encoder want the model to focus on while making the prediction&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Firstly, we take the conved output of a word from the decoder, do a element wise sum with the decoder input embedding to generate combined embedding&lt;/li&gt;
&lt;li&gt;Next, we calculate the attention between the above generated combined embedding and the encoder conved, to find how much it matches with the encoded conved &lt;/li&gt;
&lt;li&gt;Then, this is used to calculate the weighted sum over the encoded combined to apply the attention.&lt;/li&gt;
&lt;li&gt;This is then projected back up to the hidden dimenson size and a residual connection to the initial input is applied to the attention layer.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This can be seen as attention with multiple ’hops’ compared to single step attention&lt;/p&gt;

&lt;h2&gt;
  
  
  Seq2Seq
&lt;/h2&gt;

&lt;p&gt;For the final part of the implementation, we'll implement the seq2seq model. This will stitch the Encoder and Decoder together:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Firstly  token is sliced off from the target sentence as we do not input this token to the decoder.&lt;/li&gt;
&lt;li&gt;The encoder receives the input/source sentence and produces two context vectors for each word:

&lt;ul&gt;
&lt;li&gt;encoder_conved (output from final encoder conv. block) and &lt;/li&gt;
&lt;li&gt;encoder_combined [encoder_conved plus (elementwise) src embedding plus positional embeddings]&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;The decoder takes in all the target sentence at one to produce the prediction of output/target sentence&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Inference
&lt;/h2&gt;

&lt;p&gt;Following are the steps that we taken during inference:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Firstly, ensure our model is in evaluation mode, which it should "always" be for inference&lt;/li&gt;
&lt;li&gt;When a new unseen sentence is passed, we first convert that to lower case and tokenize the sentence&lt;/li&gt;
&lt;li&gt;append the &amp;lt;sos&amp;gt; and &amp;lt;eos&amp;gt; tokens&lt;/li&gt;
&lt;li&gt;map the tokens to their indexes i.e corresponding integer representation fron vocab&lt;/li&gt;
&lt;li&gt;convert it to a tensor and use unsqueeze operation to add a batch dimension&lt;/li&gt;
&lt;li&gt;feed the source sentence into the encoder using torch.no_grad() block to ensure no gradients are calculated within the block to reduce memory consumption and speed things up.&lt;/li&gt;
&lt;li&gt;create a list to hold the output sentence, initialized with an &amp;lt;sos&amp;gt; token&lt;/li&gt;
&lt;li&gt;while we have not hit a maximum length

&lt;ul&gt;
&lt;li&gt;convert the current output sentence prediction into a tensor with a batch dimension&lt;/li&gt;
&lt;li&gt;place the current output and the two encoder outputs into the decoder&lt;/li&gt;
&lt;li&gt;get next output token prediction from decoder&lt;/li&gt;
&lt;li&gt;add prediction to current output sentence prediction&lt;/li&gt;
&lt;li&gt;break if the prediction was an  token&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;convert the output sentence from indexes to tokens&lt;/li&gt;
&lt;li&gt;return the output sentence (with the  token removed) and the attention from the last layer&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Compared to RNN models convolution models have two advantages. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First, it runs faster because convolution can be performed in parallel. By contrast, RNN needs to wait for the value of the previous timesteps to be computed.&lt;/li&gt;
&lt;li&gt;Second, it captures dependencies of different lengths between the words easily. In a group of stacked CNN layers, the bottom layers captures closer dependencies while the top layers extract longer (complex) dependencies  between words.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Having said that when comparing RNN vs CNN, both are commonplace in the field of Deep Learning. Each architecture has advantages and disadvantages that are dependent upon the type of data that is being modeled.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;From the abstract of the paper, the authors claim to outperform the accuracy of deep LSTMs in WMT’14 English-German and WMT’14 English-French translation at an order of magnitude faster speed, both on GPU and CPU&lt;/em&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Pytorch implementation to this can be found &lt;a href="https://github.com/divya-r-kamat/NLP-With-PyTorch/blob/master/Convolutional_Sequence_to_Sequence/German_to_English_Translation_using_Convolutional_Seq2Seq.ipynb"&gt;here&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
