def _birnn_encoder(self, inputs, input_len, name_lens, name_pos, name_tok_len): """forward Args: inputs (Variable): shape=[batch_size, max_seq_len, hidden_size] input_len (Variable): shape=[batch_size] name_lens (Variable): shape=[batch_size] name_pos (Variable): shape=[batch_size, max_name_len, max_tokens] name_tok_len (Variable): shape=[batch_size, max_name_len] Returns: TODO Raises: NULL """ rnn_output, rnn_final_state = self._rnn_encoder.forward( inputs, input_len) max_name_len = name_pos.shape[1] name_begin = name_pos[:, :, 0] name_repr_mask = layers.sequence_mask(name_lens, max_name_len, dtype=name_tok_len.dtype) len_delta = layers.elementwise_mul(name_tok_len - 1, name_repr_mask, axis=0) name_end = name_begin + len_delta if self._bidirectional: name_fwd_repr_gathered = nn_utils.batch_gather_2d( rnn_output, name_end)[:, :, :self._hidden_size] name_bwd_repr_gathered = nn_utils.batch_gather_2d( rnn_output, name_begin)[:, :, self._hidden_size:] name_repr_gathered = layers.concat( input=[name_fwd_repr_gathered, name_bwd_repr_gathered], axis=-1) new_hidden_size = self._hidden_size * 2 else: name_repr_gathered = layers.gather_nd(rnn_output, name_end) new_hidden_size = self._hidden_size name_repr_tmp = layers.reshape( name_repr_gathered, shape=[-1, max_name_len, new_hidden_size]) name_repr_mask = layers.cast(name_repr_mask, dtype=name_repr_tmp.dtype) name_repr = layers.elementwise_mul(name_repr_tmp, name_repr_mask, axis=0) return name_repr, None
def span_encoder(self, cls_hidden, seq_hidden, span_index, span_tokens_index, span_tokens_mask, proj_fn=None): """encode spans(like headers, table names) by sequence hidden states Args: cls_hidden (TYPE): NULL seq_hidden (TYPE): NULL span_index (TYPE): NULL span_tokens_index (TYPE): NULL span_tokens_mask (TYPE): NULL proj_fn (callable): Default is None. Returns: TODO Raises: NULL """ batch_size, max_col_nums, max_col_tokens = span_tokens_index.shape hidden_size = cls_hidden.shape[-1] # shape = [batch, max_col, hidden_size] span_enc1 = nn_utils.batch_gather_2d(seq_hidden, span_index) token_gather_index = paddle.reshape( span_tokens_index, shape=[-1, max_col_nums * max_col_tokens]) span_tokens_enc_origin = nn_utils.batch_gather_2d( seq_hidden, token_gather_index) span_tokens_weight = paddle.reshape( paddle.matmul(span_tokens_enc_origin, paddle.unsqueeze(cls_hidden, [-1])), [-1, max_col_nums, max_col_tokens]) span_tokens_weight = F.softmax(nn_utils.sequence_mask( span_tokens_weight, span_tokens_mask), axis=-1) span_tokens_enc_origin = paddle.reshape( span_tokens_enc_origin, [-1, max_col_nums, max_col_tokens, hidden_size]) span_enc2 = paddle.sum(paddle.multiply( span_tokens_enc_origin, span_tokens_weight.unsqueeze([-1])), axis=2) span_enc = paddle.concat([span_enc1, span_enc2], axis=-1) if proj_fn is not None: span_enc = proj_fn(span_enc) return span_enc
def _simple_sum_encoder(self, inputs, input_len, name_lens, name_pos, name_tok_len): """forward Args: inputs (Variable): shape=[batch_size, max_seq_len, hidden_size] input_len (Variable): shape=[batch_size] name_lens (Variable): shape=[batch_size] name_pos (Variable): shape=[batch_size, max_name_len, max_tokens] name_tok_len (Variable): shape=[batch_size, max_name_len] Returns: TODO Raises: NULL """ max_name_len = name_pos.shape[1] max_name_tok_len = name_pos.shape[2] hidden_size = inputs.shape[2] name_pos_1d = layers.reshape( name_pos, shape=[-1, max_name_len * max_name_tok_len]) name_enc = nn_utils.batch_gather_2d(inputs, name_pos_1d) name_enc = layers.reshape( name_enc, shape=[-1, max_name_len, max_name_tok_len, hidden_size]) # shape = [batch_size, name_len, token_len, hidden_size] name_tok_mask = layers.sequence_mask(name_tok_len, maxlen=max_name_tok_len, dtype=name_enc.dtype) name_enc_masked = layers.elementwise_mul(name_enc, name_tok_mask, axis=0) # shape = [batch_size, name_len, hidden_size] output = layers.reduce_sum(name_enc_masked, dim=2) return output, None
def _lf_embedder(self, tokens, token_lens=None): """lf embedder. Args: tokens (Variable): [batch_size, seq_len] token_lens (Variable): Default is None. Returns: TODO Raises: NULL """ self._batch_size = layers.shape(self.question_encoding)[0] ## Grammar Rule Embedding self._grammar_vocab = tensor.cast(tensor.assign( self.grammar.gmr_vocab.astype(np.int32)), dtype='int64') self._grammar_emb = fluid.embedding( input=self._grammar_vocab, size=[self.grammar.grammar_size, self.lf_emb_size], dtype='float32', is_sparse=False, param_attr=fluid.ParamAttr(name="lf_embedding", initializer=nn_utils.uniform( self.init_scale))) batch_emb_lookup_grammar = layers.expand( layers.unsqueeze(self._grammar_emb, [0]), [self._batch_size, 1, 1]) def _table_to_lf_input(ori_encoding): """trans ori_encoding to size of lf_embedding """ output = layers.fc(input=ori_encoding, size=self.lf_emb_size, num_flatten_dims=2, **nn_utils.param_attr('fc_table2lf_input', self.init_scale, need_bias=False)) return output batch_emb_lookup_all = tensor.concat([ batch_emb_lookup_grammar, _table_to_lf_input(self.tname_encoding), _table_to_lf_input(self.cname_encoding), _table_to_lf_input(self.value_encoding) ], axis=1) lf_embedding = nn_utils.batch_gather_2d(batch_emb_lookup_all, tokens) ## Grammar Rule 类型 Embedding self._grammar2name = layers.cast(layers.assign( self.grammar.gmr2name_arr.astype(np.int32)), dtype='int64') lf_name = layers.reshape(layers.gather( self._grammar2name, layers.reshape(tokens, shape=[-1])), shape=tokens.shape) lf_name.stop_gradient = True lf_name_emb = fluid.embedding( input=lf_name, size=[self.grammar.name_size, self.lf_name_emb_size], dtype='float32', is_sparse=False, param_attr=fluid.ParamAttr(name="lf_name_embedding", initializer=nn_utils.uniform( self.init_scale))) output = layers.concat([lf_embedding, lf_name_emb], axis=-1) if token_lens is not None: mask = layers.sequence_mask(token_lens, maxlen=layers.shape(tokens)[1], dtype='float32') output = layers.elementwise_mul(output, mask, axis=0) return output
def forward(self, inputs): """modeling forward stage of encoder """ seq_hidden, cls_hidden = self.base_encoder(inputs['src_ids'], inputs['sent_ids']) if self.pretrain_model_type != 'ERNIE' and self.pretrain_model_type != 'BERT': cls_hidden, seq_hidden = seq_hidden, cls_hidden question_tokens_index = inputs["question_tokens_index"] table_indexes = inputs["table_indexes"] column_indexes = inputs["column_indexes"] value_indexes = inputs["value_indexes"] question_encs = nn_utils.batch_gather_2d(seq_hidden, question_tokens_index) table_encs = nn_utils.batch_gather_2d(seq_hidden, table_indexes) column_encs = nn_utils.batch_gather_2d(seq_hidden, column_indexes) value_encs = nn_utils.batch_gather_2d(seq_hidden, value_indexes) if self.enc_value_with_col: value_num = value_encs.shape[1] // 2 value_encs = value_encs.reshape( [value_encs.shape[0], value_num, 2, -1]).sum(axis=2) orig_inputs = inputs['orig_inputs'] column_pointer_maps = [{ i: [i] for i in range(len(orig_input.columns)) } for orig_input in orig_inputs] table_pointer_maps = [{i: [i] for i in range(len(orig_input.tables))} for orig_input in orig_inputs] value_pointer_maps = [{i: [i] for i in range(len(orig_input.values))} for orig_input in orig_inputs] enc_results = [] # calculate relation encoding one-by-one for batch_idx, orig_input in enumerate(orig_inputs): q_len = orig_input.column_indexes[0] - 2 col_size = len(orig_input.columns) tab_size = len(orig_input.tables) val_size = len(orig_input.values) q_enc = question_encs[batch_idx][:q_len] tab_enc = table_encs[batch_idx][:tab_size] col_enc = column_encs[batch_idx][:col_size] val_enc = value_encs[batch_idx][:val_size] c_boundary = list(range(col_size + 1)) t_boundary = list(range(tab_size + 1)) v_e_input = val_enc.unsqueeze(0) if self.rel_has_value else None (q_enc_new, c_enc_new, t_enc_new, v_enc_new), align_mat = self.encs_update.forward_unbatched( q_enc.unsqueeze(0), col_enc.unsqueeze(0), tab_enc.unsqueeze(0), c_boundary, t_boundary, orig_input.relations, v_e_input) memory = [] if 'question' in self.include_in_memory: memory.append(q_enc_new) if 'table' in self.include_in_memory: memory.append(t_enc_new) if 'column' in self.include_in_memory: memory.append(c_enc_new) if 'value' in self.include_in_memory and self.rel_has_value: memory.append(v_enc_new) memory = paddle.concat(memory, axis=1) if not self.rel_has_value: v_enc_new = val_enc.unsqueeze(0) m2v_align_mat = self.value_align(memory, v_enc_new, relations=None) align_mat[2] = m2v_align_mat schema_memory = (c_enc_new, t_enc_new) if self.rel_has_value: schema_memory += (v_enc_new, ) enc_results.append( EncoderState( state=None, cls_hidden=cls_hidden[batch_idx], memory=memory, question_memory=q_enc_new, schema_memory=paddle.concat(schema_memory, axis=1), words=orig_input.question_tokens, pointer_memories={ 'table': t_enc_new, 'column': c_enc_new, 'value': v_enc_new, }, pointer_maps={ 'column': column_pointer_maps[batch_idx], 'table': table_pointer_maps[batch_idx], 'value': value_pointer_maps[batch_idx], }, m2c_align_mat=align_mat[0], m2t_align_mat=align_mat[1], m2v_align_mat=align_mat[2], )) return enc_results