基于textCNN的文本分类模型(论文复现+优化)
一、模型架构
此文章主要总结个人复现textCNN
模型的一些知识并且做了一些优化。整个的模型架构如下所示
整个架构大体上包括三个部分:
- 输入层,将数据集语句通过
Embedding
的方式构建成一个二维的矩阵; CNN + activate + max_pooling
块,核心部分,输入的数据通过三个这样的块,得到三组特征,一组特征包含2个(论文中为2,实际上此值等于卷积层中隐藏层的个数)- 第三部分是一个线性分类器,根据类别数量的不同设置不同的输出
二、代码复现
代码复现也包括三部分:
- 数据处理,包括如何读取数据集、建立词表以及构建数据集类
- 模型架构构建
- 模型训练与调参
下面展开介绍,数据集需要的话可以私信联系。
数据处理
def read_data(file_name, data_num=None):
texts = []
labels = []
with open(os.path.join("..", "data", file_name + ".txt"),"r", encoding="utf-8") as f:
all_data = f.read().split("\n")
for data in all_data:
if data == "":
continue
text, label = data.split("\t")
texts.append(text)
labels.append(label)
if data_num is None:
return texts, labels
return texts[:data_num], labels[:data_num]
这段代码实现了将文本数据读入两个列表中:texts
和labels
,用于构建词典。
def build_corpus(texts, embed_size):
word2idx = {"PAD":0, "UNK":1}
for text in texts:
for word in text:
if word2idx.get(word) is None:
word2idx[word] = len(word2idx)
return word2idx, nn.Embedding(len(word2idx), embed_size)
这段代码通过传入文本构建出词表,并且预先给定了两个词<PAD>和<UNK>
用于表示特殊的填充和不明字,随后通过字典的get
方法构建词典。
构建数据集类
#构建数据集
class TextDataset(Dataset):
def __init__(self, word2idx, texts, labels, max_len) -> None:
super().__init__()
self.texts = texts
self.labels = labels
self.word2idx = word2idx
self.max_len = max_len
def __getitem__(self, index):
text = self.texts[index][:self.max_len]
label = int(self.labels[index])
text_idx = [self.word2idx.get(t,1) for t in text]
text_idx = text_idx + [0] * (self.max_len - len(text_idx))
text_idx = torch.Tensor(text_idx).unsqueeze(0) # 新增一个维度
return text_idx, label
def __len__(self):
return len(self.texts)
算了,就先写到这儿吧,反正也没啥人看hhh