textcnn DC竞赛

1.介绍

      textcnn是一种利用卷积神经网络来进行文本分类的计算机算法,如果采用多种词向量组合的方式,可以获得很高的分类准确率。我们团队在2018年暑期的DC文本竞赛时使用了textcnn,如果不做开始的词向量融合,textcnn甚至超越不了传统的支持向量机方法。但是由于和支持向量机的工作方式不一样,在模型融合时可以提一些分数。

2. 模型代码

     比赛中我们发现,textcnn的全连接层的神经元数量不易过多,过多反而导致分数不高,我们最后选择的神经元数量只有16或者32. 接下来是textcnn的代码,关于完整代码可以查看我的github:https://github.com/jianfeng123/NLP

class TextCNN(object):
    """文本分类,CNN模型"""
    def __init__(self, saving_loading = False):
        # 三个待输入的数据
        ## 重新导入计算图防止卡顿
        tf.reset_default_graph()
        self.input_x = tf.placeholder(tf.int32, [None, Config.seq_length], name='input_x')
        self.input_y = tf.placeholder(tf.float32, [None, Config.num_classes], name='input_y')
        self.keep_prob = tf.placeholder(tf.float32, name='keep_prob')
        self.cnn()
        self.session = tf.Session()
        self.session.run(tf.global_variables_initializer())
        ## 是否导入模型
        if saving_loading == True:
            self.save_dir = 'checkpoints/textcnn'
            self.save_path = os.path.join(self.save_dir, 'best_validation')
            self.saver = load_model(self.session, self.save_dir)
        self.saving_or_loading = saving_loading
    ## textcnn网路
    def cnn(self):
        """CNN模型"""
        # 词向量映射
        with tf.name_scope('embedding'):
            embedding = tf.get_variable('embedding', [Config.vocab_size, Config.embedding_dim])   ### embedding 映射,原始的向量模型,可以用词向量进行替代
            embedding_outputs = tf.nn.embedding_lookup(embedding, self.input_x)
        pooled_outputs = []
        for filter_size in Config.kernel_size:            ## 并行处理的卷积层个数,由于可能存在2、3、4个字组成的词,所以卷积核的大小也会不一样
            with tf.name_scope('conv_filter{0}'.format(filter_size)):
                conv1 = tf.layers.conv1d(embedding_outputs, 128,kernel_size=filter_size,strides=1, padding='VALID') ## 单核卷积的输入是二维张量,双核卷积输入是三维
                conv_re_output = tf.nn.relu(conv1)
            with tf.name_scope("pool_filter{0}".format(filter_size)):
                pooled0 = tf.reduce_max(conv_re_output, reduction_indices=[1])       ## 最大池化                    
                pooled1 = tf.reduce_mean(conv_re_output, reduction_indices=[1])      ## 平均池化
                pooled_combine = tf.concat([pooled0, pooled1], axis=-1)
            pooled_outputs.append(pooled_combine)
        h_pool = tf.concat(pooled_outputs, axis=1)                                   ## 将输出的特征重组 
        with tf.name_scope("score"):
            # 分类器
            self.logits = tf.layers.dense(h_pool, Config.num_classes, name='fc3')
            self.soft = tf.nn.softmax(self.logits)
            self.y_pred_cls = tf.argmax(self.soft, 1)  # 预测类别                     ## 分类结果

        with tf.name_scope("optimize"):
            cross_entropy = tf.nn.softmax_cross_entropy_with_logits(logits=self.logits, labels=self.input_y)   ## 交叉熵最小化
            self.loss = tf.reduce_mean(cross_entropy)
            # 优化器
            self.optim = tf.train.AdamOptimizer(learning_rate=Config.learning_rate).minimize(self.loss)        ## 优化函数

        with tf.name_scope("accuracy"):                                                                        ## 准确率计算
            # 准确率
            correct_pred = tf.equal(tf.argmax(self.input_y, 1), self.y_pred_cls)
            self.acc = tf.reduce_mean(tf.cast(correct_pred, tf.float32))
            self.label = tf.argmax(self.input_y, 1)

猜你喜欢

转载自blog.csdn.net/monotonomo/article/details/83340514