Closed geasyheart closed 2 years ago
定义成非bug原因为模型本身不具有可解释性,只要效果不错,就不定义为bug~
随后你会在每一个任务里面获取句子向量时都是通过
encoder_hidden[:, 1:-1:, ]
来表示
请问究竟哪个任务这样表示了呢?所有token level的任务都有相应的token level的mask,不会将padding纳入loss或prediction。
我debug的multitask,另外不会将padding纳入loss或prediction
这里没问题,只是你对transformer encode取对应的index那里不合理。
除了tok,剩下的multi task learning都会走到h[:, 1:-1,:]
。这里 。
我们有两个地方理解得可能不一样。
h
已经是每个token的hidden state了sep_is_eos
意味着如果句子有n个token的话,h这一维的长度就是n+1(包含eos)。所以sep_is_eos=False
时,为了下游任务正确地apply token mask,这里只有将最后一个元素去掉,但不意味着去掉的一定是sep。其实只要去掉一个无关紧要的元素就行,很明显去掉最后一个是效率最高的做法。这种做法乍一看似乎很绕,其实HanLP的代码复用率是相当高的。所有的task都是继承了single task learning的component,这些single task在设计的时候是不需要考虑h的长度不一致的问题的。毕竟一个task不一定会做MTL,我希望写它们的时候不用考虑兼容性。只要需要的时候,为了将它们纳入MTL框架,才有上面这段检查bos和eos的代码。
那我举个例子,tok那里您也是一样的处理方式(即transformer_encoder_output[:, 1:-1, :]
)。比如有两个句子:
batch['token'] = [['我', '爱', '你', '们', '和', '北', '京', '。'], ['我', '爱', '你', '们', '。']]
# 您的token_token_span
batch['token_token_span'] = tensor([[[0],[1],[2], [3], [4], [5], [6],[7],[8],[9]],
[[0], [1], [2],[3],[4],[5], [6], [0],[0],[0]]])
您经过transformer encoder
和pick_tensor_for_each_token
处理后,维度h是(2, 10, 256)
,这里没问题,问题在下面decoder这一步:
def forward(self, contextualized_embeddings: torch.FloatTensor, batch: Dict[str, torch.Tensor], mask=None):
return self.classifier(contextualized_embeddings[:, 1:-1, :])
这里的-1
在有padding的情况下不会是[SEP]
。
嗯嗯,multi task learning代码写的相当nice,有很多值得学习的地方。
```python
这里的-1在有padding的情况下不会是[SEP]。
去掉的究竟是sep还是pad其实对下游任务没有任何影响,因为总归是要再过一遍mask的,只要h的维度和mask一致就行了。
下游任务有没有影响,本质来讲是输入的形式是固定的,以及模型已经能够拟合的很好。
如果在每次pick_tensor_for_each_token对transformer_encoder结果进行操作时去掉[CLS]
和[SEP]
,那么在decoder部分接收到的都是原tokens了。
下游任务有没有影响,本质来讲是输入的形式是固定的,以及模型已经能够拟合的很好。 如果在每次pick_tensor_for_each_token对transformer_encoder结果进行操作时去掉
[CLS]
和[SEP]
,那么在decoder部分接收到的都是原tokens了。
无论去掉的是不是sep,decoder得到的h在mask后一模一样。
不能直接去掉。有些任务需要cls作为bos,需要sep作为eos。MTL框架会根据所有task取一个全集去encode,再根据每个task的需要裁剪。
好的,我知道您这边的做法了
Describe the bug A clear and concise description of what the bug is. 你好,我在看到transformer_tokenizer.py时,你对CLS和SEP也计算了
token_token_span
,接着你会调用pick_tensor_for_each_token这个函数来获取首字向量或者平均向量,随后你会在每一个任务里面获取句子向量时都是通过encoder_hidden[:, 1:-1:, ]
来表示,其中-1
在有padding的情况下不会是[SEP]。Code to reproduce the issue Provide a reproducible test case that is the bare minimum necessary to generate the problem.
Describe the current behavior A clear and concise description of what happened.
Expected behavior A clear and concise description of what you expected to happen.
System information
Other info / logs Include any logs or source code that would be helpful to diagnose the problem. If including tracebacks, please include the full traceback. Large logs and files should be attached.