神经网络:文本分类II

作者: zqh_zy | 来源:发表于2017-04-20 11:52 被阅读546次
tensorflow

本篇文章主要记录对之前用神经网络做文本识别的初步优化,进一步将准确率由原来的65%提高到80%,这里优化的几个方面包括:

  • 随机打乱训练数据
  • 增加隐层,和验证集
  • 正则化
  • 对原数据进行PCA预处理
  • 调节训练参数(迭代次数,batch大小等)
随机化训练数据

观察训练数据集,发现训练集是按类别存储,读进内存后在仍然是按类别顺序存放。这样顺序取一部分作为验证集,很大程度上会减少一个类别的训练样本数,对该类别的预测准确率会有所下降。所以首先考虑打乱训练数据。
在已经向量化的训练数据的基础上打乱数据,首先合并data和label,打乱后再将数据和标签分离为trian.txt和train_label.txt。这里可以直接使用shell命令:

1、将labels加到trian.txt的第一列
paste -d" " train_labels.txt train.txt > train_to_shuf.txt

2、随机打乱文件行

shuf train_to_shuf.txt -o train.txt

3、 提取打乱后文件的第一列,保存到train_labels.txt
cat train.txt | awk '{print $1}' > train_labels.txt

4、删除第一列label.
awk '{$1="";print $0}' train.txt

这样再次以相同方式训练,准确率由65%上升到75% 。

改变网络结构,增加隐层

之前的网络直接对输入数据做softmax回归,这里考虑增加隐层,数量并加入验证集观察准确率的变化情况。这里加入一个隐层,隐层节点数为500,激励函数使用Relu。替换原来的网络结构,准确率进一步上升。

正则化,改善过拟合

观察模型对训练集的拟合程度到90%+,而通过上步对训练数据的准确率为76%,一定程度上出现了过拟合的现象,这里在原有cost function中上加入正则项,希望减轻过拟合的现象。这里使用L2正则。连同上步部分的代码如下:

#!/usr/bin/python
#-*-coding:utf-8-*-

LAYER_NODE1 = 500 # layer1 node num
INPUT_NODE = 5000
OUTPUT_NODE = 10
REG_RATE = 0.01

import tensorflow as tf
from datasets import datasets

def interface(inputs, w1, b1, w2,b2):
    """
        compute forword progration result
    """
    lay1 = tf.nn.relu(tf.matmul(inputs, w1) + b1)
    return tf.nn.softmax(tf.matmul(lay1, w2) + b2) # need softmax??

data_sets = datasets()
data_sets.read_train_data(".", True)

sess = tf.InteractiveSession()

x = tf.placeholder(tf.float32, [None, INPUT_NODE], name="x-input")
y_ = tf.placeholder(tf.float32, [None, OUTPUT_NODE], name="y-input")

w1 = tf.Variable(tf.truncated_normal([INPUT_NODE, LAYER_NODE1], stddev=0.1))
b1 = tf.Variable(tf.constant(0.0, shape=[LAYER_NODE1]))

w2 = tf.Variable(tf.truncated_normal([LAYER_NODE1, OUTPUT_NODE], stddev=0.1))
b2 = tf.Variable(tf.constant(0.0, shape=[OUTPUT_NODE]))

y = interface(x, w1, b1, w2, b2)

cross_entropy = -tf.reduce_sum(y_ * tf.log(y + 1e-10))
regularizer = tf.contrib.layers.l2_regularizer(REG_RATE)
regularization = regularizer(w1) + regularizer(w2)
loss = cross_entropy + regularization


train_step = tf.train.GradientDescentOptimizer(0.01).minimize(loss)

#training
tf.global_variables_initializer().run()
saver = tf.train.Saver()

cv_feed = {x: data_sets.cv.text, y_: data_sets.cv.label}
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
acc = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

for i in range(5000):
    if i % 200 == 0:
        cv_acc = sess.run(acc, feed_dict=cv_feed)
        print "train steps: %d, cv accuracy is %g " % (i, cv_acc)
    batch_xs, batch_ys = data_sets.train.next_batch(100)
    train_step.run({x: batch_xs, y_: batch_ys})

path = saver.save(sess, "./model4/model.md")
PCA处理

一方面对文本向量集是严重稀疏的矩阵,而且维度较大,一方面影响训练速度,一方面消耗内存。这里考虑对数据进行PCA处理。该部分希望保存99%的差异率,得到相应的k,即对应的维度。

#!/usr/bin/python
#-*-coding:utf-8-*-
"""
    PCA for datasets
    
"""
import os
import sys
import commands
import numpy
from contextlib import nested
from datasets import datasets

ORIGIN_DIM = 5000

