Combate de PNL: Pytorch implementa 6 clasificaciones clásicas de texto corto chino de aprendizaje profundo -bert+ERNIE+bert_CNN+bert_RNN+bert_RCNN+bert_DPCNN

inserte la descripción de la imagen aquí


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 THUCNewscarpeta en la dirección de Github a continuación para obtener más detalles.

inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

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

  1. Inicie sesión en el sitio web oficial de Anaconda , descargue e instale Anaconda

  2. 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

inserte la descripción de la imagen aquí
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

inserte la descripción de la imagen aquí
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 torchpara 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.

inserte la descripción de la imagen aquí
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_pretainen el directorio y el modelo ERNIE se coloca ERNIE_pretrainen 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_dictEs necesario crear una nueva carpeta llamada THUCNews para guardar ckptlos archivos del modelo después de cada entrenamiento.

inserte la descripción de la imagen aquí

Si no se crea, aparecerá el siguiente error:

inserte la descripción de la imagen aquí

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:
inserte la descripción de la imagen aquí

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 %.

inserte la descripción de la imagen aquí

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

  1. Mismo punto:
  • aprendizaje continuo
  • Tareas de pre-entrenamiento usando múltiples niveles semánticos
  1. 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

inserte la descripción de la imagen aquí

El diagrama esquemático de ERNIE 2.0 es el siguiente:

inserte la descripción de la imagen aquí

El diagrama esquemático de ERNIE 3.0 es el siguiente:

inserte la descripción de la imagen aquí

# 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 %.

inserte la descripción de la imagen aquí

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:

inserte la descripción de la imagen aquí

berto_RNN:

inserte la descripción de la imagen aquí

berto_RCNN:

inserte la descripción de la imagen aquí

bert_DPCNN:

inserte la descripción de la imagen aquí

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.

Supongo que te gusta

Origin blog.csdn.net/qq_31136513/article/details/131599155
Recomendado
Clasificación