| 6 | |
| 7 | |
| 8 | class CaptioningModel(Module): |
| 9 | def __init__(self): |
| 10 | super(CaptioningModel, self).__init__() |
| 11 | |
| 12 | def init_weights(self): |
| 13 | raise NotImplementedError |
| 14 | |
| 15 | def step(self, t, prev_output, visual, seq, mode='teacher_forcing', **kwargs): |
| 16 | raise NotImplementedError |
| 17 | |
| 18 | def forward(self, images, seq, *args): |
| 19 | device = images.device |
| 20 | b_s = images.size(0) |
| 21 | seq_len = seq.size(1) |
| 22 | state = self.init_state(b_s, device) |
| 23 | out = None |
| 24 | |
| 25 | outputs = [] |
| 26 | for t in range(seq_len): |
| 27 | out, state = self.step(t, state, out, images, seq, *args, mode='teacher_forcing') |
| 28 | outputs.append(out) |
| 29 | |
| 30 | outputs = torch.cat([o.unsqueeze(1) for o in outputs], 1) |
| 31 | return outputs |
| 32 | |
| 33 | def test(self, visual: utils.TensorOrSequence, max_len: int, eos_idx: int, **kwargs) -> utils.Tuple[torch.Tensor, torch.Tensor]: |
| 34 | b_s = utils.get_batch_size(visual) |
| 35 | device = utils.get_device(visual) |
| 36 | outputs = [] |
| 37 | log_probs = [] |
| 38 | |
| 39 | mask = torch.ones((b_s,), device=device) |
| 40 | with self.statefulness(b_s): |
| 41 | out = None |
| 42 | for t in range(max_len): |
| 43 | log_probs_t = self.step(t, out, visual, None, mode='feedback', **kwargs) |
| 44 | out = torch.max(log_probs_t, -1)[1] |
| 45 | mask = mask * (out.squeeze(-1) != eos_idx).float() |
| 46 | log_probs.append(log_probs_t * mask.unsqueeze(-1).unsqueeze(-1)) |
| 47 | outputs.append(out) |
| 48 | |
| 49 | return torch.cat(outputs, 1), torch.cat(log_probs, 1) |
| 50 | |
| 51 | def sample_rl(self, visual: utils.TensorOrSequence, max_len: int, **kwargs) -> utils.Tuple[torch.Tensor, torch.Tensor]: |
| 52 | b_s = utils.get_batch_size(visual) |
| 53 | outputs = [] |
| 54 | log_probs = [] |
| 55 | |
| 56 | with self.statefulness(b_s): |
| 57 | out = None |
| 58 | for t in range(max_len): |
| 59 | out = self.step(t, out, visual, None, mode='feedback', **kwargs) |
| 60 | distr = distributions.Categorical(logits=out[:, 0]) |
| 61 | out = distr.sample().unsqueeze(1) |
| 62 | outputs.append(out) |
| 63 | log_probs.append(distr.log_prob(out).unsqueeze(1)) |
| 64 | |
| 65 | return torch.cat(outputs, 1), torch.cat(log_probs, 1) |
nothing calls this directly
no outgoing calls
no test coverage detected