def test_reduce_prod(self, some_seq_batch):
     result = SequenceBatch.reduce_prod(some_seq_batch)
     assert_tensor_equal(result, [
         [4, 10],
         [0, 4],
         [1, 1]
     ])
    def test_embed(self):
        sequences = [
            [],
            [1, 2, 3],
            [3, 3],
            [2]
        ]

        vocab = SimpleVocab([0, 1, 2, 3, 4])
        indices = SequenceBatch.from_sequences(sequences, vocab)

        embeds = GPUVariable(torch.FloatTensor([
            [0, 0],
            [2, 2],   # 1
            [3, 4],   # 2
            [-10, 1], # 3
            [11, -1]  # 4
        ]))

        embedded = SequenceBatch.embed(indices, embeds)

        correct = np.array([
            [[0, 0], [0, 0], [0, 0]],
            [[2, 2], [3, 4], [-10, 1]],
            [[-10, 1], [-10, 1], [0, 0]],
            [[3, 4], [0, 0], [0, 0]]
        ], dtype=np.float32)
        assert_tensor_equal(embedded.values, correct)
Example #3
0
    def test_embed_indices(self, embedder):
        indices = GPUVariable(torch.LongTensor([
            [0, 1],
            [2, 2],
            [4, 5],
        ]))

        embeds = embedder.embed_indices(indices)

        assert_tensor_equal(embeds, [
            [[1, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0]],
            [[0, 0, 1, 0, 0, 0], [0, 0, 1, 0, 0, 0]],
            [[0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 1]],
        ])

        indices = GPUVariable(
            torch.LongTensor([
                [[0, 1], [1, 0]],
                [[2, 2], [3, 2]],
            ]))

        embeds = embedder.embed_indices(indices)
        assert_tensor_equal(embeds, [
            [[[1, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0]],
             [[0, 1, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0]]],
            [[[0, 0, 1, 0, 0, 0], [0, 0, 1, 0, 0, 0]],
             [[0, 0, 0, 1, 0, 0], [0, 0, 1, 0, 0, 0]]],
        ])
Example #4
0
    def multi_vocab_indices(self, sequences, vocabs, min_seq_length=0):
        """Convert a batch of sequences into indices, where each token is converted into a **tuple** of indices.

        Args:
            sequences (list[list[unicode]]): a batch of sequences
            vocabs (list[list[Vocab]]): vocabs[v] = a batch of vocabs (one per example in the batch), corresponding to vocab v
            min_seq_length (int): see SequenceBatch.from_sequences
        
        Returns:
            SequenceBatch:
                mask (Variable): has shape (batch_size, seq_length)
                values (Variable): has shape (batch_size, seq_length, num_vocabs)
        """
        seq_batches = [
            SequenceBatch.from_sequences(sequences, vocabs_v, min_seq_length)
            for vocabs_v in vocabs
        ]
        values_list, mask_list = zip(*seq_batches)

        for mask in mask_list:
            assert_tensor_equal(mask,
                                mask_list[0])  # all masks should be the same

        values = torch.stack(values_list, 2)

        return SequenceBatch(values, mask_list[0])
Example #5
0
    def test_transfer_copy_probs(self):

        # not actual probs, but that's ok
        probs = torch.FloatTensor([
            # special base    copy
            [1, 2, 3, 10, 11, 12, 14, 16],
            [4, 5, 6, 20, 21, 22, 24, 26],
        ])

        base_vocab = HardCopyVocab('a b'.split(), num_copy_tokens=3)
        dynamic_vocabs = [
            HardCopyDynamicVocab(base_vocab, 'b a c d e f g'.split(
            )),  # d, e, f, g don't get assigned copy tokens (not enough)
            HardCopyDynamicVocab(
                base_vocab,
                'e f f f a d'.split()),  # e, f, g get assigned copy tokens
        ]

        AttentionDecoderCellOutput._transfer_copy_probs(
            probs, dynamic_vocabs, base_vocab)

        assert_tensor_equal(
            probs,
            [
                [
                    1, 2, 3, 24, 23, 0, 0, 16
                ],  # copy prob for 'c' is not transferred, since it's not in base
                [4, 5, 6, 46, 21, 22, 24, 0
                 ],  # only prob for 'a' gets transferred
            ])
