当前位置:   article > 正文

文本分类(三) | (4)模型及其配置的定义(基于预训练语言模型)_bert+dpcnn

bert+dpcnn

完整项目​​​​​​​

本篇博客,主要介绍各个模型的模块定义,包括模型本身的定义以及模型对应的配置(超参数)的定义,二者在一个模块文件中。

目录

1. bert

2. bert+CNN

3. bert+RNN

4. bert+RCNN

5. bert+DPCNN

6. ERNIE


 

1. bert

  • 配置类
  1. class Config(object):
  2. """配置参数"""
  3. def __init__(self, dataset):
  4. self.model_name = 'bert'
  5. #训练集、验证集、测试集路径
  6. self.train_path = dataset + '/data/train.txt'
  7. self.dev_path = dataset + '/data/dev.txt'
  8. self.test_path = dataset + '/data/test.txt'
  9. #类别名单
  10. self.class_list = [x.strip() for x in open(
  11. dataset + '/data/class.txt').readlines()]
  12. #存储模型的训练结果
  13. self.save_path = dataset + '/saved_dict/' + self.model_name + '.ckpt'
  14. self.device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') # 设备
  15. self.require_improvement = 1000 # 若超过1000batch效果还没提升,则提前结束训练
  16. self.num_classes = len(self.class_list) # 类别数
  17. self.num_epochs = 3 # epoch数
  18. self.batch_size = 128 # mini-batch大小
  19. self.pad_size = 32 # 每句话处理成的长度(短填长切)
  20. self.learning_rate = 5e-5 # 学习率
  21. #预训练模型相关文件(模型文件.bin、配置文件.json、词表文件vocab.txt)存储路径
  22. self.bert_path = './bert_pretrain'
  23. #序列切分工具
  24. self.tokenizer = BertTokenizer.from_pretrained(self.bert_path)
  25. #隐藏单元数
  26. self.hidden_size = 768
  • 模型定义类
  1. class Model(nn.Module):
  2. def __init__(self, config):
  3. super(Model, self).__init__()
  4. #加载bert预训练模型
  5. self.bert = BertModel.from_pretrained(config.bert_path)
  6. #微调
  7. for param in self.bert.parameters():
  8. param.requires_grad = True #finetuning
  9. #输出层
  10. self.fc = nn.Linear(config.hidden_size, config.num_classes)
  11. def forward(self, x):
  12. context = x[0] # 输入的句子 (batch,seq_len)
  13. mask = x[2] # 对padding部分进行mask,和句子一个size,padding部分用0表示,如:[1, 1, 1, 1, 0, 0]
  14. _, pooled = self.bert(context, attention_mask=mask, output_all_encoded_layers=False) #pooled (batch,hidden_size) cls对应的最后一层的编码向量
  15. out = self.fc(pooled) #(batch,classes)
  16. return out

