NLP-神经语言模型:文本生成

一、引言

NLP-统计语言模型中已经简要介绍过语言模型的相关知识,该文中已阐述语言模型的应用场景和一些传统的实现方式,本文接着演示n-gram的另一种实现方式-神经网络,那这样的实现方式就是神经语言模型吗?
按本渣的理解,答案是否定的,神经语言模型是一个类指,其本质是在统计语言模型上的一种延伸和扩展,我可以只考虑上文n个词,也可以考虑下文n个词,也可以基于上下文考虑,具体的情况需要根据需求而定。

二、文本生成实践

1、训练语料

为了和NLP-统计语言模型形成呼应,本文依旧使用文本生成作为案例,依旧照抄语料库(量少更能直观理解过程)。
另外强调一点,本文还是以理解为主,并没有将数据进行训练、验证和测试等拆分!

    corpus = '''
    这一生原本一个人,你坚持厮守成我们,却小小声牵着手在默认。
    感动的眼神说愿意,走进我的人生。
    进了门开了灯一家人,盼来生依然是一家人。
    确认过眼神,我遇上对的人。
    我挥剑转身,而鲜血如红唇。
    前朝记忆渡红尘,伤人的不是刀刃,是你转世而来的魂。
    青石板上的月光照进这山城,我一路的跟你轮回声,我对你用情极深。
    谁在用琵琶弹奏一曲东风破,枫叶将故事染色,结局我看透。
    篱笆外的古道我牵着你走过,荒烟漫草的年头,就连分手都很沉默。
    '''

2、项目结构

项目流程结构.png

3、数据处理

本文假设第n个词的出现只与前面n-1个词相关,而与其它任何词都不相关,因此在构建训练数据时,将语料进行截取,如

这一生原本一个人,你坚持厮守成我们,却小小声牵着手在默认

以n为4进行切分的话即为

这一生->原
一生原->本
生原本->一
...以此类推

根据上述的切分方法,将数据进行切分并转为one-hot序列

   def __init__(self,window,corpus):
       self.window = window
       self.corpus = corpus
       self.char2id = None
       self.id2char = None
       self.char_length = 0


   def load_data(self):
       X = []
       Y = []
       # 将语料按照\n切分为句子
       corpus = self.corpus.strip().split('\n')
       # 获取所有的字符作为字典
       chrs = set(self.corpus.replace('\n',''))
       chrs.add('UNK')
       self.char_length = len(chrs)
       self.char2id = {c: i for i, c in enumerate(chrs)}
       self.id2char = {i: c for c, i in self.char2id.items()}
       for line in corpus:
           x = [[self.char2id[char] for char in line[i: i + self.window]] for i in range(len(line) - self.window)]
           y = [[self.char2id[line[i + self.window]]] for i in range(len(line) - self.window)]
           X.extend(x)
           Y.extend(y)
       # 转为one-hot
       X = to_categorical(X)
       Y = to_categorical(Y)
       return X,Y

4、模型构建

本文使用两层的LSTM进行模型搭建

    def build_model(self):
        model = Sequential()
        model.add(Bidirectional(LSTM(100,return_sequences=True)))
        model.add(Bidirectional(LSTM(200)))
        model.add(Dense(self.char_length, activation='softmax'))
        model.compile('adam', 'categorical_crossentropy')
        self.model = model

5、模型训练方法

    def train_model(self,X,Y,epochs):
        self.model.fit(X, Y, epochs=epochs, verbose=1)
        self.model.save('model.model')

6、模型测试方法

    def predict(self,sentence):
        input_sentence = [self.char2id.get(char,self.char2id['UNK']) for char in sentence]
        input_sentence = pad_sequences([input_sentence],maxlen=self.window)
        input_sentence = to_categorical(input_sentence,num_classes=self.char_length)
        predict = self.model.predict(input_sentence)
        # 本文为了方便 直接取使用最大概率的值,并非绝对,采样的方式有很多种,自行选择
        return self.id2char[np.argmax(predict)]

7、训练及测试

    # 以5切分
    window = 5
    text_generate = TextGenerate(window,corpus)
    X,Y = text_generate.load_data()
    text_generate.build_model()
    text_generate.train_model(X,Y,500)
    # text_generate.load_model()
    input_sentence = '确认过眼神'
    result = input_sentence
    #在构建语料的过程中,设置了每次只预测一个词,为了生成完成的一句话,需要进行循环预测
    while not result.endswith('。'):
        predict = text_generate.predict(input_sentence)
        result += predict
        input_sentence += predict
        input_sentence = input_sentence[len(input_sentence)-(window if len(input_sentence)>window else len(input_sentence)):]
        print(result)

以‘确认过眼神’作为提示语句,测试结果如下:

'''
确认过眼神,
确认过眼神,我
确认过眼神,我遇
确认过眼神,我遇上
确认过眼神,我遇上对
确认过眼神,我遇上对的
确认过眼神,我遇上对的人
确认过眼神,我遇上对的人。
'''

从结果中发现,该模型已经完全记住了训练语料的连接关系,但也因为采样的时候贪婪地采样最大概率词作为预测结果,所以当提示语句在语料库中完全出现过时,预测结果的多样性就受到了抑制。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,657评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,662评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,143评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,732评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,837评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,036评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,126评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,868评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,315评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,641评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,773评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,859评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,584评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,676评论 2 351

推荐阅读更多精彩内容