Tabla de contenido
Introducción Introducción
Basado en el marco PyTorch, este documento implementa 6 modelos clásicos de clasificación de texto chino de aprendizaje profundo.Estos modelos incluyen Bert y ERNIE basados en el modelo Transformer, y bert_CNN y bert_RNN que combinan redes neuronales convolucionales, redes neuronales cíclicas y redes neuronales convolucionales piramidales profundas. ., bert_RCNN y bert_DPCNN, y comparó el entrenamiento y los resultados de cada modelo.
Primero, este documento proporciona una descripción detallada del conjunto de datos, incluida la fuente del conjunto de datos, el método de preprocesamiento y la forma en que se divide el conjunto de datos. De esta forma, el lector puede comprender las características del conjunto de datos y seguir las instrucciones para preparar y procesar los datos.
En cuanto a la construcción del entorno, proporcionamos las bibliotecas dependientes necesarias y las instrucciones de configuración del entorno para ayudar a los lectores a configurar correctamente el entorno y ejecutar el proyecto. Al mismo tiempo, teniendo en cuenta el tiempo de ejecución, también le brindamos pasos detallados para instalar la versión GPU de Pytorch .
Para cada modelo, proporcionamos instrucciones detalladas, incluida la estructura del modelo, el formato de los datos de entrada y los procedimientos de entrenamiento e inferencia. Estas descripciones ayudan al lector a comprender cómo funciona cada modelo y los detalles de implementación.
Finalmente, adjuntamos un informe detallado de los resultados de los entrenamientos y pruebas. Estos resultados pueden ayudar a los lectores a evaluar el rendimiento de cada modelo en tareas de clasificación de texto chino y hacer comparaciones y análisis.
A través de este artículo, los lectores pueden conocer los detalles de implementación y el rendimiento de varios modelos de clasificación de texto chino de aprendizaje profundo. Este proyecto no solo proporciona una referencia para los investigadores académicos, sino que también brinda a los desarrolladores y profesionales un código reutilizable y pautas experimentales para ayudarlos a lograr mejores resultados en las tareas de clasificación de texto chino.
conjunto de datos
Se extrajeron 200.000 titulares de noticias de THUCNews , con una longitud de texto entre 20 y 30. Hay 10 categorías en total, cada una con 20.000 entradas.
Ingrese el modelo en unidades de palabras, utilizando el vector de palabras previamente entrenado: Sogou News Word+Character 300d.
Categorías: Finanzas, Bienes Raíces, Acciones, Educación, Tecnología, Sociedad, Actualidad, Deportes, Juegos, Entretenimiento.
El conjunto de datos, el vocabulario y los vectores de palabras pre-entrenados correspondientes han sido empaquetados, consulte la THUCNews
carpeta en la dirección de Github a continuación para obtener más detalles.
Entorno de Python e instalación de los paquetes dependientes correspondientes
- pitón 3.7 o superior
- pytorch 1.1 o superior
- tqdm
- aprendió
- tensorboardX
- boto3
- expresiones regulares
Configuración del entorno Anaconda
-
Inicie sesión en el sitio web oficial de Anaconda , descargue e instale Anaconda
-
Luego abra la terminal e ingrese los siguientes comandos de la terminal en secuencia:
Nuevo ambiente:chinese_text_classification
conda create --name chinese_text_classification python==3.8.10
Activa el entorno:
conda activate chinese_text_classification
Ingrese los siguientes comandos a su vez para instalar los paquetes de python relevantes
conda install pytorch
conda install scikit-learn
conda install tqdm
conda install tensorboardX
conda install boto3
conda install regex
Tenga en cuenta que el pytorch instalado anteriormente es la versión de la CPU por defecto. Dado que los modelos bert y ERNIE de este artículo utilizan módulos relacionados con Transform, se recomienda instalar la versión GPU de pytorch .
Si desea instalar la versión GPU de pytorch, puede consultar los siguientes pasos:
Primero, asegúrese de haber instalado correctamente el controlador de gráficos NVIDIA y de que su tarjeta gráfica sea compatible con CUDA. Puede encontrar el controlador correspondiente y la información de compatibilidad de CUDA en el sitio web oficial de NVIDIA.
Antes de instalar PyTorch en un entorno de Python, debe instalar CUDAToolkit para su versión de CUDA. Puede descargar e instalar CUDAToolkit para su versión de CUDA desde el sitio web para desarrolladores de NVIDIA.
Después de completar los pasos anteriores, puede usar el siguiente comando para verificar su versión relacionada con GPU.
nvcc --version
Si no hay una versión anterior, debe verificar si CUDA y CUDAToolkit están instalados.
Luego, puede descargar la versión correspondiente de whl desde el sitio web de descarga de pytorch para la instalación, debido a que el archivo de pytorch de la versión gpu general es muy grande, no se recomienda usar pip para instalar directamente. Por ejemplo, el siguiente es el comando pytorch para instalar la versión gpu directamente usando pip, lo que demora aproximadamente 13 horas:
pip3 install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu117
Puede usar directamente el navegador para abrir el sitio web de descarga que aparece en la imagen de arriba: https://download.pytorch.org/whl/cu117 y seleccionar torch
para buscar las palabras clave en la imagen de arriba cu117-cp38-cp38-win_amd64.whl
. Haga clic para descargar. Generalmente, si la velocidad de la red es rápida, la descarga se puede completar en unos 10 minutos.
Después de que la descarga sea exitosa, puede usar directamente el siguiente comando para instalar:
pip install <path/to/your/whl/file.whl>
Reemplácelo <path/to/your/whl/file.whl>
con la ruta del archivo .wl real (p. ej.: pip install /path/to/your/file.whl
)
dirección del código fuente
Dirección de Github: https://github.com/649453932/Bert-Chinese-Text-Classification-Pytorch
Descarga del modelo de lenguaje preentrenado
Ya que tanto bert como ERNIE usan modelos pre-entrenados. Antes de ejecutar el proyecto, debe descargar los archivos de modelo previamente entrenados relevantes.
El modelo bert se coloca bert_pretain
en el directorio y el modelo ERNIE se coloca ERNIE_pretrain
en el directorio Hay tres archivos en cada directorio:
- modelo_pytorch .bin
- bert_config.json
- vocabulario.txt
Dirección de descarga del modelo previo al entrenamiento:
bert_Chinese: modelo https://s3.amazonaws.com/models.huggingface.co/bert/bert-base-chinese.tar.gz
vocabulario https://s3.amazonaws.com/models. huggingface.co/bert/bert-base-chinese-vocab.txt
Tenga en cuenta que después de descargar el archivo de vocabulario, se le cambiará el nombrevocab.txt
ERNIE_Chino: dirección de disco de red: https://pan.baidu.com/s/1lEPdDN1-YQJmKEd_g9rLgw
Después de la descompresión, colóquelo en el directorio correspondiente de acuerdo con lo anterior y confirme que el nombre del archivo es correcto.
Crear una nueva carpeta Saved_dict
saved_dict
Es necesario crear una nueva carpeta llamada THUCNews para guardar ckpt
los archivos del modelo después de cada entrenamiento.
Si no se crea, aparecerá el siguiente error:
Berto
BERT es un modelo de preentrenamiento propuesto por Google AI Research Institute en octubre de 2018. El nombre completo de BERT es Representación de codificador bidireccional de transformadores . BERT ha mostrado resultados sorprendentes en la prueba de nivel superior SQuAD1.1 de comprensión de lectura automática: ha superado a los humanos en las dos métricas y ha logrado el rendimiento de SOTA en 11 pruebas diferentes de NLP, incluido el aumento del punto de referencia GLUE al 80,4 % (mejora absoluta de 7,6). %), la precisión de MultiNLI alcanzó el 86,7 % (una mejora absoluta del 5,6 %), convirtiéndose en un hito en la historia del desarrollo de la PNL.
Descripcion del modelo
El modelo BERT se basa en el codificador de Transformer (codificador), y la estructura del modelo principal es el apilamiento de Transformer. Al mismo tiempo, Bert se refiere directamente al módulo Encoder en la arquitectura Transformer y descarta el módulo Decoder, de modo que automáticamente tiene capacidades de codificación bidireccional y potentes capacidades de extracción de funciones. Es una red Transformer bidireccional. En cierto sentido, BERT se enfoca más en la comprensión del idioma, no solo en la generación del idioma.
En BERT, el vector de entrada se suma mediante tres incrustaciones diferentes, a saber:
1) token embedding
: la representación vectorial de la palabra misma. Token se refiere a la división de palabras en un conjunto limitado de unidades de subpalabras comunes, que pueden lograr un compromiso entre la efectividad de las palabras y la flexibilidad de los caracteres.
2) position embedding
: codifica la información de posición de la palabra en un vector de características. Debido a que nuestra estructura de red no tiene RNN o LSTM, no podemos obtener la información de posición de la secuencia, por lo que necesitamos construir una incrustación de posición. Hay dos formas de construir la incrustación de posición: BERT inicializa una incrustación de posición y luego la aprende a través del entrenamiento, mientras que Transformer construye una incrustación de posición mediante la formulación de reglas.
3) segment embedding
: Representación vectorial para distinguir dos oraciones. Esto se usa para distinguir oraciones asimétricas como preguntas y respuestas.
En BERT, la salida se compone de cuatro partes:
(1) last_hidden_state
: la forma es (tamaño_de_lote, longitud_de_secuencia, tamaño_oculto), tamaño_oculto=768, que es el resultado de estado oculto de la última capa del modelo (usualmente usado para el reconocimiento de entidades nombradas).
(2) pooler_output
: la forma es (batch_size, hidden_size), que es el estado oculto de la última capa de la primera ficha (ficha de clasificación) de la secuencia, que es procesada posteriormente por la capa lineal y la función de activación de Tanh (usualmente utilizada para oraciones clasificación, en cuanto a si usar esta representación, o usar el promedio o la agrupación de la secuencia de estado oculto de la secuencia de entrada completa, según sea el caso).
(3) hidden_states
: esta es una opción opcional para la salida. Si la salida, debe especificar config.output_hidden_states=True, que también es una tupla. Su primer elemento es la incrustación, y el resto de los elementos son la salida de cada capa. Cada elemento La forma es (tamaño_lote, longitud_secuencia, tamaño_oculto).
(4) attentions
: Esta es también una opción para la salida. Si es una salida, debe especificar config.output_attentions=True, que también es una tupla, y sus elementos son los pesos de atención de cada capa, que se utilizan para calcular el peso de cabezas de autoatención valor promedio.
El diagrama esquemático es el siguiente:
ventaja:
La base de Bert se basa en el transformador, que tiene una potente representación del lenguaje y capacidades de extracción de funciones. Alcanzó el estado del arte en 11 tareas de referencia de PNL. Al mismo tiempo, demostró nuevamente que el modelo de lenguaje bidireccional es más poderoso.
Desventajas:
1) Mala reproducibilidad, básicamente imposible de hacer, ¡solo se puede usar directamente!
2) Durante el proceso de entrenamiento, debido a que solo el 15% de los datos en cada tamaño de lote participa en la predicción, ¡el modelo converge lentamente y requiere un potente soporte de potencia informática!
# coding: UTF-8
import torch
import torch.nn as nn
# from pytorch_pretrained_bert import BertModel, BertTokenizer
from pytorch_pretrained import BertModel, BertTokenizer
class Config(object):
"""配置参数"""
def __init__(self, dataset):
self.model_name = 'bert'
self.train_path = dataset + '/data/train.txt' # 训练集
self.dev_path = dataset + '/data/dev.txt' # 验证集
self.test_path = dataset + '/data/test.txt' # 测试集
self.class_list = [x.strip() for x in open(
dataset + '/data/class.txt').readlines()] # 类别名单
self.save_path = dataset + '/saved_dict/' + self.model_name + '.ckpt' # 模型训练结果
self.device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') # 设备
self.require_improvement = 1000 # 若超过1000batch效果还没提升,则提前结束训练
self.num_classes = len(self.class_list) # 类别数
self.num_epochs = 3 # epoch数
self.batch_size = 128 # mini-batch大小
self.pad_size = 32 # 每句话处理成的长度(短填长切)
self.learning_rate = 5e-5 # 学习率
self.bert_path = './bert_pretrain'
self.tokenizer = BertTokenizer.from_pretrained(self.bert_path)
self.hidden_size = 768
class Model(nn.Module):
def __init__(self, config):
super(Model, self).__init__()
self.bert = BertModel.from_pretrained(config.bert_path)
for param in self.bert.parameters():
param.requires_grad = True
self.fc = nn.Linear(config.hidden_size, config.num_classes)
def forward(self, x):
context = x[0] # 输入的句子
mask = x[2] # 对padding部分进行mask,和句子一个size,padding部分用0表示,如:[1, 1, 1, 1, 0, 0]
_, pooled = self.bert(context, attention_mask=mask, output_all_encoded_layers=False)
out = self.fc(pooled)
return out
Ejecute los siguientes comandos en la terminal para entrenamiento y prueba:
python run.py --model Bert
Los resultados del entrenamiento y las pruebas son los siguientes:
Usando la versión GPU de pytorch, tomó 32 minutos y 18 segundos, y la tasa de precisión fue del 94,48 %.
ERNIE
ERNIE (Representación mejorada a través de la integración del conocimiento) es un modelo de representación semántica propuesto por Baidu, también basado en Transformer Encoder. En comparación con BERT, su proceso de preentrenamiento utiliza un conocimiento semántico más rico y más tareas semánticas, y ha logrado mejores resultados que BERT y otros modelos en múltiples tareas de PNL.
ERNIE 1.0
ERNIE 1.0 aprende conocimiento semántico del mundo real al modelar palabras, entidades y relaciones entre entidades en datos masivos. En comparación con BERT que aprende la señal del idioma original, ERNIE 1.0 puede modelar directamente la unidad de conocimiento semántico anterior, lo que mejora la capacidad de representación semántica del modelo.
Una de las tareas de entrenamiento del modelo Bert es el modelo de lenguaje de máscara, que realiza marcas de máscara aleatorias en caracteres individuales (chino) y palabras (inglés) para predecir el valor de la máscara. El modelo de lenguaje enmascarado hace que Bert tenga buenos resultados, pero al mismo tiempo, el gran defecto es que rompe la relación entre palabras y palabras o palabras y palabras en una oración.
En respuesta a los defectos del modelo de Bert, el modelo de lenguaje de máscara máscara utilizado por ERNIE no es una sola palabra o palabra, sino una palabra, frase o entidad nombrada completa. Después de cubrir, predecir el todo, para que el modelo de lenguaje pueda entrenar mejor la información global y aprender resultados muy previos.
Después de mucho entrenamiento, Baidu entrenó un modelo de segmentación de palabras, un modelo de empalme de frases y un modelo de reconocimiento de entidades nombradas con mejores resultados, y marcó las palabras en el corpus por adelantado. (Esta idea se llama en el documento: fusión de conocimiento)
ERNIE2.0
La idea principal de ERNIE 2.0: aprender continuamente las tareas y conocimientos esperados en diferentes niveles, para mejorar la capacidad de modelado de la representación semántica del modelo ERNIE.
El modelo ERNIE 2.0 toma cuatro partes principales como entrada, a saber:
1. Incrustación de tokens: la incrustación del vector de palabra en sí
2. Incrustación de oraciones: la incrustación del tipo de oración
3. Incrustación de posiciones: la incrustación de la información de la posición
4. Incrustación de tareas: la incrustación de tareas modela diferentes tareas
Agregue las cuatro incrustaciones principales y el resultado final se usa como entrada de Transformer para entrenar diferentes subtareas. Las subtareas se dividen en tres categorías, a saber:
1.Tarea de preentrenamiento consciente de las palabras, tarea de preentrenamiento léxico,
2.Tarea de preentrenamiento consciente de la estructura, tarea de preentrenamiento estructural,
3.Tarea de preentrenamiento semántico, tarea de preentrenamiento semántico.
ERNIE 3.0
Comparar con ERNIE 2.0
- Mismo punto:
- aprendizaje continuo
- Tareas de pre-entrenamiento usando múltiples niveles semánticos
- diferencia:
- Codificador ERNIE 3.0 Transformer-XL (autoregresivo + codificador automático), Codificador ERNIE 2.0 Transformer (codificador automático)
- Los matices de las tareas previas a la formación, el mapa de conocimientos añadido en ERNIE3.0
- ERNIE 3.0 considera que las distintas tareas de formación previa tienen una semántica de alto nivel diferente, pero comparten la semántica subyacente (como la gramática, el vocabulario, etc.). Para aprovechar al máximo los datos y lograr una formación previa eficiente, ERNIE 3.0 utiliza entrenamiento multitarea Es una práctica común dividir diferentes capas de características en Representación universal y Representación específica de tareas.
Comparando ERNIE y Bert
El diagrama esquemático de ERNIE 2.0 es el siguiente:
El diagrama esquemático de ERNIE 3.0 es el siguiente:
# coding: UTF-8
import torch
import torch.nn as nn
# from pytorch_pretrained_bert import BertModel, BertTokenizer
from pytorch_pretrained import BertModel, BertTokenizer
class Config(object):
"""配置参数"""
def __init__(self, dataset):
self.model_name = 'ERNIE'
self.train_path = dataset + '/data/train.txt' # 训练集
self.dev_path = dataset + '/data/dev.txt' # 验证集
self.test_path = dataset + '/data/test.txt' # 测试集
self.class_list = [x.strip() for x in open(
dataset + '/data/class.txt').readlines()] # 类别名单
self.save_path = dataset + '/saved_dict/' + self.model_name + '.ckpt' # 模型训练结果
self.device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') # 设备
self.require_improvement = 1000 # 若超过1000batch效果还没提升,则提前结束训练
self.num_classes = len(self.class_list) # 类别数
self.num_epochs = 3 # epoch数
self.batch_size = 128 # mini-batch大小
self.pad_size = 32 # 每句话处理成的长度(短填长切)
self.learning_rate = 5e-5 # 学习率
self.bert_path = './ERNIE_pretrain'
self.tokenizer = BertTokenizer.from_pretrained(self.bert_path)
print(self.tokenizer)
self.hidden_size = 768
class Model(nn.Module):
def __init__(self, config):
super(Model, self).__init__()
self.bert = BertModel.from_pretrained(config.bert_path)
for param in self.bert.parameters():
param.requires_grad = True
self.fc = nn.Linear(config.hidden_size, config.num_classes)
def forward(self, x):
context = x[0] # 输入的句子
mask = x[2] # 对padding部分进行mask,和句子一个size,padding部分用0表示,如:[1, 1, 1, 1, 0, 0]
_, pooled = self.bert(context, attention_mask=mask, output_all_encoded_layers=False)
out = self.fc(pooled)
return out
Ejecute los siguientes comandos en la terminal para entrenamiento y prueba:
python run.py --model ERNIE
Los resultados del entrenamiento y las pruebas son los siguientes:
Usando la versión GPU de pytorch, tomó 30 minutos y 14 segundos, y la tasa de precisión fue del 94,67 %.
bert_CNN、bert_RNN、bert_RCNN、bert_DPCNN
Descripcion del modelo
- bert_CNN: envía a bert como una capa incrustada en el modelo de CNN
- bert_RNN: envía bert como una capa incrustada en el modelo RNN
- bert_RCNN: envía a bert como una capa incrustada en el modelo RCNN
- bert_DPCNN: envía bert como una capa incrustada en el modelo DPCNN
Para obtener descripciones detalladas y diagramas esquemáticos relacionados de los modelos CNN, RNN, RCNN y DPCNN, consulte mi otro blog para obtener más detalles: Práctica de PNL: Pytorch implementa 7 clasificaciones clásicas de texto chino de aprendizaje profundo: TextCNN+TextRNN+FastText+TextRCNN+TextRNN_Attention+DPCNN+ Transformer
código del modelo bert_CNN:
# coding: UTF-8
import torch
import torch.nn as nn
import torch.nn.functional as F
from pytorch_pretrained import BertModel, BertTokenizer
class Config(object):
"""配置参数"""
def __init__(self, dataset):
self.model_name = 'bert'
self.train_path = dataset + '/data/train.txt' # 训练集
self.dev_path = dataset + '/data/dev.txt' # 验证集
self.test_path = dataset + '/data/test.txt' # 测试集
self.class_list = [x.strip() for x in open(
dataset + '/data/class.txt').readlines()] # 类别名单
self.save_path = dataset + '/saved_dict/' + self.model_name + '.ckpt' # 模型训练结果
self.device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') # 设备
self.require_improvement = 1000 # 若超过1000batch效果还没提升,则提前结束训练
self.num_classes = len(self.class_list) # 类别数
self.num_epochs = 3 # epoch数
self.batch_size = 128 # mini-batch大小
self.pad_size = 32 # 每句话处理成的长度(短填长切)
self.learning_rate = 5e-5 # 学习率
self.bert_path = './bert_pretrain'
self.tokenizer = BertTokenizer.from_pretrained(self.bert_path)
self.hidden_size = 768
self.filter_sizes = (2, 3, 4) # 卷积核尺寸
self.num_filters = 256 # 卷积核数量(channels数)
self.dropout = 0.1
class Model(nn.Module):
def __init__(self, config):
super(Model, self).__init__()
self.bert = BertModel.from_pretrained(config.bert_path)
for param in self.bert.parameters():
param.requires_grad = True
self.convs = nn.ModuleList(
[nn.Conv2d(1, config.num_filters, (k, config.hidden_size)) for k in config.filter_sizes])
self.dropout = nn.Dropout(config.dropout)
self.fc_cnn = nn.Linear(config.num_filters * len(config.filter_sizes), config.num_classes)
def conv_and_pool(self, x, conv):
x = F.relu(conv(x)).squeeze(3)
x = F.max_pool1d(x, x.size(2)).squeeze(2)
return x
def forward(self, x):
context = x[0] # 输入的句子
mask = x[2] # 对padding部分进行mask,和句子一个size,padding部分用0表示,如:[1, 1, 1, 1, 0, 0]
encoder_out, text_cls = self.bert(context, attention_mask=mask, output_all_encoded_layers=False)
out = encoder_out.unsqueeze(1)
out = torch.cat([self.conv_and_pool(out, conv) for conv in self.convs], 1)
out = self.dropout(out)
out = self.fc_cnn(out)
return out
código del modelo bert_RNN:
# coding: UTF-8
import torch
import torch.nn as nn
import torch.nn.functional as F
from pytorch_pretrained import BertModel, BertTokenizer
class Config(object):
"""配置参数"""
def __init__(self, dataset):
self.model_name = 'bert'
self.train_path = dataset + '/data/train.txt' # 训练集
self.dev_path = dataset + '/data/dev.txt' # 验证集
self.test_path = dataset + '/data/test.txt' # 测试集
self.class_list = [x.strip() for x in open(
dataset + '/data/class.txt').readlines()] # 类别名单
self.save_path = dataset + '/saved_dict/' + self.model_name + '.ckpt' # 模型训练结果
self.device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') # 设备
self.require_improvement = 1000 # 若超过1000batch效果还没提升,则提前结束训练
self.num_classes = len(self.class_list) # 类别数
self.num_epochs = 3 # epoch数
self.batch_size = 128 # mini-batch大小
self.pad_size = 32 # 每句话处理成的长度(短填长切)
self.learning_rate = 5e-5 # 学习率
self.bert_path = './bert_pretrain'
self.tokenizer = BertTokenizer.from_pretrained(self.bert_path)
self.hidden_size = 768
self.filter_sizes = (2, 3, 4) # 卷积核尺寸
self.num_filters = 256 # 卷积核数量(channels数)
self.dropout = 0.1
self.rnn_hidden = 768
self.num_layers = 2
class Model(nn.Module):
def __init__(self, config):
super(Model, self).__init__()
self.bert = BertModel.from_pretrained(config.bert_path)
for param in self.bert.parameters():
param.requires_grad = True
self.lstm = nn.LSTM(config.hidden_size, config.rnn_hidden, config.num_layers,
bidirectional=True, batch_first=True, dropout=config.dropout)
self.dropout = nn.Dropout(config.dropout)
self.fc_rnn = nn.Linear(config.rnn_hidden * 2, config.num_classes)
def forward(self, x):
context = x[0] # 输入的句子
mask = x[2] # 对padding部分进行mask,和句子一个size,padding部分用0表示,如:[1, 1, 1, 1, 0, 0]
encoder_out, text_cls = self.bert(context, attention_mask=mask, output_all_encoded_layers=False)
out, _ = self.lstm(encoder_out)
out = self.dropout(out)
out = self.fc_rnn(out[:, -1, :]) # 句子最后时刻的 hidden state
return out
código del modelo bert_RCNN:
# coding: UTF-8
import torch
import torch.nn as nn
import torch.nn.functional as F
from pytorch_pretrained import BertModel, BertTokenizer
class Config(object):
"""配置参数"""
def __init__(self, dataset):
self.model_name = 'bert'
self.train_path = dataset + '/data/train.txt' # 训练集
self.dev_path = dataset + '/data/dev.txt' # 验证集
self.test_path = dataset + '/data/test.txt' # 测试集
self.class_list = [x.strip() for x in open(
dataset + '/data/class.txt').readlines()] # 类别名单
self.save_path = dataset + '/saved_dict/' + self.model_name + '.ckpt' # 模型训练结果
self.device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') # 设备
self.require_improvement = 1000 # 若超过1000batch效果还没提升,则提前结束训练
self.num_classes = len(self.class_list) # 类别数
self.num_epochs = 3 # epoch数
self.batch_size = 128 # mini-batch大小
self.pad_size = 32 # 每句话处理成的长度(短填长切)
self.learning_rate = 5e-5 # 学习率
self.bert_path = './bert_pretrain'
self.tokenizer = BertTokenizer.from_pretrained(self.bert_path)
self.hidden_size = 768
self.filter_sizes = (2, 3, 4) # 卷积核尺寸
self.num_filters = 256 # 卷积核数量(channels数)
self.dropout = 0.1
self.rnn_hidden = 256
self.num_layers = 2
class Model(nn.Module):
def __init__(self, config):
super(Model, self).__init__()
self.bert = BertModel.from_pretrained(config.bert_path)
for param in self.bert.parameters():
param.requires_grad = True
self.lstm = nn.LSTM(config.hidden_size, config.rnn_hidden, config.num_layers,
bidirectional=True, batch_first=True, dropout=config.dropout)
self.maxpool = nn.MaxPool1d(config.pad_size)
self.fc = nn.Linear(config.rnn_hidden * 2 + config.hidden_size, config.num_classes)
def forward(self, x):
context = x[0] # 输入的句子
mask = x[2] # 对padding部分进行mask,和句子一个size,padding部分用0表示,如:[1, 1, 1, 1, 0, 0]
encoder_out, text_cls = self.bert(context, attention_mask=mask, output_all_encoded_layers=False)
out, _ = self.lstm(encoder_out)
out = torch.cat((encoder_out, out), 2)
out = F.relu(out)
out = out.permute(0, 2, 1)
out = self.maxpool(out).squeeze()
out = self.fc(out)
return out
código del modelo bert_DPCNN:
# coding: UTF-8
import torch
import torch.nn as nn
import torch.nn.functional as F
# from pytorch_pretrained_bert import BertModel, BertTokenizer
from pytorch_pretrained import BertModel, BertTokenizer
class Config(object):
"""配置参数"""
def __init__(self, dataset):
self.model_name = 'bert'
self.train_path = dataset + '/data/train.txt' # 训练集
self.dev_path = dataset + '/data/dev.txt' # 验证集
self.test_path = dataset + '/data/test.txt' # 测试集
self.class_list = [x.strip() for x in open(
dataset + '/data/class.txt').readlines()] # 类别名单
self.save_path = dataset + '/saved_dict/' + self.model_name + '.ckpt' # 模型训练结果
self.device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') # 设备
self.require_improvement = 1000 # 若超过1000batch效果还没提升,则提前结束训练
self.num_classes = len(self.class_list) # 类别数
self.num_epochs = 3 # epoch数
self.batch_size = 128 # mini-batch大小
self.pad_size = 32 # 每句话处理成的长度(短填长切)
self.learning_rate = 5e-5 # 学习率
self.bert_path = './bert_pretrain'
self.tokenizer = BertTokenizer.from_pretrained(self.bert_path)
self.hidden_size = 768
self.num_filters = 250 # 卷积核数量(channels数)
class Model(nn.Module):
def __init__(self, config):
super(Model, self).__init__()
self.bert = BertModel.from_pretrained(config.bert_path)
for param in self.bert.parameters():
param.requires_grad = True
# self.fc = nn.Linear(config.hidden_size, config.num_classes)
self.conv_region = nn.Conv2d(1, config.num_filters, (3, config.hidden_size), stride=1)
self.conv = nn.Conv2d(config.num_filters, config.num_filters, (3, 1), stride=1)
self.max_pool = nn.MaxPool2d(kernel_size=(3, 1), stride=2)
self.padding1 = nn.ZeroPad2d((0, 0, 1, 1)) # top bottom
self.padding2 = nn.ZeroPad2d((0, 0, 0, 1)) # bottom
self.relu = nn.ReLU()
self.fc = nn.Linear(config.num_filters, config.num_classes)
def forward(self, x):
context = x[0] # 输入的句子
mask = x[2] # 对padding部分进行mask,和句子一个size,padding部分用0表示,如:[1, 1, 1, 1, 0, 0]
encoder_out, text_cls = self.bert(context, attention_mask=mask, output_all_encoded_layers=False)
x = encoder_out.unsqueeze(1) # [batch_size, 1, seq_len, embed]
x = self.conv_region(x) # [batch_size, 250, seq_len-3+1, 1]
x = self.padding1(x) # [batch_size, 250, seq_len, 1]
x = self.relu(x)
x = self.conv(x) # [batch_size, 250, seq_len-3+1, 1]
x = self.padding1(x) # [batch_size, 250, seq_len, 1]
x = self.relu(x)
x = self.conv(x) # [batch_size, 250, seq_len-3+1, 1]
while x.size()[2] > 2:
x = self._block(x)
x = x.squeeze() # [batch_size, num_filters(250)]
x = self.fc(x)
return x
def _block(self, x):
x = self.padding2(x)
px = self.max_pool(x)
x = self.padding1(px)
x = F.relu(x)
x = self.conv(x)
x = self.padding1(x)
x = F.relu(x)
x = self.conv(x)
x = x + px # short cut
return x
Ejecute los siguientes comandos en la terminal para entrenamiento y prueba:
python run.py --model <模型名称>
Usando la versión GPU de pytorch, los resultados de entrenamiento y prueba de bert_CNN, bert_RNN, bert_RCNN y bert_DPCNN son los siguientes:
berto_CNN:
berto_RNN:
berto_RCNN:
bert_DPCNN:
Comparación de los efectos de cada modelo
Modelo | cuenta | Observación |
---|---|---|
Berto | 94,48% | berto + fc |
ERNIE | 94,67% | Uso ERNIE 1.0, que es un poco mejor que bert (a diferencia del rumoreado bert aplastante chino) |
bert_CNN | 94,67% | bert+clasificación de texto CNN clásica |
bert_RNN | 93,98% | bert+BiLSTM |
bert_RCNN | 94,61% | bert+BiLSTM+agrupación |
bert_DPCNN | 94,28% | bert+ pirámide profunda CNN |
Referencias
Comprensión y uso de ERNIE 2.0
Modelo grande de preentrenamiento chino: principio técnico de Wenxin Ernie
¡ERNIE3.0 actualiza más de 50 puntos de referencia de tareas de PNL!
Descarga de otra información
Si desea continuar aprendiendo sobre rutas de aprendizaje y sistemas de conocimiento relacionados con la inteligencia artificial, bienvenido a leer mi otro blog " Pesado | Ruta de aprendizaje de conocimiento básico de aprendizaje de inteligencia artificial completa, todos los materiales se pueden descargar directamente desde el disco de la red sin pagar atención a las rutinas "
Este blog se refiere a la conocida plataforma de código abierto de Github, la plataforma de tecnología de IA y expertos en campos relacionados: Datawhale, ApacheCN, AI Youdao y Dr. Huang Haiguang, etc. Hay alrededor de 100G de materiales relacionados, y espero ayuda a todos tus amigos.