Example #6
0
    def test_reduce_mean(self, some_seq_batch):
        result = SequenceBatch.reduce_mean(some_seq_batch, allow_empty=True)

        assert_tensor_equal(result, [[2.5, 3.5], [0, 4], [0, 0]])

        with pytest.raises(ValueError):
            SequenceBatch.reduce_mean(some_seq_batch, allow_empty=False)
Example #7
0
    def test_reduce_max(self, some_seq_batch):

        with pytest.raises(ValueError):
            # should complain about empty sequence
            SequenceBatch.reduce_max(some_seq_batch)

        values = GPUVariable(
            torch.FloatTensor([
                [
                    [1, 2], [4, 5], [4, 4]
                ],  # actual max is in later elements, but shd be suppressed by mask
                [[0, -4], [43, -5],
                 [-1, -20]],  # note that all elements in 2nd dim are negative
            ]))
        mask = GPUVariable(torch.FloatTensor([
            [1, 0, 0],
            [1, 1, 0],
        ]))
        seq_batch = SequenceBatch(values, mask)
        result = SequenceBatch.reduce_max(seq_batch)

        assert_tensor_equal(result, [
            [1, 2],
            [43, -4],
        ])
Example #8
0
    def test_forward(self, embedder, dom_elements):
        d0, d1, d2, d3, d1a, d1b, d2a = dom_elements
        pad = DOMElementPAD()

        # a batch of DOM element sequences
        # one unrealistic aspect of this batch is that different sequences share the same elements
        # (won't happen in the actual task)
        batch = [
            [d0, d1, d2, d3, d1a, d1b, d2a],
            [d1, d2, d3, d1a, pad, pad, pad],
            [d1a, d2a, pad, pad, pad, pad, pad],
        ]

        # the correct embeddings for each DOM element:
        # the original embedding, concatenated with the average of your neighbors

        d0_ = [0.1, 0, 0, 0]  # d0 should have no neighbors
        d1_ = [1, 1, 2.5, 2.5]
        d2_ = [2, 2, 2, 2]
        d3_ = [3, 3, 1.5, 1.5]
        d1a_ = [1, 0, 1, 0.5]
        d1b_ = [1, 0.5, 1, 0]
        d2a_ = [2, 0, 0, 0]  # d2a should have no neighbors
        pad_ = [0, 0, 0, 0]

        correct = np.array([
            [d0_, d1_, d2_, d3_, d1a_, d1b_, d2a_],
            [d1_, d2_, d3_, d1a_, pad_, pad_, pad_],
            [d1a_, d2a_, pad_, pad_, pad_, pad_, pad_],
        ],
                           dtype=np.float32)

        result = embedder(batch)
        assert_tensor_equal(result, correct)
Example #9
0
def base_plus_copy_indices(words, dynamic_vocabs, base_vocab, volatile=False):
    """Compute base + copy indices.
    
    Args:
        words (list[list[unicode]])
        dynamic_vocabs (list[HardCopyDynamicVocab])
        base_vocab (HardCopyVocab)
        volatile (bool)

    Returns:
        MultiVocabIndices
    """
    unk = base_vocab.UNK
    copy_seqs = []
    for seq, dyna_vocab in izip(words, dynamic_vocabs):
        word_to_copy = dyna_vocab.word_to_copy_token
        normal_copy_seq = []
        for w in seq:
            normal_copy_seq.append(word_to_copy.get(w, unk))
        copy_seqs.append(normal_copy_seq)

    # each SeqBatch.values has shape (batch_size, seq_length)
    base_indices = SequenceBatch.from_sequences(words, base_vocab, volatile=volatile)
    copy_indices = SequenceBatch.from_sequences(copy_seqs, base_vocab, volatile=volatile)

    assert_tensor_equal(base_indices.mask, copy_indices.mask)

    # has shape (batch_size, seq_length, 2)
    concat_values = torch.stack([base_indices.values, copy_indices.values], 2)

    return MultiVocabIndices(concat_values, base_indices.mask)
