使用CNN进行文本分类

1.卷积神经网络简介
卷积神经网络(Convolutional Neural Network, CNN)是一种 前馈神经网络,它的人工神经元可以响应一部分覆盖范围内的周围单元,对于大型图像处理有出色表现。它包括卷积层(alternating convolutional layer)和池层(pooling layer)。
卷积神经网络是近年发展起来,并引起广泛重视的一种高效识别方法。20世纪60年代,Hubel和Wiesel在研究猫脑皮层中用于局部敏感和方向选择的神经元时发现其独特的网络结构可以有效地降低反馈神经网络的复杂性,继而提出了卷积神经网络(Convolutional Neural Networks-简称CNN)。现在,CNN已经成为众多科学领域的研究热点之一,特别是在模式分类领域,由于该网络避免了对图像的复杂前期预处理,可以直接输入原始图像,因而得到了更为广泛的应用。 K.Fukushima在1980年提出的新识别机是卷积神经网络的第一个实现网络。随后,更多的科研工作者对该网络进行了改进。其中,具有代表性的研究成果是Alexander和Taylor提出的“改进认知机”,该方法综合了各种改进方法的优点并避免了耗时的误差反向传播。
一般地,CNN的基本结构包括两层,其一为特征提取层,每个神经元的输入与前一层的局部接受域相连,并提取该局部的特征。一旦该局部特征被提取后,它与其它特征间的位置关系也随之确定下来;其二是特征映射层,网络的每个计算层由多个特征映射组成,每个特征映射是一个平面,平面上所有神经元的权值相等。特征映射结构采用影响函数核小的sigmoid函数作为卷积网络的激活函数,使得特征映射具有位移不变性。此外,由于一个映射面上的神经元共享权值,因而减少了网络自由参数的个数。卷积神经网络中的每一个卷积层都紧跟着一个用来求局部平均与二次提取的计算层,这种特有的两次特征提取结构减小了特征分辨率。
CNN主要用来识别位移、缩放及其他形式扭曲不变性的二维图形。由于CNN的特征检测层通过训练数据进行学习,所以在使用CNN时,避免了显示的特征抽取,而隐式地从训练数据中进行学习;再者由于同一特征映射面上的神经元权值相同,所以网络可以并行学习,这也是卷积网络相对于神经元彼此相连网络的一大优势。卷积神经网络以其局部权值共享的特殊结构在语音识别和图像处理方面有着独特的优越性,其布局更接近于实际的生物神经网络,权值共享降低了网络的复杂性,特别是多维输入向量的图像可以直接输入网络这一特点避免了特征提取和分类过程中数据重建的复杂度。
本文主要使用一维卷积核的CNN进行文本分类(二维卷积主要用于图像处理)
步骤 1:测试文本的预处理,分词->去去除停用词->统计选择top 5000的词做为特征词
步骤 2:为每个特征词生成ID
步骤 3:将文本转化成ID序列,并将左侧补齐
步骤 4:训练集shuffle
步骤 5:Embedding Layer 将词转化为词向量
步骤 6:添加Conv1D卷积层
步骤 7:添加池化层
步骤 7:添加全连接层,loss function = binary_crossentropy
步骤 8:输出层使用Sigmoid
from __future__ import print_function

from keras.preprocessing import sequence
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation
from keras.layers import Embedding
from keras.layers import Conv1D, GlobalMaxPooling1D
from keras.datasets import imdb
from keras.models import model_from_json
import numpy as np
# set parameters:
max_features = 5001
maxlen = 100
batch_size = 32
embedding_dims = 50
filters = 250
kernel_size = 3
hidden_dims = 250
epochs = 10


x_train=np.loadtxt("x_train.txt",dtype=int)
y_train=np.loadtxt("y_train.txt",dtype=int)

indices = np.arange(x_train.shape[0])
np.random.shuffle(indices)
x_train = x_train[indices]
y_train = y_train[indices]

print('Loading data...')
#x_train=np.loadtxt("x_train.txt",dtype=int)
#y_train=np.loadtxt("y_train.txt",dtype=int)
x_test=x_train[20000:]
y_test=y_train[20000:]
x_train=x_train[:20000]
y_train=y_train[:20000]
#x_test=x_train
#y_test=y_train
print(len(x_train), 'train sequences')
print(len(x_test), 'test sequences')
print(x_train[:1])
print('Pad sequences (samples x time)')
x_train = sequence.pad_sequences(x_train, maxlen=maxlen)
x_test = sequence.pad_sequences(x_test, maxlen=maxlen)
print('x_train shape:', x_train.shape)
print('x_test shape:', x_test.shape)