2. bert+CNN

  • 配置类
  1. class Config(object):
  2. """配置参数"""
  3. def __init__(self, dataset):
  4. self.model_name = 'bert'
  5. # 训练集、验证集、测试集路径
  6. self.train_path = dataset + '/data/train.txt'
  7. self.dev_path = dataset + '/data/dev.txt'
  8. self.test_path = dataset + '/data/test.txt'
  9. # 类别名单
  10. self.class_list = [x.strip() for x in open(
  11. dataset + '/data/class.txt').readlines()]
  12. # 存储模型的训练结果
  13. self.save_path = dataset + '/saved_dict/' + self.model_name + '.ckpt'
  14. self.device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') # 设备
  15. self.require_improvement = 1000 # 若超过1000batch效果还没提升,则提前结束训练
  16. self.num_classes = len(self.class_list) # 类别数
  17. self.num_epochs = 3 # epoch数
  18. self.batch_size = 128 # mini-batch大小
  19. self.pad_size = 32 # 每句话处理成的长度(短填长切)
  20. self.learning_rate = 5e-5 # 学习率
  21. # 预训练模型相关文件(模型文件.bin、配置文件.json、词表文件vocab.txt)存储路径
  22. self.bert_path = './bert_pretrain'
  23. # 序列切分工具
  24. self.tokenizer = BertTokenizer.from_pretrained(self.bert_path)
  25. # 隐藏单元数
  26. self.hidden_size = 768
  27. self.filter_sizes = (2, 3, 4) # 不同大小卷积核尺寸
  28. self.num_filters = 256 # 不同大小卷积核数量(channels数)
  29. self.dropout = 0.1 #丢弃率
  • 模型定义类
  1. class Model(nn.Module):
  2. def __init__(self, config):
  3. super(Model, self).__init__()
  4. # 加载bert预训练模型
  5. self.bert = BertModel.from_pretrained(config.bert_path)
  6. # 微调
  7. for param in self.bert.parameters():
  8. param.requires_grad = True
  9. #不同大小卷积核的2d卷积操作
  10. self.convs = nn.ModuleList(
  11. [nn.Conv2d(1, config.num_filters, (k, config.hidden_size)) for k in config.filter_sizes])
  12. self.dropout = nn.Dropout(config.dropout)
  13. self.fc_cnn = nn.Linear(config.num_filters * len(config.filter_sizes), config.num_classes)
  14. def conv_and_pool(self, x, conv):
  15. x = F.relu(conv(x)).squeeze(3)#(batch,num_filters,height)
  16. x = F.max_pool1d(x, x.size(2)).squeeze(2) #(batch,num_filters) 全局最大池化
  17. return x
  18. def forward(self, x):
  19. context = x[0] # 输入的句子 (batch,seq_len)
  20. mask = x[2] # 对padding部分进行mask,和句子一个size,padding部分用0表示,如:[1, 1, 1, 1, 0, 0]
  21. #encoder_out (batch,seq_len,hidden_size) 最后一层 各个时刻/token对应的编码向量
  22. #text_cls (batch,hidden_size) 最后一层 cls token对应的编码向量
  23. encoder_out, text_cls = self.bert(context, attention_mask=mask, output_all_encoded_layers=False)
  24. out = encoder_out.unsqueeze(1) #添加通道维 方便2d卷积 (batch,1,seq_len,hidden_size)
  25. out = torch.cat([self.conv_and_pool(out, conv) for conv in self.convs], 1) #(batch,num_filters*len(filter_sizes)
  26. out = self.dropout(out)
  27. out = self.fc_cnn(out) #(batch,classes)
  28. return out

 

3. bert+RNN

  • 配置类
  1. class Config(object):
  2. """配置参数"""
  3. def __init__(self, dataset):
  4. self.model_name = 'bert'
  5. # 训练集、验证集、测试集路径
  6. self.train_path = dataset + '/data/train.txt'
  7. self.dev_path = dataset + '/data/dev.txt'
  8. self.test_path = dataset + '/data/test.txt'
  9. # 类别名单
  10. self.class_list = [x.strip() for x in open(
  11. dataset + '/data/class.txt').readlines()]
  12. # 存储模型的训练结果
  13. self.save_path = dataset + '/saved_dict/' + self.model_name + '.ckpt'
  14. self.device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') # 设备
  15. self.require_improvement = 1000 # 若超过1000batch效果还没提升,则提前结束训练
  16. self.num_classes = len(self.class_list) # 类别数
  17. self.num_epochs = 3 # epoch数
  18. self.batch_size = 128 # mini-batch大小
  19. self.pad_size = 32 # 每句话处理成的长度(短填长切)
  20. self.learning_rate = 5e-5 # 学习率
  21. # 预训练模型相关文件(模型文件.bin、配置文件.json、词表文件vocab.txt)存储路径
  22. self.bert_path = './bert_pretrain'
  23. # 序列切分工具
  24. self.tokenizer = BertTokenizer.from_pretrained(self.bert_path)
  25. # 隐藏单元数
  26. self.hidden_size = 768
  27. self.dropout = 0.1 #丢弃率
  28. self.rnn_hidden = 768 #rnn隐藏单元数
  29. self.num_layers = 2 #rnn层数
  • 模型定义类
  1. class Model(nn.Module):
  2. def __init__(self, config):
  3. super(Model, self).__init__()
  4. # 加载bert预训练模型
  5. self.bert = BertModel.from_pretrained(config.bert_path)
  6. # 微调
  7. for param in self.bert.parameters():
  8. param.requires_grad = True
  9. #两层双向lstm batch_size 为第一维度
  10. self.lstm = nn.LSTM(config.hidden_size, config.rnn_hidden, config.num_layers,
  11. bidirectional=True, batch_first=True, dropout=config.dropout)
  12. self.dropout = nn.Dropout(config.dropout)
  13. self.fc_rnn = nn.Linear(config.rnn_hidden * 2, config.num_classes)
  14. def forward(self, x):
  15. context = x[0] # 输入的句子 (batch,seq_len)
  16. mask = x[2] # 对padding部分进行mask,和句子一个size,padding部分用0表示,如:[1, 1, 1, 1, 0, 0]
  17. # encoder_out (batch,seq_len,hidden_size) 最后一层 各个时刻/token对应的编码向量
  18. # text_cls (batch,hidden_size) 最后一层 cls token对应的编码向量
  19. encoder_out, text_cls = self.bert(context, attention_mask=mask, output_all_encoded_layers=False)
  20. out, _ = self.lstm(encoder_out) #(batch,seq_len,rnn_hidden_size*2)
  21. out = self.dropout(out)
  22. out = self.fc_rnn(out[:, -1, :]) # 句子最后时刻的 hidden state (batch,classes)
  23. return out

