NLP实战之ELMo词向量文本分类
ELMo词向量文本分类原理讲解ELMo出处:论文Deep contextualized word representationsELMo无需标注。原理可参考:从Word Embedding到Bert模型—自然语言处理中的预训练技术发展史-张俊林模型构建与训练中文预训练模型:github上有哈工大的HIT-SCIR/ELMoForManyLangs,多种语言,注意区分有繁体中文和简体中文(网盘下载)
ELMo词向量文本分类
原理讲解
ELMo出处:论文Deep contextualized word representations
ELMo无需标注。
原理可参考:从Word Embedding到Bert模型—自然语言处理中的预训练技术发展史-张俊林
模型构建与训练
中文预训练模型:github上有哈工大的HIT-SCIR/ELMoForManyLangs,多种语言,注意区分有繁体中文和简体中文(网盘下载)两种。
该模型是基于pytorch架构的。
初始化ELMo变换器
配置ELMo环境
安装torch
pip3 install torch torchvision -i https://pypi.tuna.tsinghua.edu.cn/simple
注意:在安装中可能会报错ERROR: Failed building wheel for torch
。由于需要版本是大于1.4的,找不到对应的whl文件,所以建议老老实实按pytorch官网选择对应自己环境的命令安装。
安装elmoformanylangs
需要先装上pytorch、h5py、numpy、overrides。
注意:我这里遇到了运行python无反应的问题,且在命令行里输入python会跳转到应用商店。这是由于在环境变量中path配置了 %USERPROFILE%\AppData\Local\Microsoft\WindowsApps
导致,只需要将该环境变量的配置去除,并保证已添加python的路径到环境变量中即可解决。
# git clone https://github.com/HIT-SCIR/ELMoForManyLangs.git
cd ELMoForManyLangs
python setup.py install
导入
from elmoformanylangs import Embedder
e = Embedder('../ELMo_Chinese_text_classifier/zhs.model/')
如果在Windows上这一步有问题,可能是因为路径中的左斜杠或右斜杠,绝对路径或相对路径。
用两个句子做测试
sents = [['我', '在', '学习', '新', '的', '知识'],
['谁', '知道','预', '训练', '模型', '的', '效果', '如何', '呢']]
results = e.sents2elmo(sents)
type(results)
type(results[0])
results[0].shape
手写padding过程
def pad_sent(x, max_len):
if len(x)>max_len:
return x[:max_len]
else:
return x+['']*(max_len-len(x))
手写使用ELMo变换后的生成器generator
由于哈工大的ELMo是用pytorch写的,所以我们这里用它当做一个变换器,不断产出变换后的样本。
def batch_generator(x, y, batch_size=64):
n_batches_per_epoch = len(x)//batch_size # 计算多少个batch
for i in range(n_batches_per_epoch):
x_batch = e.sents2elmo([pad_sent(sent,30) for sent in x[batch_size*i:batch_size*(i+1)]]) # 切片后截断
y_batch = y[batch_size*i:batch_size*(i+1),:]
yield np.array(x_batch), y_batch
定义网络结构
from tensorflow.keras import Input, Model
from tensorflow.keras.layers import Embedding, Dense, Conv1D, GlobalMaxPooling1D, Concatenate, Dropout
import numpy as np
class ELMoTextClassifier(object):
# 基于ELMO预训练词向量的TextCNN
def __init__(self, maxlen, max_features, embedding_dims,
class_num=5,
last_activation='softmax'):
self.maxlen = maxlen
self.max_features = max_features
self.embedding_dims = embedding_dims
self.class_num = class_num
self.last_activation = last_activation
def get_model(self):
embedding = Input((self.maxlen, self.embedding_dims,))
convs = []
for kernel_size in [3, 4, 5]:
c = Conv1D(128, kernel_size, activation='relu')(embedding)
c = GlobalMaxPooling1D()(c)
convs.append(c)
x = Concatenate()(convs)
output = Dense(self.class_num, activation=self.last_activation)(x)
model = Model(inputs=embedding, outputs=output)
return model
数据处理与训练
注意这里用的是fit_generator
而不是fit
。
Windows下同样需要修改
import sys
sys.path.append('../data/lesson2_data')
from tensorflow.keras.preprocessing import sequence
import random
from sklearn.model_selection import train_test_split
from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint
from tensorflow.keras.utils import to_categorical
from utils import *
# 数据文件夹
data_dir = "../data/lesson2_data/data"
# 神经网络配置
maxlen = 30
batch_size = 64
max_features = 40001
embedding_dims = 1024
epochs = 8
print('数据预处理与加载数据...')
# 获得 词汇/类别 与id映射字典
categories, cat_to_id = read_category()
# 全部数据
x, y = read_files(data_dir)
data = list(zip(x,y))
del x,y
# 乱序
random.shuffle(data)
# 切分训练集和测试集
train_data, test_data = train_test_split(data)
# 对文本的词id和类别id进行编码
x_train = [content[0] for content in train_data]
y_train = to_categorical(encode_cate([content[1] for content in train_data], cat_to_id))
x_test = [content[0] for content in test_data]
y_test = to_categorical(encode_cate([content[1] for content in test_data], cat_to_id))
print('构建模型...')
model = ELMoTextClassifier(maxlen, max_features, embedding_dims).get_model()
model.compile('adam', 'categorical_crossentropy', metrics=['accuracy'])
print('训练...')
# 设定callbacks回调函数
my_callbacks = [
ModelCheckpoint('./cnn_model.h5', verbose=1),
EarlyStopping(monitor='val_accuracy', patience=2, mode='max')
]
# fit拟合数据
history = model.fit_generator(generator=batch_generator(x_train, y_train),
epochs=epochs,
callbacks=my_callbacks,
validation_data=batch_generator(x_test, y_test),
steps_per_epoch=len(y_train)//batch_size,
validation_steps=len(y_test)//batch_size)
训练中间信息的输出和模型结构的打印
略,和前文一样。
(跑到一个batch时报错,不知道为什么。)
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)