print('Build model...')
model = Sequential()

# we start off with an efficient embedding layer which maps
# our vocab indices into embedding_dims dimensions
model.add(Embedding(max_features,
                    embedding_dims,
                    input_length=maxlen))
model.add(Dropout(0.5))

# we add a Convolution1D, which will learn filters
# word group filters of size filter_length:
model.add(Conv1D(filters,
                 kernel_size,
                 padding='valid',
                 activation='relu',
                 strides=1))
# we use max pooling:
model.add(GlobalMaxPooling1D())

# We add a vanilla hidden layer:
model.add(Dense(hidden_dims))
model.add(Dropout(0.5))
model.add(Activation('relu'))

# We project onto a single unit output layer, and squash it with a sigmoid:
model.add(Dense(1))
model.add(Activation('sigmoid'))

model.compile(loss='binary_crossentropy',
              optimizer='adam',
              metrics=['accuracy'])
model.fit(x_train, y_train,
          batch_size=batch_size,
          epochs=epochs,
          validation_data=(x_test, y_test))

model_json = model.to_json()
with open("model.json", "w") as json_file:
    json_file.write(model_json)
model.save_weights("model.h5")
json_file = open('model.json', 'r')
loaded_model_json = json_file.read()
json_file.close()
loaded_model = model_from_json(loaded_model_json)
# load weights into new model
loaded_model.load_weights("model.h5")
print("Loaded model from disk")
loaded_model.compile(loss='binary_crossentropy',optimizer='adam',metrics=['accuracy'])
score = loaded_model.evaluate(x_test, y_test, verbose=0)
print(score)

此外,如果是多分类,则需要将:
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)
loss function change from binary_crossentropy to  categorical_crossentropy
此方法将1,2,3,4,....这样的分类转化成one-hot 向量的形式,最终使用softmax做为输出:
model.add(Dense(num_classes, activation='softmax'))
model.compile(loss='categorical_crossentropy',
              optimizer=RMSprop(),
              metrics=['accuracy'])
  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 14
    评论
使用CNN模型进行文本分类,需要将文本转换为数字向量,常用的方式是使用词嵌入(Word Embedding),将每个单词映射为一个向量。 以下是一个使用Python实现CNN模型文本分类的示例代码: ```python import numpy as np from keras.datasets import imdb from keras.preprocessing import sequence from keras.models import Sequential from keras.layers import Dense, Dropout, Activation, Embedding, Conv1D, GlobalMaxPooling1D # 设置超参数 max_features = 5000 # 保留最常见的5000个单词 maxlen = 400 # 文本最大长度 batch_size = 32 # 批大小 embedding_dims = 50 # 词嵌入维度 filters = 250 # 卷积核数量 kernel_size = 3 # 卷积核尺寸 hidden_dims = 250 # 隐藏层大小 epochs = 2 # 训练轮数 # 加载数据 (x_train, y_train), (x_test, y_test) = imdb.load_data(num_words=max_features) # 填充序列,确保所有序列长度相同 x_train = sequence.pad_sequences(x_train, maxlen=maxlen) x_test = sequence.pad_sequences(x_test, maxlen=maxlen) # 构建模型 model = Sequential() # 添加嵌入层 model.add(Embedding(max_features, embedding_dims, input_length=maxlen)) # 添加卷积层和最大池化层 model.add(Conv1D(filters, kernel_size, padding='valid', activation='relu', strides=1)) model.add(GlobalMaxPooling1D()) # 添加全连接层和输出层 model.add(Dense(hidden_dims)) model.add(Dropout(0.2)) model.add(Activation('relu')) model.add(Dense(1)) model.add(Activation('sigmoid')) # 编译模型 model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy']) # 训练模型 model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, validation_data=(x_test, y_test)) # 评估模型 score, acc = model.evaluate(x_test, y_test, batch_size=batch_size) print('Test score:', score) print('Test accuracy:', acc) ``` 该示例使用了Keras深度学习框架,加载了IMDB电影评论数据集,并将每个评论转换为一个长度为400的向量。然后搭建了一个包含嵌入层、卷积层、全连接层和输出层的CNN模型,并使用二元交叉熵作为损失函数,Adam作为优化器进行训练。最后评估模型的准确率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值