Example #10
0
    def test_modify(self, vocab):
        whitelists = [
            ['eat', 'what',
             'drive'],  # only eat and drive will have lemmas matched
            ['hello', 'drive'],  # only drive will have lemmas matched
            ['hi'],  # no lemmas will match
        ]

        always_allowed = []
        always_allowed.append(vocab.STOP)
        always_allowed.extend(vocab.copy_tokens)

        modifier = LexicalWhitelister(whitelists,
                                      vocab,
                                      self.word_to_forms,
                                      always_allowed=always_allowed)
        extension_probs = np.reshape(np.arange(0, 45, dtype=np.float32),
                                     (3, 15))
        modified = modifier.modify(extension_probs, None, None)

        # STOP token is enabled
        # all the copy tokens are enabled
        assert_tensor_equal(modified, [
            [0, 0, 2, 3, 4, 5, 0, 0, 0, 9, 10, 11, 12, 13, 14],
            [0, 0, 17, 0, 0, 0, 0, 0, 0, 24, 25, 26, 27, 28, 29],
            [0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 43, 44],
        ])
    def test_reduce_sum(self, some_seq_batch):
        result = SequenceBatch.reduce_sum(some_seq_batch)

        assert_tensor_equal(result, [
            [5, 7],
            [0, 4],
            [0, 0],
        ])
Example #12
0
    def test_embed_tokens(self, embedder):
        tokens = ['b', 'c', 'c']
        embeds = embedder.embed_tokens(tokens)

        assert_tensor_equal(embeds, [
            [0, 0, 0, 0, 1, 0],
            [0, 0, 0, 0, 0, 1],
            [0, 0, 0, 0, 0, 1],
        ])
Example #13
0
    def test_embed_seq_batch(self, multi_vocab_indices, token_embedder):
        embeds = token_embedder.embed_seq_batch(multi_vocab_indices)

        assert_tensor_equal(embeds.values, [
            [[10, 11, 20, 21], [8, 9, 18, 19], [10, 11, 20, 21], [10, 11, 20, 21]],
            [[0, 1, 22, 23], [8, 9, 0, 1], [10, 11, 16, 17], [0, 1, 0, 1]],
        ])

        assert_tensor_equal(embeds.mask, multi_vocab_indices.mask)
Example #14
0
    def test_base_plus_copy_indices(self, multi_vocab_indices):
        assert_tensor_equal(multi_vocab_indices.mask, [
            [1, 1, 1, 1],
            [1, 1, 1, 0],
        ])

        assert_tensor_equal(multi_vocab_indices.values, [
            [[5, 10], [4, 9], [5, 10], [5, 10]],
            [[0, 11], [4, 0], [5, 8], [0, 0]],  # z maps to UNK in base idx, b maps to UNK in copy idx
        ])
Example #15
0
    def test_embedding_from_array(self):
        emb = TokenEmbedder._embedding_from_array(np.array([[9, 9], [8, 7]], dtype=np.float32))
        assert isinstance(emb, Embedding)
        values = emb(GPUVariable(torch.LongTensor([[0, 0], [1, 0]])))

        assert_tensor_equal(values,
                            [
                                [[9, 9], [9, 9]],
                                [[8, 7], [9, 9]],
                            ])
