Skip to content
This repository was archived by the owner on Jan 24, 2024. It is now read-only.
Open
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
229 changes: 227 additions & 2 deletions hapi/text/text.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
import paddle.fluid as fluid
import paddle.fluid.layers.utils as utils
from paddle.fluid.layers.utils import map_structure, flatten, pack_sequence_as
from paddle.fluid.dygraph import to_variable, Embedding, Linear, LayerNorm, GRUUnit
from paddle.fluid.dygraph import to_variable, Embedding, Linear, LayerNorm, GRUUnit, Conv2D
from paddle.fluid.data_feeder import convert_dtype

from paddle.fluid import layers
Expand All @@ -49,7 +49,8 @@
'BeamSearchDecoder', 'MultiHeadAttention', 'FFN',
'TransformerEncoderLayer', 'TransformerEncoder', 'TransformerDecoderLayer',
'TransformerDecoder', 'TransformerBeamSearchDecoder', 'Linear_chain_crf',
'Crf_decoding', 'SequenceTagging', 'GRUEncoderLayer'
'Crf_decoding', 'SequenceTagging', 'GRUEncoderLayer', 'SimCNNEncoder',
'SimBOWEncoder', 'SimpleConvPoolLayer', 'SimGRUEncoder', 'DynamicGRU', 'SimLSTMEncoder'
]


Expand Down Expand Up @@ -1896,3 +1897,227 @@ def forward(self, word, lengths, target=None):
self.linear_chain_crf.weight = self.crf_decoding.weight
crf_decode = self.crf_decoding(input=emission, length=lengths)
return crf_decode, lengths

class SimpleConvPoolLayer(Layer):

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed, rename as Conv1DPoolLayer

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed, rename as Conv1DPoolLayer

Done. Thanks

def __init__(self,
num_channels,
num_filters,
filter_size,
use_cudnn=False,
act=None
):
super(SimpleConvPoolLayer, self).__init__()
self._conv2d = Conv2D(num_channels=num_channels,
num_filters=num_filters,
filter_size=filter_size,
padding=[1, 1],
use_cudnn=use_cudnn,
act=act)

def forward(self, input):
x = self._conv2d(input)
x = fluid.layers.reduce_max(x, dim=-1)
x = fluid.layers.reshape(x, shape=[x.shape[0], -1])
Comment thread
jinyuKING marked this conversation as resolved.
Outdated
return x


class SimCNNEncoder(Layer):

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

如讨论所述,可以重新命名为CNNEncoder

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

如讨论所述,可以重新命名为CNNEncoder

Done,Thanks

"""
simple CNNEncoder for simnet
"""
Comment thread
jinyuKING marked this conversation as resolved.
def __init__(self,
dict_size,
emb_dim,
filter_size,
num_filters,
hidden_dim,
seq_len,
padding_idx,
act
):
super(SimCNNEncoder, self).__init__()
self.dict_size = dict_size
self.emb_dim = emb_dim
self.filter_size = filter_size
self.num_filters = num_filters
self.hidden_dim = hidden_dim
self.seq_len = seq_len
self.padding_idx = padding_idx
self.act = act
self.channels = 1
self.emb_layer = Embedding(size=[self.dict_size, self.emb_dim],
is_sparse=True,
padding_idx=self.padding_idx,
param_attr=fluid.ParamAttr(name='emb', initializer=fluid.initializer.Xavier()))
self.cnn_layer = SimpleConvPoolLayer(
self.channels,
self.num_filters,
self.filter_size,
use_cudnn=False,
act=self.act
)

def forward(self, input):
emb = self.emb_layer(input)
emb_reshape = fluid.layers.reshape(
emb, shape=[-1, self.channels, self.seq_len, self.hidden_dim])

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

感觉最好不要使用固定的seq_len,对于不同batch,seq_len应该允许可变

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

感觉最好不要使用固定的seq_len,对于不同batch,seq_len应该允许可变

已更改

emb_out=self.cnn_layer(emb_reshape)
return emb_out

class SimBOWEncoder(Layer):
"""
simple BOWEncoder for simnet
"""
def __init__(self,
dict_size,
emb_dim,
bow_dim,
seq_len,
padding_idx
):
super(SimBOWEncoder, self).__init__()
self.dict_size = dict_size
self.bow_dim = bow_dim
self.seq_len = seq_len

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

感觉BOWEncoder相对简单些可以直接放在模型中,这里可以不提供,另外这里似乎还是会有seq_len的问题

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

如果有其他模型需要使用的话这里也可以保留

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

如果有其他模型需要使用的话这里也可以保留

BOWEncoder只使用了Embedding,感觉由用户自己搭建比较好,不放在text.py中了

self.emb_dim = emb_dim
self.padding_idx=padding_idx
self.emb_layer = Embedding(size=[self.dict_size, self.emb_dim],
is_sparse=True,
padding_idx=self.padding_idx,
param_attr=fluid.ParamAttr(name='emb', initializer=fluid.initializer.Xavier()))

def forward(self, input):
emb = self.emb_layer(input)
emb_reshape = fluid.layers.reshape(
emb, shape=[-1, self.seq_len, self.bow_dim])
bow_emb = fluid.layers.reduce_sum(emb_reshape, dim=1)
return bow_emb

