# SOLSim **Repository Path**: link2t/sol-sim ## Basic Information - **Project Name**: SOLSim - **Description**: No description available - **Primary Language**: Python - **License**: LGPL-3.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2021-01-15 - **Last Updated**: 2021-01-15 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # SOL模拟器 ## 简介 本项目是基于GloVe(求取Embedding)和LSTM(训练生成器)制作的SOL对话模拟器,模拟SOL在群里的对话方式。 如果有机会的话,后续会制作制作成QQ插件。 ## 来自网络的语料库 https://github.com/codemayq/chinese_chatbot_corpus | **名称** | **数量** | **SOL的奇妙手工打分** | |-------|--------|-----------| |chatterbot|560|8(翻译有问题,但是内容都是对上的)| |douban|3.520M|2(牛头不对马嘴)| |ptt|0.4M|8(八卦太多了,好吧毕竟是八卦语料库,不过好像没怎么参与训练?)| |qingyun|0.1M|5(部分内容无关)| |subtitle|2.74M|8(语言通顺性还行,不过不是对话)| |tieba|2.32M|6(语言通顺性还行,但是足球实在太多了)| |weibo|4.43M|8(其实这语料库还行的)| |xiaohuangji|0.45M|2(黄色内容过多)| ## 训练技巧指导 https://github.com/soumith/ganhacks ## 基本处理流程 - 使用语料库,训练Embedding - 输入:one hot字向量(单个汉字作为基本单位) - 输出:embedded低维度字向量 - 数据集:raw_chat_corpus(网络聊天记录语料库) - 使用语料库,训练LSTM生成器 - 输入:短句(embedded字向量序列)\[batch\*l_in\*\embed_dim] - 输出:下一个字概率\[batch\*dict_size\] - 数据集:raw_chat_corpus - 使用SOL对话记录,迁移训练上述模型 - 输入输出同上 - 数据集:自备 ## 进度 | **阶段** | **进度** | |------|------| | 知识储备 | 100% | | Embedding数据集 | 100% | | Embedding训练 | 100% | | 数据清洗 | 100% | | LSTM训练 | 100% | | LSTM + Attention训练 | 100% | | **GAN + LSTM训练** | 60% | | **GAN + LSTM + MCTS训练** | 0% | | 迁移数据集 | 0% | | 迁移训练 | 0% | ## 备注 ### 对于v1~v4 对应代码无后缀。 效果较差。 ### 对于v5 对应代码后缀v5。 引入Attention。 ### 对于v6~v8 对应代码后缀v6。 不再使用预训练Embedding,而是集成在模型中训练。可以注意到收敛loss明显降低(2.8->0.8),开始输出通顺语句,但语义杂乱、句式单一。 ### 对于v9 v9训练集不填充,支持变长训练集,但是因为只能逐行运算,训练速度大幅降低。目前看来v9**还是比v8强不少的,没有填充干扰会小很多**。 目前,仅使用较清洁的chatterbot和青云语料库可以达到很低的loss,模型也能输出通顺的句子,但是内容和句式都比较单一。 在线资料表明,生成式模型确实容易“陷入万能输出”,即无论输入什么都返回相同的内容。后续版本会考虑解决此问题的方案。 ### 对于v10 对于Naive Seq2Seq(with Attention)的尝试到上一个版本为止。本版本开始引入GAN。 根据原理推测,GAN的判别器“理论上”可以快速排除掉之前版本的万能输出。 实验表明Discriminator非常难以设计。使用LSTM对全句打分和对单字打分效果都不甚理想。 一种可以尝试的思路是,保持Generator无填充的同时,对Discriminator填充至固定长度,从而可以使用拉平等方法。 实验证明以上思路并不可行。生成器会迅速趋于输出单字或连续重复的字,换言之模型忽略了几乎全部的信息而成为常函数。 由于尝试次数过多,v10版本号作为失败品被放弃。 ### 对于v11 v10的问题出在Discriminator(即ScrModel)设计不合理,导致无法对Generator的训练起到足够的指导作用。 在v11中,我们参考现有设计方案,总结出两种可行的思路,分别命名为v11a和v11b。 相比之前的版本,v11A比较复杂,而v11B非常复杂,因此需要较长的时间更新(v9,你又可以活一阵子了)。 ### 对于v11A v11A不再使用LSTM作为评分器。为了能够更好地提取文本中前段的信息(即便是LSTM,hn、cn依然包含更多靠后的信息),采用不同大小的卷积核实现1D-CNN作为评分器。 同时,加入batch中的模型分布与真实分布之间的JS散度作为训练loss的一项。--由于单纯用JS散度无法习得输入输出之间的关系,因此只用于增加语句通顺性。-- 其实也是可以习得输入输出的关系,只需要把输入也包含进去,然后做一个特征提取(代码中为Scr.dense1)。 **添加了额外的训练数据:有噪声的正样本(还是正样本)和纯随机的样本(作为负样本)。**可以用来解决生成器开始生成无意义字符的问题;由于输入是Embedding,甚至可以解决模型“纠结”(即对于多个字符输出相同的概率难以选择)的问题。 GAN中Gen Loss缓慢递增(不是快速暴涨)是正常的,因为生成任务比判定任务困难很多,判定器应该较快收敛。模型需要更长时间的训练。 如果后期Gen Loss仍然不下降,则增加生成模型复杂度;很有可能Generator已经收敛了无法训练。 ### 对于v11B v11B使用MCTS优化下一个生成的文字,以Discriminator的输出作为估价函数,进行强化学习。由于MCTS基于采样,训练过程资源开销可能过于高昂,因此作为保留计划(Plan B)。 ### 对于v12 v11A的表现可以接受,但是存在一些问题。 现在Discriminator给我觉得说的比较好的句子打0分,给有些不通顺的句子打1分。 我在想这是不是因为Generator已经和真实值很相近了,但是Discriminator在训练的时候,还是把Generator标注成负样本,于是它就转而向另一个错误方向训练去了。 解决方案也有,就是训练三个不同的Discriminator,一个管输出和输入的相关性,一个管输出的通顺性,还有一个管人格特征。 还有一点,就是再加入一些各种类型的负样本,并且加入软Label。 这就是v12了。 当然还有备用方案,就是蒙特卡罗法,也就是v11B。 这时,新的问题出现了。 评分器的表现远远超出了生成器,导致生成器无法收敛。 考虑提升生成器的参数数量,ReqModel改为双向模型,RessModel改为两个独立的LSTM+Attention模型。