卷积神经网络

1 卷积运算

       在泛函分析中,卷积是通过两个函数 f 和 g 生成第三个函数的数学运算,表征函数 f 和经过翻转,平移的 g 的乘积函数围成的曲边梯形的面积。

       连续函数卷积: 设 f(x),g(x) 是 R 上两个可积函数,作积分:

                                                              \int_{-\infty }^{\infty }f(t)g(x-t)dt

       离散序列卷积: 设 f(m),g(n) 是长度为 N 的两个离散信号,它们的积分是

                                                           (f*g)[n] =\sum_{m=0}^{N-1} f(m)g(n-m)

       卷积运算的应用相当广泛,比如多项式的乘法(包括整数的乘法), 其实就是在进行对两个离散序列进行卷 积运算。在图像处理中,用作图像的边缘检测,图像模糊,锐化等等。在统计学中,加权的平滑是一种卷积。 在概率论中,两个统计独立的变量 X,Y 的概率密度函数是 XY 概率密度函数的卷积。在信号处理的过程中, 任何一个系统的输出都可以看成是输入信号和系统冲击响应的卷积。

2 卷积运算动机

       卷积运算的三个重要思想:

  • 稀疏权重:卷积网络通过使核的大小远小于输入的大小来达到稀疏连接的目的。 
  • 参数共享:在一个模型的多个函数中使用相同的参数。
  • 等变表示:输入改变,输出也以同样的方式改变。

3 池化运算

       池化运算也叫亚采样或者下采样。池化运算用一个矩阵区域内部的某个总体统计量来作为神经网络在该矩阵区域的输出,它综合了该矩阵区域的信息。

  • 最大池化:定义一个窗口,并从窗口内取出最大值作为总体统计量。
  • 均值池化:定义一个窗口,并从窗口内取出平均值作为总体统计量。
  • 其他常见的还有: 范数以及基于中心像素距离的加权平均函数作为总体统计量。

4 池化动机

  • 平移近似不变性:
    • 当输入做出了少量的平移时,最大池化能够获得输出的近似不变性。
    • 局部平移不变性是个很重要的性质。该性质表明:网络只关心某个特征是否出现,而不关心它出现的具体位置。
  • 模拟其它不变性
    • 最大池化只能对空间的平移具有不变性,而无法对空间的旋转具有不变性
    • 最大池化的空间平移不变性是原生的,其他变换的不变性则必须采用这种多通道的方法来实现。

5 Text-CNN原理

经典论文:A Sensitivity Analysis of (and Practitioners’ Guide to) Convolutional Neural Networks for Sentence Classification

Text-CNN模型结构

卷积神经网络_第1张图片

TextCNN详细过程:

  • Embedding:第一层是图中最左边的7乘5的句子矩阵,每行是词向量,维度=5,这个可以类比为图像中的原始像素点。
  • Convolution:然后经过 kernel_sizes=(2,3,4) 的一维卷积层,每个kernel_size 有两个输出 channel。
  • MaxPolling:第三层是一个1-max pooling层,这样不同长度句子经过pooling层之后都能变成定长的表示。
  • Full connection and Softmax:最后接一层全连接的 softmax 层,输出每个类别的概率。

通道(Channels):

  • 图像中可以利用 (R, G, B) 作为不同channel;
  • 文本的输入的channel通常是不同方式的embedding方式(比如 word2vec或Glove),实践中也有利用静态词向量和fine-tunning词向量作为不同channel的做法。

一维卷积(conv-1d):

  • 图像是二维数据;
  • 文本是一维数据,因此在TextCNN卷积用的是一维卷积(在word-level上是一维卷积;虽然文本经过词向量表达后是二维数据,但是在embedding-level上的二维卷积没有意义)。一维卷积带来的问题是需要通过设计不同 kernel_size 的 filter 获取不同宽度的视野

6 Text-CNN模型来进行文本分类