4. bert+RCNN

  • 配置类
  1. class Config(object):
  2. """配置参数"""
  3. def __init__(self, dataset):
  4. # 训练集、验证集、测试集路径
  5. self.train_path = dataset + '/data/train.txt'
  6. self.dev_path = dataset + '/data/dev.txt'
  7. self.test_path = dataset + '/data/test.txt'
  8. # 类别名单
  9. self.class_list = [x.strip() for x in open(
  10. dataset + '/data/class.txt').readlines()]
  11. # 存储模型的训练结果
  12. self.save_path = dataset + '/saved_dict/' + self.model_name + '.ckpt'
  13. self.device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') # 设备
  14. self.require_improvement = 1000 # 若超过1000batch效果还没提升,则提前结束训练
  15. self.num_classes = len(self.class_list) # 类别数
  16. self.num_epochs = 3 # epoch数
  17. self.batch_size = 128 # mini-batch大小
  18. self.pad_size = 32 # 每句话处理成的长度(短填长切)
  19. self.learning_rate = 5e-5 # 学习率
  20. # 预训练模型相关文件(模型文件.bin、配置文件.json、词表文件vocab.txt)存储路径
  21. self.bert_path = './bert_pretrain'
  22. # 序列切分工具
  23. self.tokenizer = BertTokenizer.from_pretrained(self.bert_path)
  24. # 隐藏单元数
  25. self.hidden_size = 768
  26. self.dropout = 0.1
  27. self.rnn_hidden = 256 #rnn 隐藏单元数
  28. self.num_layers = 2 #rnn层数
  • 模型定义类
  1. class Model(nn.Module):
  2. def __init__(self, config):
  3. super(Model, self).__init__()
  4. # 加载bert预训练模型
  5. self.bert = BertModel.from_pretrained(config.bert_path)
  6. # 微调
  7. for param in self.bert.parameters():
  8. param.requires_grad = True
  9. # 两层双向lstm batch_size 为第一维度
  10. self.lstm = nn.LSTM(config.hidden_size, config.rnn_hidden, config.num_layers,
  11. bidirectional=True, batch_first=True, dropout=config.dropout)
  12. self.maxpool = nn.MaxPool1d(config.pad_size) #1维全局最大池化
  13. self.fc = nn.Linear(config.rnn_hidden * 2 + config.hidden_size, config.num_classes)
  14. def forward(self, x):
  15. context = x[0] # 输入的句子 (batch,seq_len)
  16. mask = x[2] # 对padding部分进行mask,和句子一个size,padding部分用0表示,如:[1, 1, 1, 1, 0, 0]
  17. # encoder_out (batch,seq_len,hidden_size) 最后一层 各个时刻/token对应的编码向量
  18. # text_cls (batch,hidden_size) 最后一层 cls token对应的编码向量
  19. encoder_out, text_cls = self.bert(context, attention_mask=mask, output_all_encoded_layers=False)
  20. out, _ = self.lstm(encoder_out) #(batch,seq_len,rnn_hidden_size*2)
  21. out = torch.cat((encoder_out, out), 2) #(batch,seq_len,hidden_size+rnn_hidden_size*2)
  22. out = F.relu(out)
  23. out = out.permute(0, 2, 1) #(batch,hidden_size+rnn_hidden_size*2,seq_len) 把隐藏状态维提前 作为通道维 对seq_len维作全局最大池化
  24. out = self.maxpool(out).squeeze() #(batch,hidden_size+rnn_hidden_size*2)
  25. out = self.fc(out) #(batch,classes)
  26. return out

