fastnlp / fastNLP

fastNLP: A Modularized and Extensible NLP Framework. Currently still in incubation.
https://gitee.com/fastnlp/fastNLP
Apache License 2.0
3.05k stars 451 forks source link

BertEmbedding #378

Open yt-liang opened 2 years ago

yt-liang commented 2 years ago

您好,我是用BertEmbedding,模型使用cn(chinese-bert-wwm),输入分好的词,是不是可以这样做,这样可以得到分词的向量,还是说必须基于字符进行输入.因为我的下游任务需要分好词的向量,如果必须要字符的话,那词向量如何获得.

yhcc commented 2 years ago

可以这样直接输入词语的,这样底层还是用的字的bert,但是在bert输出字的表示之后,BertEmbedding会把属于同一个词的字做pooling再输出。

yt-liang commented 2 years ago

可以这样直接输入词语的,这样底层还是用的字的bert,但是在bert输出字的表示之后,BertEmbedding会把属于同一个词的字做pooling再输出。

感谢您的回复,最近几天试了试发现基于中文的bert,效果并不理想,调了好多参数,效果都不太好,是对于中文768维度太大了,还是什么原因呢?还想请您指导一下。我目前做的是biaffine,是基于分好词的,,BertEmbedding会把属于同一个词的字做pooling再输出,因此我就直接按照词输入的。

yhcc commented 2 years ago

你确认下BERTEmbedding的梯度是不是打开了,初始化参数中的requires_grad是否为True。 你先通过在小数据集(比如你的dev数据集,或者部分dev,100条左右)上overfit看看,即在dev上训练,然后在dev上测试,看看性能能不能达到100%(至少应该可以达到99%),如果不能的话,应该就是代码写错了。 另外就是一般lr设置成1e-5~5e-5之间吧,建议需要使用warmup。如果还不行的话,建议bertembedding和后续model使用不同的lr再试试。

yt-liang commented 2 years ago

你确认下BERTEmbedding的梯度是不是打开了,初始化参数中的requires_grad是否为True。 你先通过在小数据集(比如你的dev数据集,或者部分dev,100条左右)上overfit看看,即在dev上训练,然后在dev上测试,看看性能能不能达到100%(至少应该可以达到99%),如果不能的话,应该就是代码写错了。 另外就是一般lr设置成1e-5~5e-5之间吧,建议需要使用warmup。如果还不行的话,建议bertembedding和后续model使用不同的lr再试试。

warmup就是用的(WarmupCallback)默认0.1.学习率分开是什么意思呢?我是用的是AdamW,设置的学习率,如何设置两个学习率呢?

yt-liang commented 2 years ago

目前,requires_grad打开了 dev上正在尝试,warmup就是用的(WarmupCallback)默认0.1.学习率分开是什么意思呢?我是用的是AdamW,设置的学习率,如何设置两个学习率呢?

yhcc commented 2 years ago

类似于pytorch学习系列(6):不同的层设置不同的学习率(迁移学习) - 空谷幽兰的文章 - 知乎 https://zhuanlan.zhihu.com/p/93589161

yt-liang commented 2 years ago

类似于pytorch学习系列(6):不同的层设置不同的学习率(迁移学习) - 空谷幽兰的文章 - 知乎 https://zhuanlan.zhihu.com/p/93589161

感谢您的回复,目前使用BERT,CTB7依存分析能达到88左右,我查询资料BERT基本能达到91左右,可能参数还是没调好。我还有一个问题是,BERTEmbedding传入vocab的作用是什么?因为我的是基于词的,传入的就是词典,但是bert那个vocab不是字的吗?有什么影响吗?

yhcc commented 2 years ago

bert的本身的vocab是字的,但是bertembedding接受的vocab可以是词的,bertembedding会在forward的时候自动把词拆分成字输入给bert(因为bert只认识字),在forward结束之前会使用pooling方法把属于同一个词的字的表示聚合起来得到这个词语的表示。传入给bertembedding的vocab相当于就是告诉bertembedding当在forward中输入1或某个数字(这些数字使用传入的vocab进行index得到的)的时候代表的是哪个词,bertembedding应该把它拆成哪些字输入到bertembedding中。

yt-liang commented 2 years ago

bert的本身的vocab是字的,但是bertembedding接受的vocab可以是词的,bertembedding会在forward的时候自动把词拆分成字输入给bert(因为bert只认识字),在forward结束之前会使用pooling方法把属于同一个词的字的表示聚合起来得到这个词语的表示。传入给bertembedding的vocab相当于就是告诉bertembedding当在forward中输入1或某个数字(这些数字使用传入的vocab进行index得到的)的时候代表的是哪个词,bertembedding应该把它拆成哪些字输入到bertembedding中。

例如两个句子匹配任务,我可以自己把两个句子拼接起来送到bert-embedding吗?例如:【cls】A【sep】B 这样子

yhcc commented 2 years ago

可以的,[CLS]和[SEP]会被识别成特殊BERT的表示的。

yt-liang commented 2 years ago

可以的,[CLS]和[SEP]会被识别成特殊BERT的表示的。

也就是说,我把字或者词转换成数字送入到bertembedddig,如2,90,68,3,45,40,3(index 2代表cls,3代表sep ),他会自动转成cls和sep并进行识别是吗?

yhcc commented 2 years ago

是的

yt-liang commented 2 years ago

是的 您好,那我自己加上如【cls】A【sep】B【sep】和include_cls_sep设置为True,我只在A、B中间加上【sep】,效果是一样的吗

yhcc commented 2 years ago

是的