class DynamicGRU(fluid.dygraph.Layer):

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

text.py中已有GRU的接口可以直接使用,对外统一提供一个吧,不然容易引起困惑

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

text.py中已有GRU的接口可以直接使用,对外统一提供一个吧,不然容易引起困惑

好的。

def __init__(self,
size,
h_0=None,
param_attr=None,
bias_attr=None,
is_reverse=False,
gate_activation='sigmoid',
candidate_activation='tanh',
origin_mode=False,
init_size=None):
super(DynamicGRU, self).__init__()

self.gru_unit = GRUUnit(
size * 3,
param_attr=param_attr,
bias_attr=bias_attr,
activation=candidate_activation,
gate_activation=gate_activation,
origin_mode=origin_mode)

self.size = size
self.h_0 = h_0
self.is_reverse = is_reverse

def forward(self, inputs):
hidden = self.h_0
res = []
for i in range(inputs.shape[1]):

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shape may be dummy for graph mode, for RNN please use RNN api in text.py

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shape may be dummy for graph mode, for RNN please use RNN api in text.py

这个GRU的接口不再写入text.py中了,使用text.py中原有的RNN相关接口搭建网络。

if self.is_reverse:
i = inputs.shape[1] - 1 - i
input_ = inputs[:, i:i + 1, :]
input_ = fluid.layers.reshape(
input_, [-1, input_.shape[2]], inplace=False)
hidden, reset, gate = self.gru_unit(input_, hidden)
hidden_ = fluid.layers.reshape(
hidden, [-1, 1, hidden.shape[1]], inplace=False)
res.append(hidden_)
if self.is_reverse:
res = res[::-1]
res = fluid.layers.concat(res, axis=1)
return res

class SimGRUEncoder(Layer):

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

同上,text.py中已有GRU的接口可以直接使用,对外统一提供一个吧

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

同上,text.py中已有GRU的接口可以直接使用,对外统一提供一个吧

好的

"""
simple GRUEncoder for simnet
"""
def __init__(self,
dict_size,
emb_dim,
gru_dim,
hidden_dim,
padding_idx,
seq_len
):
super(SimGRUEncoder, self).__init__()
self.dict_size = dict_size
self.emb_dim = emb_dim
self.gru_dim = gru_dim
self.seq_len=seq_len
self.hidden_dim = hidden_dim
self.padding_idx=self.padding_idx
self.emb_layer = Embedding(size=[self.dict_size, self.emb_dim],
is_sparse=True,
padding_idx=self.padding_idx,
param_attr=fluid.ParamAttr(name='emb',
initializer=fluid.initializer.Xavier()))
self.gru_layer = DynamicGRU(self.gru_dim)
self.proj_layer = Linear(input_dim=self.hidden_dim, output_dim=self.gru_dim * 3)

def forward(self, input):
emb = self.emb_layer(input)
emb_proj = self.proj_layer(emb)
h_0 = np.zeros((emb_proj.shape[0], self.hidden_dim), dtype="float32")
h_0 = to_variable(h_0)
gru = self.gru_layer(emb_proj, h_0=h_0)
gru = fluid.layers.reduce_max(gru, dim=1)
gru = fluid.layers.tanh(gru)
return gru

class SimLSTMEncoder(Layer):

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

可以Sim去掉,另外可以参考text.py中已有的GRUEncoder接口提供类似的实现

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

可以Sim去掉,另外可以参考text.py中已有的GRUEncoder接口提供类似的实现

好的

"""
simple LSTMEncoder for simnet
"""
def __init__(self,
dict_size,
emb_dim,
lstm_dim,
hidden_dim,
seq_len,
padding_idx,
is_reverse
):
"""
initialize
"""
super(SimLSTMEncoder, self).__init__()
self.dict_size = dict_size
self.emb_dim = emb_dim
self.lstm_dim = lstm_dim
self.hidden_dim = hidden_dim
self.seq_len = seq_len

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

还请注意下seq_len的问题

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

还请注意下seq_len的问题

好的。

self.is_reverse = False
self.padding_idx=padding_idx

self.emb_layer = Embedding(size=[self.dict_size, self.emb_dim],
is_sparse=True,
padding_idx=self.padding_idx,
param_attr=fluid.ParamAttr(name='emb', initializer=fluid.initializer.Xavier()))

self.lstm_cell = BasicLSTMCell(
hidden_size=self.lstm_dim, input_size=self.lstm_dim * 4
)
self.lstm_layer = RNN(
cell=self.lstm_cell, time_major=True, is_reverse=self.is_reverse
)
self.proj_layer = Linear(input_dim=self.hidden_dim, output_dim=self.lstm_dim * 4)

def forward(self, input):

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

为class的method添加文档,说明输入参数和返回内容,上面那个Conv1DPoolLayer类似

emb = self.emb_layer(input)
emb_proj = self.proj_layer(emb)
emb_lstm, _ = self.lstm_layer(emb_proj)
emb_reduce = fluid.layers.reduce_max(emb_lstm, dim=1)
emb_reshape = fluid.layers.reshape(
emb_reduce, shape=[-1, self.seq_len, self.hidden_dim])
emb_lstm = fluid.layers.reduce_sum(emb_reshape, dim=1)
emb_last = fluid.layers.tanh(emb_lstm)
return emb_last