5. bert+DPCNN

  • 配置类
  1. class Config(object):
  2. """配置参数"""
  3. def __init__(self, dataset):
  4. self.model_name = 'bert'
  5. # 训练集、验证集、测试集路径
  6. self.train_path = dataset + '/data/train.txt'
  7. self.dev_path = dataset + '/data/dev.txt'
  8. self.test_path = dataset + '/data/test.txt'
  9. # 类别名单
  10. self.class_list = [x.strip() for x in open(
  11. dataset + '/data/class.txt').readlines()]
  12. # 存储模型的训练结果
  13. self.save_path = dataset + '/saved_dict/' + self.model_name + '.ckpt'
  14. self.device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') # 设备
  15. self.require_improvement = 1000 # 若超过1000batch效果还没提升,则提前结束训练
  16. self.num_classes = len(self.class_list) # 类别数
  17. self.num_epochs = 3 # epoch数
  18. self.batch_size = 128 # mini-batch大小
  19. self.pad_size = 32 # 每句话处理成的长度(短填长切)
  20. self.learning_rate = 5e-5 # 学习率
  21. # 预训练模型相关文件(模型文件.bin、配置文件.json、词表文件vocab.txt)存储路径
  22. self.bert_path = './bert_pretrain'
  23. # 序列切分工具
  24. self.tokenizer = BertTokenizer.from_pretrained(self.bert_path)
  25. # 隐藏单元数
  26. self.hidden_size = 768
  27. self.num_filters = 250 # 卷积核数量(channels数)
  • 模型定义类
  1. class Model(nn.Module):
  2. def __init__(self, config):
  3. super(Model, self).__init__()
  4. # 加载bert预训练模型
  5. self.bert = BertModel.from_pretrained(config.bert_path)
  6. # 微调
  7. for param in self.bert.parameters():
  8. param.requires_grad = True
  9. # self.fc = nn.Linear(config.hidden_size, config.num_classes)
  10. # region embedding 类似于TextCNN中的卷积操作
  11. self.conv_region = nn.Conv2d(1, config.num_filters, (3, config.hidden_size), stride=1)
  12. self.conv = nn.Conv2d(config.num_filters, config.num_filters, (3, 1), stride=1)
  13. self.max_pool = nn.MaxPool2d(kernel_size=(3, 1), stride=2)
  14. self.padding1 = nn.ZeroPad2d((0, 0, 1, 1)) # top bottom 上下各添一个0
  15. self.padding2 = nn.ZeroPad2d((0, 0, 0, 1)) # bottom 下添一个0
  16. self.relu = nn.ReLU()
  17. self.fc = nn.Linear(config.num_filters, config.num_classes)
  18. def forward(self, x):
  19. context = x[0] # 输入的句子 (batch,seq_len)
  20. mask = x[2] # 对padding部分进行mask,和句子一个size,padding部分用0表示,如:[1, 1, 1, 1, 0, 0]
  21. # encoder_out (batch,seq_len,hidden_size) 最后一层 各个时刻/token对应的编码向量
  22. # text_cls (batch,hidden_size) 最后一层 cls token对应的编码向量
  23. encoder_out, text_cls = self.bert(context, attention_mask=mask, output_all_encoded_layers=False)
  24. x = encoder_out.unsqueeze(1) # [batch_size, 1, seq_len, hidden_size] 增加通道维 方便2d卷积
  25. x = self.conv_region(x) # [batch_size, num_filters, seq_len-3+1, 1]
  26. #等长卷积 序列长度不变 通过卷积和填充操作实现
  27. #激活函数在卷积操作之前
  28. x = self.padding1(x) # [batch_size, num_filters, seq_len, 1]
  29. x = self.relu(x)
  30. x = self.conv(x) # [batch_size, num_filters, seq_len-3+1, 1]
  31. x = self.padding1(x) # [batch_size, num_filters, seq_len, 1]
  32. x = self.relu(x)
  33. x = self.conv(x) # [batch_size, num_filters, seq_len-3+1, 1]
  34. while x.size()[2] > 2: #序列长度>2 则不停循环下列操作
  35. x = self._block(x)
  36. x = x.squeeze() # [batch_size, num_filters(250)]
  37. x = self.fc(x)
  38. return x
  39. def _block(self, x): #x [batch_size, num_filters, seq_len-3+1, 1]
  40. x = self.padding2(x) #[batch_size, num_filters, seq_len-1, 1]
  41. px = self.max_pool(x) #序列长度减半 [batch_size, num_filters, (seq_len-1)/2, 1]
  42. # 等长卷积 序列长度不变 通过卷积和填充操作实现
  43. # 激活函数在卷积操作之前
  44. x = self.padding1(px)
  45. x = F.relu(x)
  46. x = self.conv(x)
  47. x = self.padding1(x)
  48. x = F.relu(x)
  49. x = self.conv(x) #[batch_size, num_filters, (seq_len-1)/2, 1]
  50. x = x + px # short cut
  51. return x

