text: # AUTOGENERATED! DO NOT EDIT! File to edit: 01_model.ipynb (unless otherwise specified).
  
  __all__ = ['get_dls', 'get_glove_embeddings', 'get_my_vocab', 'convert_cnt_to_glove_emb', 'MatchPyramid']
  
  # Cell
  import torchtext
  
  from inspect import signature
  from fastai.text.all import *
  from sklearn.feature_extraction.text import CountVectorizer
  
  from .data import *
  
  
  # Cell
  def get_dls():
      train       = load_dataset()
      splits      = IndexSplitter(np.arange(len(train)-int(.2 * len(train)), len(train)))(train)
  
      combined_df = pd.DataFrame({'text': list(train.iloc[splits[0]]['question1'].unique()) + list(train.iloc[splits[0]]['question2'].unique())})
      _, cnt      = tokenize_df(combined_df, text_cols='text')
      dset = Datasets(train, [[Tokenizer.from_df('question1', tok_text_col='q1'), Tokenizer.from_df('question2', tok_text_col='q2'),
                            NumericalizePair(vocab=list(cnt.keys()))], [ItemGetter('is_duplicate'), Categorize()]], splits=splits)
      seq_len    = 72
      dls_kwargs = {
                    'before_batch': Pad_Chunk_Pair(seq_len=seq_len),
                    'after_batch': Undict(),
                    'create_batch': fa_convert
                   }
  
      dls        = dset.dataloaders(bs=128, seq_len=seq_len, **dls_kwargs)
      return dls, cnt
  
  # Cell
  def get_glove_embeddings():
      return torchtext.vocab.GloVe(name = '6B', dim = 100)
  
  # Cell
  def get_my_vocab(cnt):
      return torchtext.vocab.vocab(cnt, min_freq=1)
  
  # Cell
  def convert_cnt_to_glove_emb(my_vocab):
      return glove.get_vecs_by_tokens(my_vocab.get_itos())
  
  # Cell
  class MatchPyramid(Module):
  
      def __init__(self, vocab, max_len):
          vocab_size, emb_size = vocab.vectors.shape
          self.max_len = max_len
          self.emb = nn.Embedding(vocab_size, emb_size, _weight=vocab.vectors)
  
          self.conv1 = nn.Conv2d(in_channels=1,
                                 out_channels=8,
                                 kernel_size=(3, 3),
                                 padding=0,
                                   bias=True
                                   )
  
          self.conv2 = torch.nn.Conv2d(in_channels=8,
                                       out_channels=16,
                                       kernel_size=(3, 3),
                                       padding=0,
                                       bias=True
                                       )
  
          self.pool1 = torch.nn.AdaptiveMaxPool2d(10)
          self.pool2 = torch.nn.AdaptiveMaxPool2d(5)
          self.linear1 = torch.nn.Linear(5 * 5 * 16,
                                         128,
                                         bias=True
                                        )
  
          self.linear2 = torch.nn.Linear(128, 1, bias=True)
          self.relu    = nn.ReLU()
  
      def forward(self, xa, xb):
          seq_len1, seq_len2 = xa.size()[1], xb.size()[1]
  
          emb_a, emb_b = self.emb(xa), self.emb(xb)
          pad1         = self.max_len - seq_len1
          pad2         = self.max_len - seq_len2
          simi_img     = torch.matmul(emb_a, emb_b.transpose(1, 2)) / np.sqrt(emb_a.size()[2])
  
          simi_img = simi_img.unsqueeze(1)
  
          if pad1 != 0 or pad2 != 0:
              simi_img = F.pad(simi_img, (0, pad2, 0, pad1))
  
          simi_img = self.relu(self.conv1(simi_img))
          simi_img = self.pool1(simi_img)
          simi_img = self.relu(self.conv2(simi_img))
          simi_img = self.pool2(simi_img)
  
          simi_img = simi_img.squeeze(1).view(xa.size()[0], -1)
  
          output = self.linear2(F.relu(self.linear1(simi_img)))
  
          return output