import jieba
from gensim.models.word2vec import Word2Vec
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn import metrics
import jieba
import keras
from keras import optimizers
from keras.preprocessing.text import Tokenizer
from keras.preprocessing.sequence import pad_sequences
from keras.layers import *
from keras.models import Model

text = ['我喜欢吃苹果',
        '我爱吃香蕉',
        '他不想吃桃子',
        '我想去上海玩',
        '她游玩的地点在重庆',
        '他正在北京玩']
category = [1,1,1,2,2,2]

corpus = []
for t in text:
    corpus.append(list(jieba.cut(t)))
print(corpus)

tokenizer=Tokenizer()
tokenizer.fit_on_texts(corpus)
vocab = tokenizer.word_index

x_train, x_test, y_train, y_test = train_test_split(corpus, category, test_size=0.25)
# 将每个样本中的每个词转换为数字列表,使用每个词的编号进行编号
x_train_word_ids=tokenizer.texts_to_sequences(x_train)
x_test_word_ids = tokenizer.texts_to_sequences(x_test)
#序列模式
# 每条样本长度不唯一,将每条样本的长度设置一个固定值
x_train_padded_seqs=pad_sequences(x_train_word_ids,maxlen=10) #将超过固定值的部分截掉,不足的在最前面用0填充
x_test_padded_seqs=pad_sequences(x_test_word_ids, maxlen=10)

#训练词向量
word2vec_model = Word2Vec(sentences=corpus,min_count=1,iter=5)

embedding_matrix = np.zeros((len(vocab) + 1, 100))
for word, i in vocab.items():
    try:
        embedding_vector = word2vec_model[str(word)]
        embedding_matrix[i] = embedding_vector
    except KeyError:
        continue
 
#构建TextCNN模型
def TextCNN(x_train_padded_seqs,y_train,x_test_padded_seqs,y_test,embedding_matrix):
    # 模型结构:词嵌入-卷积池化*3-拼接-全连接-dropout-全连接
    main_input = Input(shape=(10,), dtype='float64')
    # 词嵌入(使用预训练的词向量)
    embedder = Embedding(len(vocab) + 1, 100, input_length=10, weights=[embedding_matrix], trainable=False)
    #embedder = Embedding(len(vocab) + 1, 300, input_length=50, trainable=False)
    embed = embedder(main_input)
    # 词窗大小分别为3,4,5
    cnn1 = Conv1D(128, 1, padding='same', strides=1, activation='relu')(embed)
    cnn1 = MaxPooling1D(pool_size=5)(cnn1)
    cnn2 = Conv1D(128, 2, padding='same', strides=1, activation='relu')(embed)
    cnn2 = MaxPooling1D(pool_size=4)(cnn2)
    # 合并模型的输出向量
    cnn = concatenate([cnn1, cnn2], axis=-1)
    flat = Flatten()(cnn)
    drop = Dropout(0.5)(flat)
    main_output = Dense(3, activation='softmax')(drop)
    model = Model(inputs=main_input, outputs=main_output)
    
    model.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])
 
    one_hot_labels = keras.utils.to_categorical(y_train, num_classes=3)  # 将标签转换为one-hot编码
    model.fit(x_train_padded_seqs, one_hot_labels, batch_size=10, epochs=10)
    #y_test_onehot = keras.utils.to_categorical(y_test, num_classes=3)  # 将标签转换为one-hot编码
    result = model.predict(x_test_padded_seqs)  # 预测样本属于每个类别的概率
    result_labels = np.argmax(result, axis=1)  # 获得最大概率对应的标签
    y_predict = list(map(int, result_labels))
    print('准确率', metrics.accuracy_score(y_test, y_predict))
    print('平均f1-score:', metrics.f1_score(y_test, y_predict, average='weighted'))

推荐文章:

卷积运算

CNN

TextCNN文本分类(keras实现)

 

 

 

你可能感兴趣的:(Python,算法)