论文Convolutional Naural Networks for Sentence Classification--TensorFlow实现篇

这篇博客介绍了如何使用TensorFlow实现论文中提出的卷积神经网络(CNN)进行文本分类。作者参考了Denny Britz的博文,并针对Movie Review数据集进行了实验。文章详细解释了数据预处理、CNN网络结构,包括卷积层、池化层等,并提供了训练代码。最后,讨论了训练过程和TensorBoard的可视化结果。

其实该论文作者已经将文章代码提供了出来,该代码用的是Theano实现的,但是因为最近看了TensorFlow,所以想着用用练练手,所以本文主要参考Denny Britz的一篇博文 来实现CNN和本篇论文,其代码也上传到了github上。说到Denny Britz,大神就是大神,之前也读过他一篇介绍CNN在NLP领域应用场景和方法的文章,写的很透彻也被很多国内网友翻译和转载,他的博客上有很多好的文章,有事Ian一定要好好读一遍,瞻仰和膜拜一下==

因为刚接触TensorFlow,之前只是安装好跑过一两个例子,对其大致了解了一下,知道了Graph、Tensor、Session等一些基本概念。这里就分析一下大神的代码,自己按着撸一遍,边学习TensorFlow边实现论文仿真。好了,废话不多说,开始看代码。

1,实验数据

实验所用的数据集是Movie Review data from Rotten Tomatoes,即MR电影评论数据,其中包含10662条评论,一半正面评论,一般负面。共包含18758个单词(vocab_size),最长的评论有56个单词(Padding,sequence_len),保存在data目录下的rt-polarity.neg和rt-poliarity.pos文件中。这里我们使用10%作为验证集,剩下的作为训练集。数据预处理部分写在data_helpers.py文件中,其实代码很简单,这里仅对load_data_and_labels函数进行介绍:

def load_data_and_labels(positive_data_file, negative_data_file):
    #读取正面、负面评论保存在列表中
    positive_examples = list(open(positive_data_file, "r").readlines())
    positive_examples = [s.strip() for s in positive_examples]
    negative_examples = list(open(negative_data_file, "r").readlines())
    negative_examples = [s.strip() for s in negative_examples]
    #调用clean_str()函数对评论进行处理,安单词进行分割,保存在x_text列表中
    x_text = positive_examples + negative_examples
    x_text = [clean_str(sent) for sent in x_text]
    #为每个评论添加标签,并保存在y中
    positive_labels = [[0, 1] for _ in positive_examples]
    negative_labels = [[1, 0] for _ in negative_examples]
    y = np.concatenate([positive_labels, negative_labels], 0)
    return [x_text, y]

读取完之后还要对样本进行处理以获得vocabulary并将每个样本转化为单词索引列表。这一部分的代码在train.py中实现。代码入下:

#载入实验数据
x_text, y = data_helpers.load_data_and_labels(FLAGS.positive_data_file, FLAGS.negative_data_file)

#获得句子的最大长度,用于padding。这里其值为56
max_document_length = max([len(x.split(" ")) for x in x_text])
#调用tf内部函类VocabularyProcessor,其会读取x_text,按照词语出现顺序构建vocabulary,并给每个单词以索引,然后返回的x是形如[[1,2,3,4...],...,[55,66,777...]]的嵌套列表。内列表代表每个句子,其值是评论中每个词在vocabulary中的索引。所以x是10662*56维
vocab_processor = learn.preprocessing.VocabularyProcessor(max_document_length)
x = np.array(list(vocab_processor.fit_transform(x_text)))

# Randomly shuffle data将数据进行随机打乱
np.random.seed(10)
shuffle_indices = np.random.permutation(np.arange(len(y)))
x_shuffled = x[shuffle_indices]
y_shuffled = y[shuffle_indices]