Example #16
0
def test_expand_dims_for_broadcast():
    low_tensor = torch.FloatTensor([[1, 2, 3], [4, 5, 6]])  # (2, 3)
    high_tensor = torch.zeros(2, 3, 8, 1)

    new_tensor = expand_dims_for_broadcast(low_tensor, high_tensor)

    assert new_tensor.size() == (2, 3, 1, 1)

    assert_tensor_equal(new_tensor.squeeze(), low_tensor)

    with pytest.raises(AssertionError):
        bad_tensor = torch.zeros(2, 4, 8, 1)  # prefix doesn't match
        expand_dims_for_broadcast(low_tensor, bad_tensor)
Example #17
0
def test_batch_tile():
    # (2, 3)
    v = torch.FloatTensor([[1, 2, 3], [4, 5, 6]])
    tiled = batch_tile(v, 3)
    assert_tensor_equal(tiled, [[[1, 2, 3], [4, 5, 6]], [[1, 2, 3], [4, 5, 6]],
                                [[1, 2, 3], [4, 5, 6]]])

    v = torch.LongTensor([1, 2, 3])
    assert_tensor_equal(batch_tile(v, 4), [
        [1, 2, 3],
        [1, 2, 3],
        [1, 2, 3],
        [1, 2, 3],
    ])
Example #18
0
    def test_split(self, aligns):
        items = aligns.split()
        assert len(items) == 4

        assert_tensor_equal(items[0].values,
                            [
                                [1, 3],
                                [0, 0],
                                [0, 0]
                            ])

        assert_tensor_equal(items[0].mask,
                            [
                                [1, 1],
                                [1, 0],
                                [0, 0]
                            ])

        assert_tensor_equal(items[2].values,
                            [
                                [2, 0],
                                [0, 0],
                                [0, 0]
                            ])

        assert_tensor_equal(items[2].mask,
                            [
                                [1, 0],
                                [0, 0],
                                [0, 0]
                            ])
Example #19
0
    def test(self, aligns):
        assert_tensor_equal(aligns.indices,
                            [
                                [[1, 3], [0, 0], [2, 0], [1, 3]],
                                [[0, 0], [0, 0], [0, 0], [0, 0]],
                                [[0, 0], [0, 0], [0, 0], [0, 0]],
                            ])

        assert_tensor_equal(aligns.mask,
                            [
                                [[1, 1], [0, 0], [1, 0], [1, 1]],
                                [[1, 0], [0, 0], [0, 0], [0, 0]],
                                [[0, 0], [0, 0], [0, 0], [0, 0]],
                            ])
def test_gated_update():
    h = GPUVariable(torch.FloatTensor([
        [1, 2, 3],
        [4, 5, 6],
    ]))
    h_new = GPUVariable(torch.FloatTensor([
        [-1, 2, 3],
        [4, 8, 0],
    ]))
    update = GPUVariable(torch.FloatTensor([[0], [1]
                                            ]))  # only update the second row

    out = gated_update(h, h_new, update)

    assert_tensor_equal(out, [[1, 2, 3], [4, 8, 0]])
