中文短文本分类实例六-DCNN(A Convolutional Neural Network for Modelling Sentences)「建议收藏」

中文短文本分类实例六-DCNN(A Convolutional Neural Network for Modelling Sentences)「建议收藏」一.概述DCNN(AConvolutionalNeuralNetworkforModellingSentences)byNalKalchbrenner等,又是文本分类论文的一力作。”准确表达句子的语义是语言理解的核心”,通过学习机器学习和TextCNN,我们可以知道n-gram特征是NLP文本任务和句子表达的一种重要方法。TextCNN通过不同步长的卷积核(例如2…

大家好,又见面了,我是你们的朋友全栈君。

一.概述

        DCNN(A Convolutional Neural Network for Modelling Sentences)by NalKalchbrenner等,又是文本分类论文的一力作。”准确表达句子的语义是语言理解的核心”,通过学习机器学习和TextCNN,我们可以知道n-gram特征是NLP文本任务和句子表达的一种重要方法。TextCNN通过不同步长的卷积核(例如2,3,4,5,7)构建n-gram特征,以及最大池化(max-pooling)选择特征,再加上神经网络全局优化的思想,在文本分类任务中取得了不错的效果。

        那么,除了TextCNN外,还有没有更加先进的CNN提取n-gram信息的神经网络呢?

        当然有啦,那就是DCNN!

        DCNN名为动态卷积神经网络,注意,’D’代表的是动态(Dynamic )的意思,而不是有可能望文生义的’深度(Deep)’的意思。

        DCNN,动态卷积神经网络的思想是什么,对比TextCNN有什么进步呢? 一句话,DCNN能够捕捉长距离词语或者是字的语义信息。具体说来,就是TextCNN中,每一个卷积核选择的Max-Pooling池化手段,只能选择一个n-gram信息。举个例子来说,比如说卷积核的步长是3,对于句子’花落惊飞雨’,如果文本最大长度是5,那么可以提取到字符级别的[‘花落惊’、’落惊飞’, ‘惊飞雨’]三个n-gran信息,max-pooling就是取到其中最大的一个。

        聪明的你一定可以发现,着不就是连词吗,没错,就是那么回事。可以发现,这些n-gram信息是没有间隔的连续的,其实和连续词袋差不多。它并不能抽取【’花落’、’雨’】这样的特征,不得不说不是一种遗憾。

        而我们今天所说的DCNN,特点就是Dynamic k-max pooling,是为了解决以上问题的。动态抽取远距离特征,思想如下:

                                                            中文短文本分类实例六-DCNN(A Convolutional Neural Network for Modelling Sentences)「建议收藏」

        DCNN不同于TextCNN,它有着’宽卷积’、’动态池化’和Folding层等三个特点。

二.DCNN原理图

2.1 老规矩,还是放DCNN的网络原理图

                                            中文短文本分类实例六-DCNN(A Convolutional Neural Network for Modelling Sentences)「建议收藏」

2.2 DCNN网络层信息

        如上图,DCNN主要包含one-dim宽卷积层、Dynamic k-max pooling动态topk池化层、Folding层和全连接层。

        1. one-dim宽卷积层,

             one-dim就是每一个维度,例如你有300维的word2vec作embedding层,就有300个dim,如上图网络原理图中的红色卷积所示。

           图像任务中宽卷积层可以更有效提取图边角信息,在NLP文本分类任务中也一样,可以更有效提取句子的句首和句尾信息,毕竟出现得多了,提取它们也是显而易见的,这不难理解。通常得做法可以通过补零,然后再用普通卷积方式(如same)实现它,形式化如下图论文给出的图形所示:

                                                      中文短文本分类实例六-DCNN(A Convolutional Neural Network for Modelling Sentences)「建议收藏」

2. 动态 K-Max pooling层

        动态k-max池化层也很好理解,原始的avg-pooling就是所有卷积的求平均,one-max pooling就是选择最大的那个数。那么,顾名思义,k-max pooling就是选择最大的top k个数啦。

        dynamic k-max pooling前面的动态,就是根据网络结构和预设的top k,通过公式动态地选择k值。我们预定义一个每层的最小k值(例如k=3,也和n-gram中的3,4,5差不多啦),那么当前层数1的k_curr= Max( k,len_max * (L – L_curr) / L ),其中L表示卷积网络深度,len_max表示文本最大长度,L_curr表示当前所在层。论文计算方式如下图:

                                                中文短文本分类实例六-DCNN(A Convolutional Neural Network for Modelling Sentences)「建议收藏」

3. Folding层

       Folding层没什么可说的,论文中实验它也没啥作用,看着高大上吧。原理对于宽卷积层的one-dim,还是假设你有300维的word2vec作embedding层,句子sentence的embedding也有300dim维度。那么Folding就是第一维和第二维相加,第三维和第四维相加。

        直观来看,也没有什么意义,毕竟每个字向量或者是词向量的维度上的数字并没有什么特殊的含义,论文中,实验结果也证明了这一点。

4. 调参

    论文中给出了两个实例,

            一个是有两个宽卷积核的:

                   句子长度:     7

                   宽卷积尺寸:  第一层3,第二层2

                   池化层k值:    第一层5,第二层3;(最小常量为3)

          另一个是有三个款卷积核的:

                   句子长度:     18

                   宽卷积尺寸:  第一层7,第二层5,第三层3,(这个没有说,论文中选(10,7)、(8,5)、 (7,5))

                   池化层k值:    第一层12,第二层6,第三层是3;(最小常量可选3,4,5,6等)

三.DCNN代码实现

       1. 代码实现有点小麻烦,宽卷积(wide_convolution)第一次用,不太熟;动态k-max卷积实现有点麻烦,没有keras抽象,需要用tf或者keras.backend实现;folding倒是简单些;

         github:https://github.com/yongzhuo/Keras-TextClassification/tree/master/keras_textclassification/m06_TextDCNN

        2.主体代码

         2.1  model

         

    def create_model(self, hyper_parameters):
        """
            构建神经网络,只有3层静态
        :param hyper_parameters:json,  hyper parameters of network
        :return: tensor, moedl
        """
        super().create_model(hyper_parameters)
        embedding_output = self.word_embedding.output
        pools = []
        for i in range(len(self.filters)):

            # 第一个,宽卷积,动态k-max池化
            conv_1 = wide_convolution(name="wide_convolution_{}".format(i),
                                      filter_num=self.filters_num, filter_size=self.filters[i][0])(embedding_output)
            top_k_1 = select_k(self.len_max, len(self.filters[i]), 1) # 求取k
            dynamic_k_max_pooled_1 = dynamic_k_max_pooling(top_k=top_k_1)(conv_1)
            # 第二个,宽卷积,动态k-max池化
            conv_2 = wide_convolution(name="wide_convolution_{}_{}".format(i, i),
                                      filter_num=self.filters_num, filter_size=self.filters[i][1])(dynamic_k_max_pooled_1)
            top_k_2 = select_k(self.len_max, len(self.filters[i]), 2)
            dynamic_k_max_pooled_2 = dynamic_k_max_pooling(top_k=top_k_2)(conv_2)
            # 第三层,宽卷积,Fold层,动态k-max池化
            conv_3 = wide_convolution(name="wide_convolution_{}_{}_{}".format(i, i, i), filter_num=self.filters_num,
                                      filter_size=self.filters[i][2])(dynamic_k_max_pooled_2)
            fold_conv_3 = prem_fold()(conv_3)
            top_k_3 = select_k(self.len_max, len(self.filters[i]), 3)  # 求取k
            dynamic_k_max_pooled_3 = dynamic_k_max_pooling(top_k=top_k_3)(fold_conv_3)
            pools.append(dynamic_k_max_pooled_3)
        pools_concat = Concatenate(axis=1)(pools)
        pools_concat_dropout = Dropout(self.dropout)(pools_concat)
        x = Flatten()(pools_concat_dropout)
        output = Dense(units=self.label, activation=self.activate_classify)(x)
        # output = Dense(units=self.label, activation='linear')(pools_concat)
        self.model = Model(inputs=self.word_embedding.input, outputs=output)
        self.model.summary(120)

         2.2  wide_convolution

class wide_convolution(Layer):
    """
        paper: http://www.aclweb.org/anthology/P14-1062
        paper title: "A Convolutional Neural Network for Modelling Sentences"
        宽卷积, 如果s表示句子最大长度, m为卷积核尺寸,
           则宽卷积输出为 s + m − 1,
           普通卷积输出为 s - m + 1.
        github keras实现可以参考: https://github.com/AlexYangLi/TextClassification/blob/master/models/keras_dcnn_model.py
    """
    def __init__(self, filter_num=300, filter_size=3, **kwargs):
        self.filter_size = filter_size
        self.filter_num = filter_num
        super().__init__(**kwargs)

    def build(self, input_shape):
        super().build(input_shape)

    def call(self, inputs):
        x_input_pad = ZeroPadding1D((self.filter_size-1, self.filter_size-1))(inputs)
        conv_1d = Conv1D(filters=self.filter_num,
                         kernel_size=self.filter_size,
                         strides=1,
                         padding='VALID',
                         kernel_initializer='normal', # )(x_input_pad)
                         activation='tanh')(x_input_pad)
        return conv_1d

    def compute_output_shape(self, input_shape):
        return input_shape[0], input_shape[1] + self.filter_size - 1, input_shape[-1]

         2.3  动态k-max卷积

class dynamic_k_max_pooling(Layer):
    """
        paper:        http://www.aclweb.org/anthology/P14-1062
        paper title:  A Convolutional Neural Network for Modelling Sentences
        Reference:    https://stackoverflow.com/questions/51299181/how-to-implement-k-max-pooling-in-tensorflow-or-keras
        动态K-max pooling
            k的选择为 k = max(k, s * (L-1) / L)
            其中k为预先选定的设置的最大的K个值,s为文本最大长度,L为第几个卷积层的深度(单个卷积到连接层等)
        github tf实现可以参考: https://github.com/lpty/classifier/blob/master/a04_dcnn/model.py
    """
    def __init__(self, top_k=3, **kwargs):
        self.top_k = top_k
        super().__init__(**kwargs)

    def build(self, input_shape):
        super().build(input_shape)

    def call(self, inputs):
        inputs_reshape = tf.transpose(inputs, perm=[0, 2, 1])
        pool_top_k = tf.nn.top_k(input=inputs_reshape, k=self.top_k, sorted=False).values
        pool_top_k_reshape = tf.transpose(pool_top_k, perm=[0, 2, 1])
        return pool_top_k_reshape

    def compute_output_shape(self, input_shape):
        return input_shape[0], self.top_k, input_shape[-1]

         2.4  folding

         

class prem_fold(Layer):
    """
        paper:       http://www.aclweb.org/anthology/P14-1062
        paper title: A Convolutional Neural Network for Modelling Sentences
        detail:      垂直于句子长度的方向,相邻值相加,就是embedding层300那里,(0+1,2+3...298+299)
        github tf实现可以参考: https://github.com/lpty/classifier/blob/master/a04_dcnn/model.py
    """
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

    def build(self, conv_shape):
        super().build(conv_shape)

    def call(self, convs):
        conv1 = convs[:, :, ::2]
        conv2 = convs[:, :, 1::2]
        conv_fold = Add()([conv1, conv2])
        return conv_fold

    def compute_output_shape(self, conv_shape):
        return conv_shape[0], conv_shape[1], int(conv_shape[2] / 2)

希望对你有所帮助!

 

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/137821.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • windows10切换快捷键_Word快捷键大全

    windows10切换快捷键_Word快捷键大全目录第一部分:Windows10系统快捷键复制、粘贴和其他常规快捷键Windows徽标键快捷键命令提示符快捷键对话框快捷键文件资源管理器快捷键虚拟桌面快捷键任务栏快捷键《设置》快捷键第二部分:Windows10应用的快捷键《MicrosoftEdge浏览器》快捷键《计算器》快捷键游戏栏快捷键《Groove》快捷键《地图》快捷键《电影…

  • Content-Disposition的使用和注意事项

    Content-Disposition的使用和注意事项我们在开发web系统时有时会有以下需求:希望某类或者某已知MIME类型的文件(比如:*.gif;*.txt;*.htm)能够在访问时弹出“文件下载”对话框希望以原始文件名(上传时的文件名

  • 什么是404页面,如何正确设置制作404页面

    什么是404页面,如何正确设置制作404页面
    什么是404页面?
      404网页是用户尝试访问网站不存在的网页(由于用户点击了损坏的链接、网页已被删除或用户输入了错误的网址)时看到的页面。之所以称为404网页,是因为针对丢失网页的请求,网络服务器会返回404HTTP状态代码,表明该网页未找到。
    404页面的目的是:告诉浏览者其所请求的页面不存在或链接错误,同时引导用户使用网站其他页面而不是关闭窗口离开。
    404对搜索引擎优化seo的影响
      搜索引擎通过HTTP状态码来识别网页的状态。当

  • 基于javaEE的医院病历管理系统的设计与实现[通俗易懂]

    网络的高速发展,促使着数字化医院的建设,现如今大多数医院已经在使用病历管理系统来管理患者电子病历。在医院中,病历记录了医生和患者的诊疗过程,医生可以通过之前病历记载,快速诊断患者,所以病历是医院的重要资产。使用计算机可以提高病历质量,方便存储、查阅、检索等,从而提高病案管理效率,实现病历信息同时异地共享和反复利用。电子病历的推广应用已经势不可挡,未来电子病历需求更高,应用也将继续成熟,市场的竞争也更加激烈。本次毕业设计的题目是基于javaEE的医院病历管理系统的设计与实现。本系统主要运用java编程语言、基

  • Java Volatile Keyword

    Java Volatile Keyword这几天学习Java内存模型,查看文章:JSR133(JavaMemoryModel)FAQ里面介绍了新的Java内存模型对volatile关键字的修订,因为只是一个FAQ,并没有很详细的解析volatile关键字的用法,找到一篇文章JavaVolatileKeyword详细的介绍了volatile适用的场景以及不适用的场景,翻译一下主要内容:…

  • 创建UFT对象

    创建UFT对象小船UFT总结:VBS创建UFT对象: SetqtApp=CreateObject(“QuickTest.Application”)    ‘创建COM对象qtApp.Launch                                                                     ‘启动UFTqtApp.New

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号