# Split train/test set构建训练集和验证集
dev_sample_index = -1 * int(FLAGS.dev_sample_percentage * float(len(y)))
x_train, x_dev = x_shuffled[:dev_sample_index], x_shuffled[dev_sample_index:]
y_train, y_dev = y_shuffled[:dev_sample_index
### 卷积神经网络在SST-1数据集上的句子分类代码示例 以下是基于MindSpore框架实现的卷积神经网络CNN)用于SST-1数据集的句子分类任务的代码示例。此代码展示了如何加载预训练词向量、构建模型以及完成训练过程。 #### 数据处理部分 为了适配SST-1数据集,需要先对其进行预处理并转换为适合CNN输入的形式: ```python import numpy as np from mindspore import Tensor, context from mindspore.dataset import GeneratorDataset context.set_context(mode=context.GRAPH_MODE, device_target="CPU") def load_data(file_path, max_len=50): """ 加载和预处理SST-1数据集。 :param file_path: 文件路径 :param max_len: 句子最大长度 :return: 处理后的数据 """ data_list = [] label_list = [] with open(file_path, 'r', encoding='utf-8') as f: lines = f.readlines() for line in lines: parts = line.strip().split('\t') if len(parts) != 2: continue tokens = parts[0].split()[:max_len] labels = int(float(parts[1])) token_ids = [vocab.get(token, vocab['<UNK>']) for token in tokens] # 使用词汇表映射token到id padded_tokens = token_ids + [0] * (max_len - len(token_ids)) # 填充至固定长度 data_list.append(padded_tokens) label_list.append(labels) return np.array(data_list), np.array(label_list) class DatasetGenerator: def __init__(self, inputs, targets): self.inputs = inputs self.targets = targets def __getitem__(self, index): return self.inputs[index], self.targets[index] def __len__(self): return len(self.inputs) ``` #### 构建CNN模型 下面定义了一个简单的CNN架构,适用于句子级别的分类任务: ```python import mindspore.nn as nn import mindspore.common.initializer as init class TextCNN(nn.Cell): def __init__(self, vocab_size, embedding_dim, num_classes, kernel_sizes=[3, 4, 5], num_channels=100): super(TextCNN, self).__init__() self.embedding = nn.Embedding(vocab_size=vocab_size, embedding_size=embedding_dim, padding_idx=0, embedding_table=init.Uniform(0.1)) self.convs = nn.CellList([ nn.Conv2d(in_channels=1, out_channels=num_channels, kernel_size=(k, embedding_dim), has_bias=True, weight_init=init.HeUniform()) for k in kernel_sizes]) self.dropout = nn.Dropout(keep_prob=0.5) self.fc = nn.Dense(num_channels * len(kernel_sizes), num_classes) def construct(self, x): embedded_x = self.embedding(x) # Shape: (batch_size, seq_len, embed_dim) embedded_x = embedded_x.expand_dims(axis=1) # Add channel dimension conv_outs = [] for conv in self.convs: z = conv(embedded_x) # Apply convolution z = nn.ReLU()(z.squeeze()) z = nn.MaxPool1d(z.shape[-1])(z) # Max pooling over time-step conv_outs.append(z.squeeze(-1)) pooled_output = nn.Concat()(conv_outs) # Combine outputs from all kernels pooled_output = self.dropout(pooled_output) logits = self.fc(pooled_output) return logits ``` #### 训练流程 最后,我们设置优化器、损失函数,并执行训练过程: ```python from mindspore.train.callback import LossMonitor from mindspore.nn import SoftmaxCrossEntropyWithLogits, Adam # 参数配置 vocab_size = 10000 # 根据实际词汇表大小调整 embedding_dim = 300 num_classes = 5 # SST-1有五个类别 learning_rate = 0.001 epochs = 10 batch_size = 64 # 创建模型实例 model = TextCNN(vocab_size=vocab_size, embedding_dim=embedding_dim, num_classes=num_classes) # 定义损失函数和优化器 loss_fn = SoftmaxCrossEntropyWithLogits(sparse=True, reduction='mean') optimizer = Adam(model.trainable_params(), learning_rate=learning_rate) # 加载数据 train_inputs, train_labels = load_data('sst1_train.txt') test_inputs, test_labels = load_data('sst1_test.txt') dataset_generator = DatasetGenerator(train_inputs, train_labels) ds_train = GeneratorDataset(dataset_generator, column_names=["data", "label"]) ds_train = ds_train.batch(batch_size=batch_size) # 模型封装与训练 net_with_criterion = nn.WithLossCell(model, loss_fn) train_network = nn.TrainOneStepCell(net_with_criterion, optimizer) for epoch in range(epochs): total_loss = 0 steps = 0 for batch in ds_train.create_dict_iterator(): data = Tensor(batch["data"], dtype=mindspore.int32) label = Tensor(batch["label"], dtype=mindspore.int32) loss = train_network(data, label) total_loss += loss.asnumpy() steps += 1 avg_loss = total_loss / steps print(f"Epoch {epoch+1}/{epochs}, Average Loss: {avg_loss:.4f}") ``` 以上代码实现了针对SST-1数据集的卷积神经网络句子分类功能[^1]。通过引入预训练词向量和多种尺寸的卷积核设计,该方法能够有效提取局部特征并提升分类效果[^4]。 ---
评论 11
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值