Tensorflow使用LSTM实现中文文本分类(2)

前言

经过数据预处理,现在开始正式编写代码。。。
数据预处理部分,请参考:Tensorflow使用LSTM实现中文文本分类(一)

整体结构

代码流程图:

  1. 对词表进行 embeding
  2. 构建 lstm 层
  3. 构建 fc 层
  4. 构建 train_op
  5. 训练流程

其中需要封装的几个方法:

  1. 数据集的封装
    api: next_batch(batch_size) 获得样本batch
  2. 词表封装
    api:sentence2id(text_sentence) 将 句子 转化为 id
  3. 类别的封装
    api:categoryid2id(text_category) 将 类别 转化为 id

代码演示

# -*- coding:utf-8 -*-

import tensorflow as tf
import os
import sys
import numpy as np
import math

# 打印出 log
tf.logging.set_verbosity(tf.logging.INFO)

# lstm 需要的参数
def get_default_params():
    return tf.contrib.training.HParams(
        num_embedding_size = 16, # 每个词语的向量的长度

        # 指定 lstm 的 步长, 一个sentence中会有多少个词语
        # 因为执行的过程中是用的minibatch,每个batch之间还是需要对齐的
        # 在测试时,可以是一个变长的
        num_timesteps = 50, # 在一个sentence中 有 50 个词语

        num_lstm_nodes = [32, 32], # 每一层的size是多少
        num_lstm_layers = 2, # 和上句的len 是一致的
        # 有 两层 神经单元,每一层都是 32 个 神经单元

        num_fc_nodes = 32, # 全连接的节点数
        batch_size = 100,
        clip_lstm_grads = 1.0,
        # 控制lstm的梯度,因为lstm很容易梯度爆炸或者消失
        # 这种方式就相当于给lstm设置一个上限,如果超过了这个上限,就设置为这个值
        learning_rate = 0.001,
        num_word_threshold = 10, # 词频太少的词,对于模型训练是没有帮助的,因此设置一个门限
    )


hps = get_default_params() # 生成 参数 对象



# 设置文件路径
train_file = './news_data/cnews.train.seg.txt'
val_file = './news_data/cnews.val.seg.txt'
test_file = './news_data/cnews.test.seg.txt'
vocab_file = './news_data/cnews.vocab.txt' # 统计的词频
category_file = './news_data/cnews.category.txt' # 标签
output_folder = './news_data/run_text_rnn'

if not os.path.exists(output_folder):
    os.mkdir(output_folder)

class Vocab:
    '''
    词表的封装
    '''
    def __init__(self, filename, num_word_threahold):
        # 每一个词,给她一个id,另外还要统计词频。ps:前面带下划线的为私有成员
        self._word_to_id = {
   }
        self._unk = -1 # 先给 unk 赋值一个 负值,然后根据实际情况在赋值
        self._num_word_theshold = num_word_threahold # 低于 这个值 就忽略掉该词
        self._read_dict(filename) # 读词表方法

    def _read_dict(self, filename):
        '''
        读这个词表
        :param filename: 路径
        :return: none
        '''
        with open(filename, 'r') as f:
            lines = f.readlines()
        for line in lines:
            word, frequency = line.strip('\n').split('\t')
            word = word # 获得 单词
            frequency = int(frequency) # 获得 频率
            if frequency < self._num_word_theshold:
                continue # 门限过滤一下
            idx = len(self._word_to_id) #这里使用了一个id递增的小技巧
            if word == '<UNK>': # 如果是空格,就把上一个id号给它
                # 如果是 unk的话, 就特殊处理一下
                self._unk = idx
            self._word_to_id[word] = idx
            # 如果 word 存在,就把 idx 当做值,将其绑定到一起
            # 如果 word 在词表中不存在,就把nuk的值赋予它

    def word_to_id(self, word):
        '''
        为单词分配id值
        :param word: 单词
        :return:
        '''
        # 字典.get() 如果有值,返回值;无值,返回默认值(就是第二个参数)
        return self._word_to_id.get(word, self._unk)

    def sentence_to_id(self, sentence):
        '''
        将句子 转换成 id 向量
        :param sentence: 要输入的句子(分词后的句子)
        :return:
        '''
        # 单条句子的id vector
        word_ids = [self.word_to_id(cur_word) for cur_word in sentence.split(' ')]
        # cur_word 有可能不存在,需要使用函数进行过滤一下
   
  • 3
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值