手把手教你用 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的使用技巧对训练进行进一步优化。

原文发布于微信公众号 - AI研习社(okweiwu)

原文发表时间:2017-05-31

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏新智元

吴恩达斯坦福CS230第一名:图像超级补全,效果惊艳(附代码)

【新智元导读】图像修复(Image inpainting)是一个已经被广泛研究的计算机视觉问题,即恢复图像中缺失的部分。斯坦福大学CS230课程的Mark Sa...

1363
来自专栏wOw的Android小站

[MachineLearning] 超参数之LearningRate

关于Gradient descent 算法,不打算细说概念,公式什么的.贴一张Andrew的PPT:

2461
来自专栏PPV课数据科学社区

TensorFlow和深度学习入门教程

关键词:Python,tensorflow,深度学习,卷积神经网络 正文如下: 前言 上月导师在组会上交我们用tensorflow写深度学习和卷积神经网络,并把...

4286
来自专栏量子位

想打造一个神经网络,自动给黑白照片上色?这儿有一份超详细教程

王小新 编译自 FloydHub Blog 量子位 出品 | 公众号 QbitAI ? 昨天,你可能惊喜地看到了Adobe做了个给人像上色的软件,然后伤心地发现...

4505
来自专栏ATYUN订阅号

Python机器学习的练习六:支持向量机

在这个练习中,我们将使用支持向量机(SVMs)创建一个垃圾邮件分类器。在一些简单的2D数据集上使用SVMs去观察他们如何工作,接下来我们查看一组邮件数据集,并且...

4506
来自专栏AI研习社

语义分割和转置卷积

分割对图像分析是必不可少的。语义分割描述了每个像素与类别标记的关联过程,(例如:花朵、人物、道路、天空、海洋、或者汽车)。

1382
来自专栏AI科技大本营的专栏

AI 技术讲座精选:​通过学习Keras从零开始实现VGG网络

Keras代码示例多达数百个。通常我们只需复制粘贴代码,而无需真正理解这些代码。通过学习本教程,您将搭建非常简单的构架,但是此过程会带给您些许好处:您将通过阅读...

3748
来自专栏AI科技大本营的专栏

AI技术讲座精选:神经结构搜索和强化学习

摘 要 神经网络模型不仅功能强大,而且特别灵活,在许多困难的学习任务中均发挥着良好的作用,如图像、声音和自然语言的理解等。尽管神经网络获得了一系列的成功,但是...

33211
来自专栏大数据挖掘DT机器学习

TensorFlow和深度学习入门教程

前言 上月导师在组会上交我们用tensorflow写深度学习和卷积神经网络,并把其PPT的参考学习资料给了我们, 这是codelabs上的教程:《Tensor...

3636
来自专栏机器之心

资源 | MIT提出Matlab插件mNeuron:实现深度模型神经元的可视化

选自MIT 机器之心编译 参与:黄小天、Smith 近日,麻省理工学院(MIT)Antonio Torralba 等人发表了一篇题为《mNeuron:...

3656

扫码关注云+社区

领取腾讯云代金券