Example #21
0
    def test_log_sum_exp(self):
        values = GPUVariable(torch.FloatTensor([
            [0, 1, -2, -3],
            [-2, -5, 1, 0],
        ]))

        mask = GPUVariable(torch.FloatTensor([
            [1, 1, 1, 0],
            [1, 1, 0, 0],
        ]))

        seq_batch = SequenceBatch(values, mask, left_justify=False)
        result = SequenceBatch.log_sum_exp(seq_batch)
        correct = [1.3490122167681864, -1.9514126484262577]

        assert_tensor_equal(result, correct)
    def test_from_sequences(self, sequences, vocab):
        seq_batch = SequenceBatch.from_sequences(sequences, vocab)

        assert_tensor_equal(seq_batch.values,
                            np.array([
                                [1, 2, 2, 3],
                                [3, 0, 0, 0],
                                [0, 0, 0, 0],
                            ], dtype=np.int32))

        assert_tensor_equal(seq_batch.mask,
                            np.array([
                                [1, 1, 1, 1],
                                [1, 0, 0, 0],
                                [0, 0, 0, 0],
                            ], dtype=np.float32))
    def test_weighted_sum(self, some_seq_batch):
        weights = GPUVariable(torch.FloatTensor([
            [0.5, 0.3, 0],
            [0.8, 0.2, 0],
            [0, 0, 0],
        ]))
        result = SequenceBatch.weighted_sum(some_seq_batch, weights)

        # [1, 2] * 0.5 + [4, 5] * 0.3 = [0.5 + 1.2, 1 + 1.5] = [1.7, 2.5]
        # [0, 4] * 0.8 = [0, 3.2]
        # 0

        # Weights on entries where mask[i, j] = 0 get ignored, as desired.
        assert_tensor_equal(result, [
            [1.7, 2.5],
            [0, 3.2],
            [0, 0],
        ])
    def test_embed_tokens(self, token_embedder):
        assert_tensor_equal(token_embedder.embed_tokens(['c', 'z']),
                            [[10, 11, 20, 21], [0, 1, 22, 23]])

        assert_tensor_equal(token_embedder.embed_tokens(['b', 'b']),
                            [[8, 9, 18, 19], [8, 9, 0, 1]])

        assert_tensor_equal(token_embedder.embed_tokens(['c', 'c']),
                            [[10, 11, 20, 21], [10, 11, 16, 17]])

        assert_tensor_equal(token_embedder.embed_tokens(['c', WordVocab.STOP]),
                            [[10, 11, 20, 21], [4, 5, 0, 1]])
