自然语言处理之情感分析:使用卷积神经网络(CNN)进行电影评论分类实战
卷积神经网络(CNN)在自然语言处理中用于捕捉文本中的局部特征和模式。文本分类: 如情感分析、主题分类。命名实体识别(NER): 识别文本中的实体,如人名、地名。机器翻译: 用于编码和解码序列。CNN通过卷积层(Convolutional Layers)、池化层(Pooling Layers)和全连接层(Fully Connected Layers)来处理文本数据。卷积层用于捕捉局部特征,池化层用
自然语言处理之情感分析:使用卷积神经网络(CNN)进行电影评论分类实战

自然语言处理基础
文本预处理
文本预处理是自然语言处理(NLP)任务中的关键步骤,它包括多个子任务,旨在将原始文本转换为机器学习算法或深度学习模型可以理解的形式。以下是一些常见的文本预处理技术:
- 分词(Tokenization): 将文本分割成单词或标记。
- 转换为小写(Lowercasing): 减少词汇表大小,避免大小写带来的差异。
- 去除停用词(Removing Stop Words): 去除如“的”、“和”、“是”等常见但不携带太多信息的词汇。
- 词干提取(Stemming): 将单词还原为其词根形式。
- 词形还原(Lemmatization): 类似于词干提取,但考虑词的语法形式。
- 去除标点符号(Removing Punctuation): 标点符号通常不携带语义信息。
- 去除数字(Removing Numbers): 除非数字对文本有特殊意义,否则通常会被去除。
- 去除特殊字符(Removing Special Characters): 如HTML标签、表情符号等。
示例代码
import nltk
from nltk.corpus import stopwords
from nltk.stem import SnowballStemmer
from nltk.tokenize import word_tokenize
import string
# 下载停用词和分词器
nltk.download('stopwords')
nltk.download('punkt')
# 初始化词干提取器
stemmer = SnowballStemmer('english')
# 定义预处理函数
def preprocess_text(text):
# 分词
tokens = word_tokenize(text)
# 转换为小写
tokens = [word.lower() for word in tokens]
# 去除停用词
stop_words = set(stopwords.words('english'))
tokens = [word for word in tokens if word not in stop_words]
# 去除标点符号
table = str.maketrans('', '', string.punctuation)
stripped = [word.translate(table) for word in tokens]
# 词干提取
stemmed = [stemmer.stem(word) for word in stripped]
return stemmed
# 示例文本
text = "This is a sample sentence, showing off the stop words filtration."
# 预处理文本
preprocessed_text = preprocess_text(text)
# 输出结果
print(preprocessed_text)
词向量表示
词向量表示是将词汇转换为数值向量的过程,这些向量可以捕捉词汇的语义和语法特征。常见的词向量模型包括:
- Word2Vec: 通过上下文预测目标词或通过目标词预测上下文。
- GloVe: 通过统计词共现矩阵来学习词向量。
- FastText: 基于词的子词信息来学习词向量,适用于低频词和未见过的词。
示例代码
import gensim.downloader as api
# 下载预训练的Word2Vec模型
model = api.load("word2vec-google-news-300")
# 获取单词向量
word_vector = model.wv['example']
print(word_vector)
NLP中的CNN简介
卷积神经网络(CNN)在自然语言处理中用于捕捉文本中的局部特征和模式。CNN在NLP中的应用包括:
- 文本分类: 如情感分析、主题分类。
- 命名实体识别(NER): 识别文本中的实体,如人名、地名。
- 机器翻译: 用于编码和解码序列。
CNN通过卷积层(Convolutional Layers)、池化层(Pooling Layers)和全连接层(Fully Connected Layers)来处理文本数据。卷积层用于捕捉局部特征,池化层用于减少维度,全连接层用于分类或回归任务。
示例代码
import tensorflow as tf
from tensorflow.keras import layers
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
# 示例数据
texts = ['I love this movie', 'This movie is terrible']
labels = [1, 0] # 1表示正面情感,0表示负面情感
# 分词器
tokenizer = Tokenizer(num_words=10000, oov_token='<OOV>')
tokenizer.fit_on_texts(texts)
word_index = tokenizer.word_index
# 序列化文本
sequences = tokenizer.texts_to_sequences(texts)
padded_sequences = pad_sequences(sequences, padding='post')
# 定义CNN模型
model = tf.keras.Sequential([
layers.Embedding(input_dim=len(word_index)+1, output_dim=16, input_length=max([len(x) for x in padded_sequences])),
layers.Conv1D(128, 5, activation='relu'),
layers.GlobalMaxPooling1D(),
layers.Dense(64, activation='relu'),
layers.Dense(1, activation='sigmoid')
])
# 编译模型
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
# 训练模型
model.fit(padded_sequences, labels, epochs=10)
以上代码展示了如何使用TensorFlow和Keras构建一个简单的CNN模型来处理文本分类任务,如电影评论的情感分析。通过分词、序列化和填充文本,然后定义一个包含嵌入层、卷积层、池化层和全连接层的CNN模型,最后编译和训练模型。
数据准备
加载IMDB数据集
在进行情感分析之前,首先需要一个合适的数据集。IMDB电影评论数据集是一个广泛使用的情感分析数据集,包含50,000条电影评论,其中25,000条用于训练,另外25,000条用于测试。每条评论都有一个情感标签,正面或负面。
from keras.datasets import imdb
# 加载数据集
(train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words=10000)
这里,num_words=10000表示我们只保留数据集中出现频率最高的10,000个单词。train_data和test_data是评论的整数列表,train_labels和test_labels是标签列表,1表示正面评论,0表示负面评论。
数据清洗与分词
加载数据后,需要进行数据清洗和分词。由于IMDB数据集已经进行了初步的清洗和分词,我们主要关注的是将评论文本转换为模型可以理解的格式。
import numpy as np
# 将整数列表转换为二进制矩阵
def vectorize_sequences(sequences, dimension=10000):
results = np.zeros((len(sequences), dimension))
for i, sequence in enumerate(sequences):
results[i, sequence] = 1.
return results
# 转换训练和测试数据
x_train = vectorize_sequences(train_data)
x_test = vectorize_sequences(test_data)
# 转换标签
y_train = np.asarray(train_labels).astype('float32')
y_test = np.asarray(test_labels).astype('float32')
vectorize_sequences函数将整数列表转换为二进制矩阵,其中每一行代表一条评论,每一列代表一个单词。如果单词在评论中出现,则该位置的值为1,否则为0。这种表示方法称为“one-hot编码”。
构建词汇表
构建词汇表是理解文本数据的关键步骤。在IMDB数据集中,词汇表已经由load_data函数构建,它保留了出现频率最高的10,000个单词。但是,我们可以通过以下方式手动构建词汇表:
# 手动构建词汇表示例(通常使用IMDB提供的词汇表)
word_index = imdb.get_word_index()
# 将单词索引转换为词汇表
reverse_word_index = dict([(value, key) for (key, value) in word_index.items()])
decoded_review = ' '.join([reverse_word_index.get(i - 3, '?') for i in train_data[0]])
# 输出解码后的评论
print(decoded_review)
word_index是IMDB提供的单词到整数的映射。我们创建了reverse_word_index来将整数映射回单词,然后使用这个映射来解码第一条训练评论。
通过以上步骤,我们完成了数据的准备,为后续使用CNN进行情感分析奠定了基础。接下来,可以使用这些数据来训练和评估模型。
自然语言处理之情感分析:使用卷积神经网络(CNN)进行电影评论分类
模型构建
定义CNN架构
在自然语言处理(NLP)中,卷积神经网络(CNN)可以用于文本分类任务,如情感分析。CNN能够捕捉文本中的局部特征和模式,通过卷积层、池化层和全连接层的组合,实现对文本情感的高效识别。
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Embedding, Conv1D, GlobalMaxPooling1D, Dense, Dropout
# 定义模型
model = Sequential()
model.add(Embedding(input_dim=vocab_size, output_dim=embedding_dim, input_length=max_length))
model.add(Conv1D(filters=32, kernel_size=3, padding='same', activation='relu'))
model.add(GlobalMaxPooling1D())
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))
# 参数说明
# vocab_size: 词汇表大小
# embedding_dim: 词嵌入维度
# max_length: 输入文本的最大长度
# filters: 卷积核的数量
# kernel_size: 卷积核的大小
# padding: 填充方式,'same'表示输出与输入有相同的宽度
# activation: 激活函数
# Dense: 全连接层
# Dropout: 随机失活层,用于防止过拟合
# sigmoid: 用于二分类问题的激活函数
配置训练参数
训练CNN模型时,需要设置一系列参数,包括批次大小、迭代次数、优化器和损失函数等,以确保模型能够有效地学习和泛化。
# 配置训练参数
batch_size = 32
epochs = 10
# 编译模型时使用的优化器和损失函数
optimizer = 'adam'
loss = 'binary_crossentropy'
metrics = ['accuracy']
编译模型
在定义完模型架构和训练参数后,接下来需要编译模型,指定优化器、损失函数和评估指标。
# 编译模型
model.compile(optimizer=optimizer, loss=loss, metrics=metrics)
# 训练模型
model.fit(X_train, y_train, batch_size=batch_size, epochs=epochs, validation_data=(X_test, y_test))
# 参数说明
# X_train: 训练集输入数据
# y_train: 训练集标签数据
# validation_data: 验证集数据,用于评估模型在训练过程中的表现
通过以上步骤,我们构建了一个基于CNN的情感分析模型,用于电影评论的分类。模型首先通过词嵌入层将文本转换为数值向量,然后通过卷积层捕捉文本中的局部特征,接着使用池化层减少特征维度,最后通过全连接层进行分类预测。在训练过程中,我们通过调整参数和使用验证集来优化模型性能,确保其在未见过的数据上也能有良好的表现。
训练与评估
模型训练
在自然语言处理(NLP)中,使用卷积神经网络(CNN)进行情感分析,尤其是电影评论分类,涉及将文本数据转换为模型可以理解的数值表示,然后通过训练模型来识别正面或负面情感。以下是一个使用Python和Keras库训练CNN模型的示例:
# 导入所需库
import numpy as np
from keras.preprocessing.text import Tokenizer
from keras.preprocessing.sequence import pad_sequences
from keras.models import Sequential
from keras.layers import Embedding, Conv1D, GlobalMaxPooling1D, Dense, Dropout
from keras.utils import to_categorical
from keras.datasets import imdb
# 加载IMDB数据集
(x_train, y_train), (x_test, y_test) = imdb.load_data(num_words=10000)
# 数据预处理
max_length = 500
x_train = pad_sequences(x_train, maxlen=max_length)
x_test = pad_sequences(x_test, maxlen=max_length)
y_train = to_categorical(y_train, num_classes=2)
y_test = to_categorical(y_test, num_classes=2)
# 构建CNN模型
model = Sequential()
model.add(Embedding(10000, 128, input_length=max_length))
model.add(Conv1D(64, 5, activation='relu'))
model.add(GlobalMaxPooling1D())
model.add(Dense(64, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(2, activation='softmax'))
# 编译模型
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
# 训练模型
model.fit(x_train, y_train, epochs=5, batch_size=32, validation_data=(x_test, y_test))
代码解释
- 数据加载:使用Keras内置的IMDB数据集,该数据集包含电影评论的正面和负面样本。
- 数据预处理:通过
pad_sequences将评论文本转换为固定长度的序列,使用to_categorical将标签转换为one-hot编码。 - 模型构建:模型包括一个嵌入层(用于将词汇表中的单词转换为向量),一个一维卷积层(用于捕捉局部特征),一个全局最大池化层(用于减少维度),以及两个全连接层(用于分类)。
- 模型编译:定义优化器、损失函数和评估指标。
- 模型训练:使用训练数据集进行训练,同时在测试数据集上验证模型性能。
评估模型性能
评估CNN模型在情感分析任务上的性能通常包括计算准确率、精确率、召回率和F1分数。以下是如何使用Keras评估模型性能的示例:
# 评估模型
loss, accuracy = model.evaluate(x_test, y_test, verbose=0)
print('Test accuracy:', accuracy)
# 预测
y_pred = model.predict(x_test)
y_pred = np.argmax(y_pred, axis=1)
# 计算精确率、召回率和F1分数
from sklearn.metrics import precision_score, recall_score, f1_score
precision = precision_score(np.argmax(y_test, axis=1), y_pred)
recall = recall_score(np.argmax(y_test, axis=1), y_pred)
f1 = f1_score(np.argmax(y_test, axis=1), y_pred)
print('Precision:', precision)
print('Recall:', recall)
print('F1 Score:', f1)
代码解释
- 模型评估:使用
model.evaluate函数在测试数据集上评估模型,输出测试准确率。 - 预测:使用模型对测试数据进行预测,将预测结果转换为类别标签。
- 性能指标计算:使用
sklearn.metrics中的函数计算精确率、召回率和F1分数,这些指标提供了模型分类性能的全面视图。
优化与调整
优化CNN模型涉及调整超参数、使用不同的优化器、增加正则化技术以防止过拟合,以及可能的架构调整。以下是一个调整模型的示例:
# 调整模型
model = Sequential()
model.add(Embedding(10000, 128, input_length=max_length))
model.add(Conv1D(128, 5, activation='relu'))
model.add(GlobalMaxPooling1D())
model.add(Dense(128, activation='relu', kernel_regularizer='l2'))
model.add(Dropout(0.5))
model.add(Dense(2, activation='softmax'))
# 使用不同的优化器
model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])
# 训练模型
model.fit(x_train, y_train, epochs=10, batch_size=64, validation_data=(x_test, y_test))
代码解释
- 模型架构调整:增加卷积层的过滤器数量,增加正则化(
kernel_regularizer='l2')以减少过拟合。 - 优化器选择:使用
rmsprop优化器,它可能在某些情况下比adam表现更好。 - 训练参数调整:增加训练轮数(
epochs),调整批次大小(batch_size),以寻找最佳训练配置。
通过这些步骤,可以有效地训练、评估和优化CNN模型,以提高其在电影评论情感分析任务上的性能。
实战应用:自然语言处理中的情感分析CNN模型
预测新评论的情感
在情感分析领域,使用CNN模型对电影评论进行情感分类是一个常见且有效的应用。CNN能够捕捉文本中的局部特征和上下文信息,通过卷积层和池化层的组合,模型可以学习到评论中表达情感的关键词和短语。
示例代码
假设我们已经训练好了一个CNN模型,并保存为model.h5。下面是如何使用这个模型来预测一条新评论的情感:
import numpy as np
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
from tensorflow.keras.models import load_model
# 加载模型
model = load_model('model.h5')
# 定义词汇表大小和最大评论长度
vocab_size = 10000
max_length = 100
# 新评论
new_comment = "This movie was absolutely fantastic! I loved every minute of it."
# 词汇表和预处理
tokenizer = Tokenizer(num_words=vocab_size)
tokenizer.fit_on_texts([new_comment])
encoded = tokenizer.texts_to_sequences([new_comment])
padded = pad_sequences(encoded, maxlen=max_length)
# 预测
prediction = model.predict(padded)
if prediction[0][0] > 0.5:
print("Positive sentiment")
else:
print("Negative sentiment")
解释
- 加载模型:使用
load_model函数从文件中加载预先训练好的模型。 - 词汇表和预处理:
Tokenizer用于将文本转换为数字序列,pad_sequences确保所有输入具有相同的长度。 - 预测:模型对预处理后的评论进行预测,输出一个介于0和1之间的值,表示正面情感的概率。
模型解释与可视化
理解CNN模型如何做出决策对于提高模型的透明度和可解释性至关重要。使用可视化工具,如tf-explain,可以帮助我们洞察模型内部的工作原理。
示例代码
下面的代码展示了如何使用tf-explain来可视化CNN模型中的特征图:
from tf_explain.core.grad_cam import GradCAM
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input
# 加载模型
model = load_model('model.h5')
# 创建一个模型,输出最后一层卷积层的特征图
last_conv_layer = model.get_layer('conv_1')
grad_model = Model([model.inputs], [last_conv_layer.output, model.output])
# 新评论
new_comment = "This movie was absolutely fantastic! I loved every minute of it."
# 词汇表和预处理
tokenizer = Tokenizer(num_words=vocab_size)
tokenizer.fit_on_texts([new_comment])
encoded = tokenizer.texts_to_sequences([new_comment])
padded = pad_sequences(encoded, maxlen=max_length)
# 可视化特征图
explainer = GradCAM()
grid = explainer.explain(
(padded, None),
grad_model,
class_index=1,
layer_name='conv_1'
)
解释
- 创建特征图模型:从原始模型中提取最后一层卷积层的输出,创建一个新的模型。
- GradCAM可视化:
GradCAM是一种可视化技术,它通过计算特定类别的预测对卷积层特征图的梯度,来生成热力图,显示哪些部分的评论对模型的决策贡献最大。
部署情感分析模型
将情感分析模型部署到生产环境,使其能够实时处理用户输入,是将研究成果转化为实际应用的关键步骤。
示例代码
使用Flask框架部署模型的简单示例:
from flask import Flask, request, jsonify
from tensorflow.keras.models import load_model
import numpy as np
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
app = Flask(__name__)
# 加载模型
model = load_model('model.h5')
# 定义词汇表大小和最大评论长度
vocab_size = 10000
max_length = 100
@app.route('/predict', methods=['POST'])
def predict_sentiment():
# 获取评论
comment = request.json['comment']
# 词汇表和预处理
tokenizer = Tokenizer(num_words=vocab_size)
tokenizer.fit_on_texts([comment])
encoded = tokenizer.texts_to_sequences([comment])
padded = pad_sequences(encoded, maxlen=max_length)
# 预测
prediction = model.predict(padded)
sentiment = "Positive" if prediction[0][0] > 0.5 else "Negative"
return jsonify({'sentiment': sentiment})
if __name__ == '__main__':
app.run(debug=True)
解释
- Flask应用:创建一个Flask应用,定义一个POST请求的路由
/predict。 - 处理请求:从请求中获取评论,使用与训练模型相同的预处理步骤。
- 预测并返回结果:模型预测后,将结果转换为正面或负面情感,并以JSON格式返回。
通过以上三个实战应用的示例,我们可以看到CNN模型在情感分析中的强大功能,以及如何通过代码实现预测、解释和部署这些模型。这为将自然语言处理技术应用于实际场景提供了坚实的基础。
进阶主题:多通道CNN、预训练词向量的使用、情感分析中的注意力机制
多通道CNN
原理
在自然语言处理中,多通道(Convolutional Neural Networks, CNN)模型被设计用于捕捉文本的不同特征。传统的CNN模型使用单一的卷积层来提取特征,而多通道CNN则通过多个并行的卷积层,每个卷积层使用不同大小的卷积核(kernel),来捕捉文本中不同长度的n-gram特征。这种方法能够更全面地理解文本的语义和结构,提高模型的表达能力。
内容
多通道CNN模型通常包含以下组件:
- 输入层:接收文本数据,通常经过词嵌入(Word Embedding)转换。
- 多通道卷积层:包含多个卷积核,每个核大小不同,用于捕捉不同长度的n-gram。
- 池化层:如最大池化(Max Pooling),用于减少特征维度,提取最重要的信息。
- 全连接层:用于分类任务,将池化后的特征映射到分类标签上。
示例代码
import tensorflow as tf
from tensorflow.keras import layers
# 定义模型
def create_multi_channel_cnn_model(vocab_size, embedding_dim, max_length):
input_layer = layers.Input(shape=(max_length,))
embedding_layer = layers.Embedding(vocab_size, embedding_dim)(input_layer)
# 多通道卷积层
conv1 = layers.Conv1D(filters=128, kernel_size=3, activation='relu')(embedding_layer)
conv2 = layers.Conv1D(filters=128, kernel_size=4, activation='relu')(embedding_layer)
conv3 = layers.Conv1D(filters=128, kernel_size=5, activation='relu')(embedding_layer)
# 最大池化层
maxpool1 = layers.GlobalMaxPooling1D()(conv1)
maxpool2 = layers.GlobalMaxPooling1D()(conv2)
maxpool3 = layers.GlobalMaxPooling1D()(conv3)
# 合并特征
concatenated = layers.Concatenate()([maxpool1, maxpool2, maxpool3])
# 全连接层
dense = layers.Dense(64, activation='relu')(concatenated)
output = layers.Dense(1, activation='sigmoid')(dense)
model = tf.keras.Model(inputs=input_layer, outputs=output)
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
return model
# 假设的参数
vocab_size = 10000
embedding_dim = 16
max_length = 100
# 创建模型
model = create_multi_channel_cnn_model(vocab_size, embedding_dim, max_length)
model.summary()
预训练词向量的使用
原理
预训练词向量(Pre-trained Word Embeddings)是通过大规模语料库训练得到的词的向量表示。这些向量能够捕捉词的语义信息,如词义、词性、上下文关系等。在情感分析等NLP任务中,使用预训练词向量可以显著提高模型的性能,因为它们已经包含了丰富的语言知识,无需从头开始学习。
内容
使用预训练词向量的步骤包括:
- 下载预训练词向量:如GloVe、Word2Vec或FastText。
- 构建词向量矩阵:将词汇表中的每个词映射到预训练词向量中。
- 使用词向量矩阵初始化模型的嵌入层:确保嵌入层的权重是可训练的或冻结的,取决于具体任务。
示例代码
import numpy as np
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
# 加载预训练词向量
def load_glove_vectors(glove_file):
embeddings_index = {}
with open(glove_file, encoding='utf-8') as f:
for line in f:
values = line.split()
word = values[0]
coefs = np.asarray(values[1:], dtype='float32')
embeddings_index[word] = coefs
return embeddings_index
# 构建词向量矩阵
def create_embedding_matrix(tokenizer, embeddings_index, embedding_dim, vocab_size):
embedding_matrix = np.zeros((vocab_size, embedding_dim))
for word, i in tokenizer.word_index.items():
if i >= vocab_size:
continue
embedding_vector = embeddings_index.get(word)
if embedding_vector is not None:
embedding_matrix[i] = embedding_vector
return embedding_matrix
# 假设的参数
embedding_dim = 100
vocab_size = 10000
max_length = 100
# 加载GloVe词向量
glove_file = 'path_to_glove_file.txt'
embeddings_index = load_glove_vectors(glove_file)
# 文本数据
texts = ["I love this movie", "This movie is terrible"]
tokenizer = Tokenizer(num_words=vocab_size)
tokenizer.fit_on_texts(texts)
sequences = tokenizer.texts_to_sequences(texts)
data = pad_sequences(sequences, maxlen=max_length)
# 创建词向量矩阵
embedding_matrix = create_embedding_matrix(tokenizer, embeddings_index, embedding_dim, vocab_size)
# 使用预训练词向量初始化嵌入层
embedding_layer = layers.Embedding(vocab_size, embedding_dim, weights=[embedding_matrix], trainable=False)
情感分析中的注意力机制
原理
注意力机制(Attention Mechanism)在情感分析中用于识别文本中对情感判断最为关键的部分。它允许模型在处理序列数据时,为不同的词分配不同的权重,从而聚焦于最重要的信息。在CNN中,注意力机制可以应用于卷积层的输出,以增强模型对关键特征的捕捉能力。
内容
注意力机制的实现通常包括以下步骤:
- 计算注意力权重:基于卷积层的输出,使用一个全连接层或自注意力机制(Self-Attention)来计算每个词的权重。
- 加权求和:将卷积层的输出与注意力权重相乘,然后求和,得到加权特征表示。
- 后续处理:将加权特征输入到后续的全连接层或分类器中。
示例代码
import tensorflow as tf
from tensorflow.keras import layers
# 定义注意力机制层
class AttentionLayer(layers.Layer):
def __init__(self, **kwargs):
super(AttentionLayer, self).__init__(**kwargs)
def build(self, input_shape):
self.W = self.add_weight(name='attention_weight', shape=(input_shape[-1], 1), initializer='random_normal', trainable=True)
super(AttentionLayer, self).build(input_shape)
def call(self, x):
e = tf.keras.backend.tanh(tf.keras.backend.dot(x, self.W))
a = tf.keras.backend.softmax(e, axis=1)
output = x * tf.keras.backend.repeat_elements(a, tf.shape(x)[-1], axis=-1)
return tf.keras.backend.sum(output, axis=1)
def compute_output_shape(self, input_shape):
return (input_shape[0], input_shape[-1])
# 定义模型
def create_attention_cnn_model(vocab_size, embedding_dim, max_length):
input_layer = layers.Input(shape=(max_length,))
embedding_layer = layers.Embedding(vocab_size, embedding_dim)(input_layer)
conv = layers.Conv1D(filters=128, kernel_size=3, activation='relu')(embedding_layer)
attention = AttentionLayer()(conv)
dense = layers.Dense(64, activation='relu')(attention)
output = layers.Dense(1, activation='sigmoid')(dense)
model = tf.keras.Model(inputs=input_layer, outputs=output)
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
return model
# 假设的参数
vocab_size = 10000
embedding_dim = 16
max_length = 100
# 创建模型
model = create_attention_cnn_model(vocab_size, embedding_dim, max_length)
model.summary()
以上示例展示了如何在CNN模型中集成注意力机制,以提高情感分析的准确性。通过自定义的AttentionLayer,模型能够学习到文本中哪些部分对情感判断最为关键,从而做出更精准的分类。
更多推荐


所有评论(0)