6. ERNIE

  • 配置类
  1. class Config(object):
  2. """配置参数"""
  3. def __init__(self, dataset):
  4. self.model_name = 'ERNIE'
  5. # 训练集、验证集、测试集路径
  6. self.train_path = dataset + '/data/train.txt'
  7. self.dev_path = dataset + '/data/dev.txt'
  8. self.test_path = dataset + '/data/test.txt'
  9. # 类别名单
  10. self.class_list = [x.strip() for x in open(
  11. dataset + '/data/class.txt').readlines()]
  12. # 存储模型的训练结果
  13. self.save_path = dataset + '/saved_dict/' + self.model_name + '.ckpt'
  14. self.device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') # 设备
  15. self.require_improvement = 1000 # 若超过1000batch效果还没提升,则提前结束训练
  16. self.num_classes = len(self.class_list) # 类别数
  17. self.num_epochs = 3 # epoch数
  18. self.batch_size = 128 # mini-batch大小
  19. self.pad_size = 32 # 每句话处理成的长度(短填长切)
  20. self.learning_rate = 5e-5 # 学习率
  21. # 预训练模型相关文件(模型文件.bin、配置文件.json、词表文件vocab.txt)存储路径
  22. self.bert_path = './ERNIE_pretrain'
  23. # 序列切分工具
  24. self.tokenizer = BertTokenizer.from_pretrained(self.bert_path)
  25. print(self.tokenizer)
  26. # 隐藏单元数
  27. self.hidden_size = 768
  • 模型定义类
  1. class Model(nn.Module):
  2. def __init__(self, config):
  3. super(Model, self).__init__()
  4. # 加载ERNIE预训练模型
  5. self.bert = BertModel.from_pretrained(config.bert_path)
  6. # 微调
  7. for param in self.bert.parameters():
  8. param.requires_grad = True # finetuning
  9. # 输出层
  10. self.fc = nn.Linear(config.hidden_size, config.num_classes)
  11. def forward(self, x):
  12. context = x[0] # 输入的句子 (batch,seq_len)
  13. mask = x[2] # 对padding部分进行mask,和句子一个size,padding部分用0表示,如:[1, 1, 1, 1, 0, 0]
  14. _, pooled = self.bert(context, attention_mask=mask,
  15. output_all_encoded_layers=False) # pooled (batch,hidden_size) cls对应的最后一层的编码向量
  16. out = self.fc(pooled) # (batch,classes)
  17. return out

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/719619
推荐阅读
相关标签
  

闽ICP备14008679号