def pca(origin_mat):
    """
        gen matrix using pca
        row of origin_mat is one sample of dataset
        col of origin_mat is one feature
        return matrix  U, s and  V 
    """
    # mean,normaliza1on
    avg = numpy.mean(origin_mat, axis=0)
    # covariance matrix
    cov = numpy.cov(origin_mat-avg,rowvar=0)
    #Singular Value Decomposition
    U, s, V = numpy.linalg.svd(cov, full_matrices=True)

    k = 1;
    sigma_s = numpy.sum(s)
    # chose smallest k for 99% of variance retained 
    for k in range(1, ORIGIN_DIM+1):
        variance = numpy.sum(s[0:k]) / sigma_s
        print "k = %d, variance is %f" % (k, variance)
        if variance >= 0.99:
            break

    if k == ORIGIN_DIM:
        print "some thing unexpected , k is same as ORIGIN_DIM"
        exit(1)

    return U[:, 0:k], k

if __name__ == '__main__':
    """
        main, read train.txt, and do pca
        save file to train_pca.txt
    """
    data_sets = datasets()
    train_text, _ = data_sets.read_from_disk(".", "train", one_hot=False)

    U, k = pca(train_text)
    print "U shpae: ", U.shape
    print "k is : ", k

    text_pca = numpy.dot(train_text, U)
    text_num = text_pca.shape[0]
    print "text_num in pca is ", text_num

    with open("./train_pca.txt", "a+") as f:
        for i in range(0, text_num):
            f.write(" ".join(map(str, text_pca[i,:])) + "\n")

最终得到k=2583。该部分准确率有所提高但影响不大。

调整网络参数

该部分主要根据严重集和测试集的表现不断调整网路参数,包括学习率、网路层数、每层节点个数、正则损失、迭代次数、batch大小等。最终得到80%的准确率。

小结

对神经网路进行初步优化,由原来的65%的准确率提高到80%,主要的提高在于训练数据的随机化,以及网络结构的调整。为提升训练速度,同时减少内存消耗,对数据进行了降维操作。

之后对代码的结构进行了整理,这里没有提及,该部分代码包括nn_interface.pynn_train.py 分别实现对网络结构的定义以及训练流程的管理。

后面会结合tensorflow的使用技巧对训练进行进一步优化。

原创文章,转载注明出处

相关文章

  • 文本分类;数据增强;模型微调 2020-02-25

    文本分类 文本情感分类数据集 使用循环神经网络进行情感分类 使用卷积神经网络进行情感分类文本分类是自然语言处理的一...

  • 神经网络:文本分类II

    本篇文章主要记录对之前用神经网络做文本识别的初步优化,进一步将准确率由原来的65%提高到80%,这里优化的几个方面...

  • 卷积神经网络CNN的文本分类原理和实战

    基于卷积神经网络CNN的文本分类原理和实战 前言 本文介绍了CNN在NLP中的应用:文本分类。 文本分类:是自然语...

  • Explicit Interaction Model towar

    文本分类的显式交互模型 摘要   文本分类是自然语言处理的基本任务之一。最近,与浅模型相比,深度神经网络在文本分类...

  • 【NLP保姆级教程】手把手带你RCNN文本分类(附代码)

    本文首发于微信公众号:NewBeeNLP 继续之前的文本分类系列 传统文本分类 之前介绍的都是属于深度神经网络框架...

  • 大规模文本分类网络TextCNN介绍

    TextCNN网络是2014年提出的用来做文本分类的卷积神经网络,由于其结构简单、效果好,在文本分类、推荐等NLP...

  • task8

    文本分类 使用双向循环神经网络 使用卷积神经网络->TextCNN TextCNN 模型主要使用了一维卷积层和时序...

  • 文献阅读笔记:ABCNN: Attention-Based Co

    关键词:Attention机制;CNN;卷积神经网络;文本分类;智能问答 文献:ABCNN: Attention-...

  • 卷积神经网络

    卷积神经网络基本架构 卷积神经网络,主要特点:卷积运算操作。 领域: 在图像领域,NLP领域的文本分类、软件工程的...

  • 神经网络:文本分类

    由于需要学习语音识别,期间接触了深度学习的算法。利用空闲时间,想用神经网络做一个文本分类的应用, 目的是从头到尾完...

网友评论

  • 4c401f55cf60:您好,请问一下源码中decoder文件是做什么的
  • 4e4eb7d3ecde:你好,请问这个在githup有源码吗?你的例子
    zqh_zy:@无妄无我 https://github.com/zqhZY/textclasser

本文标题:神经网络:文本分类II

本文链接:https://www.haomeiwen.com/subject/tstlzttx.html