def forward(self, v, b, q):
    'Forward\n\n        v: [batch, num_objs, obj_dim]\n        b: [batch, num_objs, b_dim]\n        q: [batch_size, seq_length]\n\n        return: logits, not probs\n        '
    w_emb = self.w_emb(q)
    q_emb = self.q_emb.forward_all(w_emb)
    ori_q_emb = q_emb
    boxes = b[:, :, :4].transpose(1, 2)
    b_emb = ([0] * self.glimpse)
    s_x = self.init_hidden_state(len(q), 256)
    s_h = torch.tanh(self.semantic_q(ori_q_emb.mean(1)))
    v_att = torch.tanh(self.att_v(F.dropout(v, 0.25)))
    op = []
    att_mask = []
    q_emb_pool = []
    for g in range(self.glimpse):
        s_h = self.semantic_rnn(s_x, s_h)
        s_x = F.softmax(self.semantic_pred(s_h), dim=(- 1))
        op.append(s_x)
        s_x = torch.max(s_x, dim=(- 1))[1]
        s_x = self.semantic_embed(s_x)
        s_att = torch.tanh(self.att_s(s_h)).unsqueeze(1).expand_as(v_att)
        fuse_feat = torch.tanh(self.att_p(torch.mul(s_att, v_att)))
        reason_att = self.att(fuse_feat)
        reason_att = F.softmax(reason_att.view(reason_att.size(0), (- 1)), dim=(- 1))
        cur_v = torch.mul(v, reason_att.unsqueeze((- 1)).expand_as(v))
        (att, logits) = self.v_att(cur_v, ori_q_emb)
        (att, logits) = (att.squeeze(), logits.squeeze())
        b_emb[g] = self.b_net[g].forward_with_weights(v, q_emb, att)
        (atten, _) = logits.max(2)
        embed = self.counter(boxes, atten)
        q_emb = (self.q_prj[g](b_emb[g].unsqueeze(1)) + q_emb)
        q_emb = (q_emb + self.c_prj[g](embed).unsqueeze(1))
        q_emb_pool.append(q_emb)
        att_mask.append(reason_att)
    op = torch.cat([_.unsqueeze(1) for _ in op], dim=1)
    att_mask = torch.cat([_.unsqueeze(1) for _ in att_mask], dim=1)
    valid_op = process_lengths(torch.max(op, dim=(- 1))[1])
    q_emb_pool = torch.cat([_.unsqueeze(1) for _ in q_emb_pool], dim=1)
    q_emb = select_last(q_emb_pool, valid_op)
    logits = self.classifier(q_emb.sum(1))
    return (F.softmax(logits, dim=(- 1)), op, att_mask)
Forward

v: [batch, num_objs, obj_dim]
b: [batch, num_objs, b_dim]
q: [batch_size, seq_length]

return: logits, not probs
def forward(self, v, b, q):
    'Forward\n\n        v: [batch, num_objs, obj_dim]\n        b: [batch, num_objs, b_dim]\n        q: [batch_size, seq_length]\n\n        return: logits, not probs\n        '
    w_emb = self.w_emb(q)
    q_emb = self.q_emb.forward_all(w_emb)
    ori_q_emb = q_emb
    boxes = b[:, :, :4].transpose(1, 2)
    b_emb = ([0] * self.glimpse)
    s_x = self.init_hidden_state(len(q), 256)
    s_h = torch.tanh(self.semantic_q(ori_q_emb.mean(1)))
    v_att = torch.tanh(self.att_v(F.dropout(v, 0.25)))
    op = []
    att_mask = []
    q_emb_pool = []
    for g in range(self.glimpse):
        s_h = self.semantic_rnn(s_x, s_h)
        s_x = F.softmax(self.semantic_pred(s_h), dim=(- 1))
        op.append(s_x)
        s_x = torch.max(s_x, dim=(- 1))[1]
        s_x = self.semantic_embed(s_x)
        s_att = torch.tanh(self.att_s(s_h)).unsqueeze(1).expand_as(v_att)
        fuse_feat = torch.tanh(self.att_p(torch.mul(s_att, v_att)))
        reason_att = self.att(fuse_feat)
        reason_att = F.softmax(reason_att.view(reason_att.size(0), (- 1)), dim=(- 1))
        cur_v = torch.mul(v, reason_att.unsqueeze((- 1)).expand_as(v))
        (att, logits) = self.v_att(cur_v, ori_q_emb)
        (att, logits) = (att.squeeze(), logits.squeeze())
        b_emb[g] = self.b_net[g].forward_with_weights(v, q_emb, att)
        (atten, _) = logits.max(2)
        embed = self.counter(boxes, atten)
        q_emb = (self.q_prj[g](b_emb[g].unsqueeze(1)) + q_emb)
        q_emb = (q_emb + self.c_prj[g](embed).unsqueeze(1))
        q_emb_pool.append(q_emb)
        att_mask.append(reason_att)
    op = torch.cat([_.unsqueeze(1) for _ in op], dim=1)
    att_mask = torch.cat([_.unsqueeze(1) for _ in att_mask], dim=1)
    valid_op = process_lengths(torch.max(op, dim=(- 1))[1])
    q_emb_pool = torch.cat([_.unsqueeze(1) for _ in q_emb_pool], dim=1)
    q_emb = select_last(q_emb_pool, valid_op)
    logits = self.classifier(q_emb.sum(1))
    return (F.softmax(logits, dim=(- 1)), op, att_mask)