@@ -45,9 +45,9 @@ class CNNCharEmbedding(TokenEmbedding): | |||||
:param pool_method: character的表示在合成一个表示时所使用的pool方法,支持'avg', 'max'. | :param pool_method: character的表示在合成一个表示时所使用的pool方法,支持'avg', 'max'. | ||||
:param activation: CNN之后使用的激活方法,支持'relu', 'sigmoid', 'tanh' 或者自定义函数. | :param activation: CNN之后使用的激活方法,支持'relu', 'sigmoid', 'tanh' 或者自定义函数. | ||||
:param min_char_freq: character的最少出现次数。默认值为2. | :param min_char_freq: character的最少出现次数。默认值为2. | ||||
:param pre_train_char_embed:可以有两种方式调用预训练好的character embedding:第一种是传入embedding文件夹(文件夹下应该只有一个 | |||||
以.txt作为后缀的文件)或文件路径;第二种是传入embedding的名称,第二种情况将自动查看缓存中是否存在该模型,没有的话将自动下载。 | |||||
如果输入为None则使用embedding_dim的维度随机初始化一个embedding. | |||||
:param pre_train_char_embed: 可以有两种方式调用预训练好的character embedding:第一种是传入embedding文件夹 | |||||
(文件夹下应该只有一个以.txt作为后缀的文件)或文件路径;第二种是传入embedding的名称,第二种情况将自动查看缓存中是否存在该模型, | |||||
没有的话将自动下载。如果输入为None则使用embedding_dim的维度随机初始化一个embedding. | |||||
""" | """ | ||||
def __init__(self, vocab: Vocabulary, embed_size: int=50, char_emb_size: int=50, word_dropout:float=0, | def __init__(self, vocab: Vocabulary, embed_size: int=50, char_emb_size: int=50, word_dropout:float=0, | ||||
dropout:float=0.5, filter_nums: List[int]=(40, 30, 20), kernel_sizes: List[int]=(5, 3, 1), | dropout:float=0.5, filter_nums: List[int]=(40, 30, 20), kernel_sizes: List[int]=(5, 3, 1), | ||||
@@ -198,9 +198,9 @@ class LSTMCharEmbedding(TokenEmbedding): | |||||
:param activation: 激活函数,支持'relu', 'sigmoid', 'tanh', 或者自定义函数. | :param activation: 激活函数,支持'relu', 'sigmoid', 'tanh', 或者自定义函数. | ||||
:param min_char_freq: character的最小出现次数。默认值为2. | :param min_char_freq: character的最小出现次数。默认值为2. | ||||
:param bidirectional: 是否使用双向的LSTM进行encode。默认值为True。 | :param bidirectional: 是否使用双向的LSTM进行encode。默认值为True。 | ||||
:param pre_train_char_embed:可以有两种方式调用预训练好的character embedding:第一种是传入embedding文件夹(文件夹下应该只有一个 | |||||
以.txt作为后缀的文件)或文件路径;第二种是传入embedding的名称,第二种情况将自动查看缓存中是否存在该模型,没有的话将自动下载。 | |||||
如果输入为None则使用embedding_dim的维度随机初始化一个embedding. | |||||
:param pre_train_char_embed: 可以有两种方式调用预训练好的character embedding:第一种是传入embedding文件夹 | |||||
(文件夹下应该只有一个以.txt作为后缀的文件)或文件路径;第二种是传入embedding的名称,第二种情况将自动查看缓存中是否存在该模型, | |||||
没有的话将自动下载。如果输入为None则使用embedding_dim的维度随机初始化一个embedding. | |||||
""" | """ | ||||
def __init__(self, vocab: Vocabulary, embed_size: int=50, char_emb_size: int=50, word_dropout:float=0, | def __init__(self, vocab: Vocabulary, embed_size: int=50, char_emb_size: int=50, word_dropout:float=0, | ||||
dropout:float=0.5, hidden_size=50,pool_method: str='max', activation='relu', min_char_freq: int=2, | dropout:float=0.5, hidden_size=50,pool_method: str='max', activation='relu', min_char_freq: int=2, | ||||
@@ -31,7 +31,7 @@ def get_embeddings(init_embed): | |||||
:param init_embed: 可以是 tuple:(num_embedings, embedding_dim), 即embedding的大小和每个词的维度;也可以传入 | :param init_embed: 可以是 tuple:(num_embedings, embedding_dim), 即embedding的大小和每个词的维度;也可以传入 | ||||
nn.Embedding 对象, 此时就以传入的对象作为embedding; 传入np.ndarray也行,将使用传入的ndarray作为作为Embedding初始化; | nn.Embedding 对象, 此时就以传入的对象作为embedding; 传入np.ndarray也行,将使用传入的ndarray作为作为Embedding初始化; | ||||
传入torch.Tensor, 将使用传入的值作为Embedding初始化。 | 传入torch.Tensor, 将使用传入的值作为Embedding初始化。 | ||||
:return nn.Embedding embeddings: | |||||
:return nn.Embedding: embeddings | |||||
""" | """ | ||||
if isinstance(init_embed, tuple): | if isinstance(init_embed, tuple): | ||||
res = nn.Embedding( | res = nn.Embedding( | ||||
@@ -15,7 +15,9 @@ __all__ = [ | |||||
'DataBundle', | 'DataBundle', | ||||
'EmbedLoader', | 'EmbedLoader', | ||||
'Loader', | |||||
'YelpLoader', | 'YelpLoader', | ||||
'YelpFullLoader', | 'YelpFullLoader', | ||||
'YelpPolarityLoader', | 'YelpPolarityLoader', | ||||
@@ -29,7 +31,6 @@ __all__ = [ | |||||
'OntoNotesNERLoader', | 'OntoNotesNERLoader', | ||||
'CTBLoader', | 'CTBLoader', | ||||
'Loader', | |||||
'CSVLoader', | 'CSVLoader', | ||||
'JsonLoader', | 'JsonLoader', | ||||
@@ -110,9 +110,14 @@ def _uncompress(src, dst): | |||||
class DataBundle: | class DataBundle: | ||||
""" | """ | ||||
经过处理的数据信息,包括一系列数据集(比如:分开的训练集、验证集和测试集)以及各个field对应的vocabulary。该对象一般由fastNLP中各种 | 经过处理的数据信息,包括一系列数据集(比如:分开的训练集、验证集和测试集)以及各个field对应的vocabulary。该对象一般由fastNLP中各种 | ||||
DataSetLoader的load函数生成,可以通过以下的方法获取里面的内容 | |||||
Loader的load函数生成,可以通过以下的方法获取里面的内容 | |||||
Example:: | Example:: | ||||
data_bundle = YelpLoader().load({'train':'/path/to/train', 'dev': '/path/to/dev'}) | |||||
train_vocabs = data_bundle.vocabs['train'] | |||||
train_data = data_bundle.datasets['train'] | |||||
dev_data = data_bundle.datasets['train'] | |||||
:param vocabs: 从名称(字符串)到 :class:`~fastNLP.Vocabulary` 类型的dict | :param vocabs: 从名称(字符串)到 :class:`~fastNLP.Vocabulary` 类型的dict | ||||
:param datasets: 从名称(字符串)到 :class:`~fastNLP.DataSet` 类型的dict | :param datasets: 从名称(字符串)到 :class:`~fastNLP.DataSet` 类型的dict | ||||
@@ -76,29 +76,7 @@ class ConllLoader(DataSetLoader): | |||||
读取的field根据ConllLoader初始化时传入的headers决定。 | 读取的field根据ConllLoader初始化时传入的headers决定。 | ||||
:param Union[str, Dict[str, str]] paths: 支持以下的几种输入方式 | |||||
(1) 传入一个目录, 该目录下名称包含train的被认为是train,包含test的被认为是test,包含dev的被认为是dev,如果检测到多个文件 | |||||
名包含'train'、 'dev'、 'test'则会报错 | |||||
Example:: | |||||
data_bundle = ConllLoader().load('/path/to/dir') # 返回的DataBundle中datasets根据目录下是否检测到train, dev, test等有所变化 | |||||
# 可以通过以下的方式取出DataSet | |||||
tr_data = data_bundle.datasets['train'] | |||||
te_data = data_bundle.datasets['test'] # 如果目录下有文件包含test这个字段 | |||||
(2) 传入文件path | |||||
Example:: | |||||
data_bundle = ConllLoader().load("/path/to/a/train.conll") # 返回DataBundle对象, datasets中仅包含'train' | |||||
tr_data = data_bundle.datasets['train'] # 可以通过以下的方式取出DataSet | |||||
(3) 传入一个dict,比如train,dev,test不在同一个目录下,或者名称中不包含train, dev, test | |||||
Example:: | |||||
paths = {'train':"/path/to/tr.conll", 'dev':"/to/validate.conll", "test":"/to/te.conll"} | |||||
data_bundle = ConllLoader().load(paths) # 返回的DataBundle中的dataset中包含"train", "dev", "test" | |||||
dev_data = data_bundle.datasets['dev'] | |||||
:param Union[str, Dict[str, str]] paths: | |||||
:return: :class:`~fastNLP.DataSet` 类的对象或 :class:`~fastNLP.io.DataBundle` 的字典 | :return: :class:`~fastNLP.DataSet` 类的对象或 :class:`~fastNLP.io.DataBundle` 的字典 | ||||
""" | """ | ||||
paths = check_loader_paths(paths) | paths = check_loader_paths(paths) | ||||
@@ -10,6 +10,7 @@ class Loader: | |||||
各种数据 Loader 的基类,提供了 API 的参考. | 各种数据 Loader 的基类,提供了 API 的参考. | ||||
""" | """ | ||||
def __init__(self): | def __init__(self): | ||||
pass | pass | ||||
@@ -24,7 +25,7 @@ class Loader: | |||||
def load(self, paths: Union[str, Dict[str, str]] = None) -> DataBundle: | def load(self, paths: Union[str, Dict[str, str]] = None) -> DataBundle: | ||||
""" | """ | ||||
从指定一个或多个路径中的文件中读取数据,返回:class:`~fastNLP.io.DataBundle` 。 | |||||
从指定一个或多个路径中的文件中读取数据,返回 :class:`~fastNLP.io.DataBundle` 。 | |||||
读取的field根据ConllLoader初始化时传入的headers决定。 | 读取的field根据ConllLoader初始化时传入的headers决定。 | ||||
@@ -59,7 +60,7 @@ class Loader: | |||||
data_bundle = DataBundle(datasets=datasets) | data_bundle = DataBundle(datasets=datasets) | ||||
return data_bundle | return data_bundle | ||||
def download(self)->str: | |||||
def download(self) -> str: | |||||
""" | """ | ||||
自动下载该数据集 | 自动下载该数据集 | ||||
@@ -10,6 +10,7 @@ from .base_model import BaseModel | |||||
from ..core.const import Const | from ..core.const import Const | ||||
from ..modules.encoder import BertModel | from ..modules.encoder import BertModel | ||||
from ..modules.encoder.bert import BertConfig, CONFIG_FILE | from ..modules.encoder.bert import BertConfig, CONFIG_FILE | ||||
from ..core.utils import seq_len_to_mask | |||||
class BertForSequenceClassification(BaseModel): | class BertForSequenceClassification(BaseModel): | ||||
@@ -70,6 +71,10 @@ class BertForSequenceClassification(BaseModel): | |||||
return model | return model | ||||
def forward(self, words, seq_len=None, target=None): | def forward(self, words, seq_len=None, target=None): | ||||
if seq_len is None: | |||||
seq_len = torch.ones_like(words, dtype=words.dtype, device=words.device) | |||||
if len(seq_len.size()) + 1 == len(words.size()): | |||||
seq_len = seq_len_to_mask(seq_len, max_len=words.size(-1)) | |||||
_, pooled_output = self.bert(words, attention_mask=seq_len, output_all_encoded_layers=False) | _, pooled_output = self.bert(words, attention_mask=seq_len, output_all_encoded_layers=False) | ||||
pooled_output = self.dropout(pooled_output) | pooled_output = self.dropout(pooled_output) | ||||
logits = self.classifier(pooled_output) | logits = self.classifier(pooled_output) | ||||
@@ -2,7 +2,8 @@ import unittest | |||||
import torch | import torch | ||||
from fastNLP.models.bert import * | |||||
from fastNLP.models.bert import BertForSequenceClassification, BertForQuestionAnswering, \ | |||||
BertForTokenClassification, BertForMultipleChoice | |||||
class TestBert(unittest.TestCase): | class TestBert(unittest.TestCase): | ||||
@@ -14,9 +15,14 @@ class TestBert(unittest.TestCase): | |||||
input_ids = torch.LongTensor([[31, 51, 99], [15, 5, 0]]) | input_ids = torch.LongTensor([[31, 51, 99], [15, 5, 0]]) | ||||
input_mask = torch.LongTensor([[1, 1, 1], [1, 1, 0]]) | input_mask = torch.LongTensor([[1, 1, 1], [1, 1, 0]]) | ||||
token_type_ids = torch.LongTensor([[0, 0, 1], [0, 1, 0]]) | |||||
pred = model(input_ids, token_type_ids, input_mask) | |||||
pred = model(input_ids, input_mask) | |||||
self.assertTrue(isinstance(pred, dict)) | |||||
self.assertTrue(Const.OUTPUT in pred) | |||||
self.assertEqual(tuple(pred[Const.OUTPUT].shape), (2, 2)) | |||||
input_mask = torch.LongTensor([3, 2]) | |||||
pred = model(input_ids, input_mask) | |||||
self.assertTrue(isinstance(pred, dict)) | self.assertTrue(isinstance(pred, dict)) | ||||
self.assertTrue(Const.OUTPUT in pred) | self.assertTrue(Const.OUTPUT in pred) | ||||
self.assertEqual(tuple(pred[Const.OUTPUT].shape), (2, 2)) | self.assertEqual(tuple(pred[Const.OUTPUT].shape), (2, 2)) | ||||