Example #25
0
    def test_bpr_loss(self):
        scores = GPUVariable(torch.FloatTensor([
            4.5, 3, 0, 1.6,
            0, 5, 11, 2,
            9, 1, 2, 4,
        ]))
        group_size = 4

        loss = Seq2SeqScorer._bpr_loss(scores, group_size)

        correct_margins = np.array([
            1.5, 4.5, 2.9,
            -5, -11, -2,
            8, 7, 5
        ])

        correct_losses = np.log(1 + np.exp(-correct_margins))
        correct_loss = np.mean(correct_losses)

        assert_tensor_equal(loss, correct_loss)
    def test_forward(self, copy_source, alignments):
        memory_dim, query_dim, attn_dim = 4, 3, 2
        attn = SoftCopyAttention(memory_dim, query_dim, attn_dim)

        attn_ex = AttentionExample()
        memory_transform, query_transform, v_transform = attn_ex.params
        memory_cells = attn_ex.memory_cells
        query = attn_ex.query

        # manually set parameters of the base attention
        base_attn = attn._base_attention
        base_attn.memory_transform.data.set_(float_tensor(memory_transform))
        base_attn.query_transform.data.set_(float_tensor(query_transform))
        base_attn.v_transform.data.set_(float_tensor(v_transform))

        # compute correct logits
        exp_logits = torch.exp(attn_ex.correct_logits)
        boost = float_tensor_var([
            [.2, 0],
            [.3, .3],
            [0, 0],
            [0, 0],
            [0, .01],
        ])
        correct_logits = torch.log(exp_logits + boost)

        # compute with module
        attn_out = attn(memory_cells, query, alignments, copy_source)

        assert_tensor_equal(attn_out.logits, correct_logits)
        assert_tensor_equal(attn_out.orig_logits, attn_ex.correct_logits)
        assert_tensor_equal(attn_out.boost, boost)
    def test_multi_vocab_indices(self):
        vocabs = [
            [SimpleVocab('a b c d e'.split()), SimpleVocab('x y z'.split())],
            [SimpleVocab('e d c b a'.split()), SimpleVocab('y z x'.split())],
        ]

        sequences = [
            'a b a e'.split(),
            'y y y x z'.split(),
        ]

        indices = SequenceBatch.multi_vocab_indices(sequences, vocabs)

        assert_tensor_equal(indices.values, [
            [[0, 4], [1, 3], [0, 4], [4, 0], [0, 0]],
            [[1, 0], [1, 0], [1, 0], [0, 2], [2, 1]],
        ])

        assert_tensor_equal(indices.mask, [
            [1, 1, 1, 1, 0],
            [1, 1, 1, 1, 1],
        ])
    def test_cat(self):
        x1 = SequenceBatchElement(
            GPUVariable(torch.FloatTensor([
                [[1, 2], [3, 4]],
                [[8, 2], [9, 0]]])),
            GPUVariable(torch.FloatTensor([
                [1],
                [1]
            ])))
        x2 = SequenceBatchElement(
            GPUVariable(torch.FloatTensor([
                [[-1, 20], [3, 40]],
                [[-8, 2], [9, 10]]])),
            GPUVariable(torch.FloatTensor([
                [1],
                [0]
            ])))
        x3 = SequenceBatchElement(
            GPUVariable(torch.FloatTensor([
                [[-1, 20], [3, 40]],
                [[-8, 2], [9, 10]]])),
            GPUVariable(torch.FloatTensor([
                [0],
                [0]
            ])))

        result = SequenceBatch.cat([x1, x2, x3])

        assert_tensor_equal(result.values,
                            [
                                [[[1, 2], [3, 4]], [[-1, 20], [3, 40]], [[-1, 20], [3, 40]]],
                                [[[8, 2], [9, 0]], [[-8, 2], [9, 10]], [[-8, 2], [9, 10]]],
                            ])

        assert_tensor_equal(result.mask,
                            [
                                [1, 1, 0],
                                [1, 0, 0]
                            ])
  def act(self, state):
    """If the current state is a "frontier", then expands the "frontier" by

        taking an action that has not been taken before. Otherwise, takes
        actions to go to a "frontier."

        Args: states (np.array)

        Returns:
            action (int)
        """
    assert_tensor_equal(state, self._current_node.history[0])
    unexplored_actions = self._current_node.unexplored_actions

    if self._planned_path is not None:
      expected_state, action = self._planned_path.pop(0)
      assert expected_state == self._current_node
      if len(self._planned_path) == 0:
        self._planned_path = None
      return action
    elif len(unexplored_actions) > 0:  # On a frontier
      action = np.random.choice(unexplored_actions)
      self._planned_path = None  # Give up on any earlier plans
      return action
    else:
      print("Planning")
      self._planned_path = self._exploration_graph.reachable_frontier(
          self._current_node)
      if self._planned_path is not None:
        expected_state, action = self._planned_path.pop(0)
        assert expected_state == self._current_node
        if len(self._planned_path) == 0:
          self._planned_path = None
        return action

    # No known way to get to frontier
    print("No reachable frontiers")
    return np.random.choice(range(self._num_actions))
Example #30
0
    def test_states_to_image_var(self):
        # mock a MiniWoBState object
        arr_to_state = lambda arr: Bunch(observation=Bunch(image=np.array(arr, dtype=np.float32)))
        arrs = [
            # ex0
            [
                [[1, 2],  # R
                 [3, 4]],
                [[1, 0],  # G
                 [3, 0]],
                [[0, 2],  # B
                 [0, 4]],
            ],
            # ex1
            [
                [[10, 20],  # R
                 [30, 40]],
                [[10, 0],  # G
                 [30, 0]],
                [[0, 20],  # B
                 [0, 40]],
            ],
            # ex2
            [
                [[100, 200],  # R
                 [300, 400]],
                [[100, 0],  # G
                 [300, 0]],
                [[0, 200],  # B
                 [0, 400]],
            ]
        ]

        correct = np.array(arrs, dtype=np.float32)

        states = [arr_to_state(arr) for arr in arrs]
        image_var = MiniWoBPolicy._states_to_image_var(states)
        assert_tensor_equal(correct, image_var)