记intel杯比赛中各种bug与debug【其四】:基于长短时记忆神经网络的中文分词的实现
(标题长一点就能让外行人感觉到高大上)
直接切入主题好了,这个比赛还必须一个神经网络才可以
所以我们结合主题,打算写一个神经网络的中文分词
这里主要写一下数据的收集和处理,网络的设计,代码的编写和模型测试
数据问题
这个模型的数据,我们打算分三类来:
用msr, pku, as, cityu的语料作数据
这些是人工分词的数据,作为数据是最合适的
虽然数据量确实不小(共158999行),但我们有几个另外的想法用已有的多个中文分词工具,对小说、新闻、法律等进行分词,作为数据
很多分词工具的分词结果并不理想,总是有一部分正确,一部分不通
现在把多个分隔作为频率,再设置一个阈值,作为是否分隔的依据
对于我们这个模型来说,语言需要一些日常用语的,和一些正式用语
所以数据直接爬取小说、新闻等即可
这样可以把数据扩大非常多直接拼接词语作为数据
这个一开始是斗机灵来着,想着想着到还是值得一试的呵呵
网络设计
想到中文分词就能想到隐马模型,然而需要神经网络的话,就直接用lstm好了
lstm网络的优点就是对序列的选择性记忆,我们人类分词的时候不也是用一点内存来记忆么
我们还要用字嵌入层,它用于把one-hot向量转为一个多维向量
这些向量之间会有相似度,也符合字之间存在相似度这一设定
网络就简单这样写:
embedding->lstm->linear->linear
简单暴力
代码编写
写过pytorch的话,chainer开发就轻而易举
代码写的不好看,反正没人看,就先贴上来把
咋有种acm选手作风
# network.py
import chainer
from chainer import links
from chainer import functions
from chainer import reporter
path="/home/tanglizi/Code/chainer/segment"
params={
"name": "segment",
"src_path": path+"/train_dataset/src",
"save_path": path+"/saved",
"test_path": path+"/test_dataset",
"train_path": path+"/train_dataset",
# just for test
"batch_size": 100,
"word_cnt": 48,
"epoch": 8,
"snap_epoch": 3,
}
class Network(chainer.Chain):
def __init__(self):
super(Network, self).__init__()
with self.init_scope():
self.embed=links.EmbedID(8000, 512)
self.rnn=links.LSTM(512, 256)
self.linear=links.Linear(256, 64)
self.out=links.Linear(64, 5)
def reset_state(self):
self.rnn.reset_state()
def __call__(self, x):
x=self.embed(x)
x=self.rnn(x.reshape((-1, 512)))
x=functions.relu(self.linear(x))
x=self.out(x)
return x
class Classifier(chainer.Chain):
def __init__(self, predictor):
super(Classifier, self).__init__()
with self.init_scope():
self.predictor=predictor
def __call__(self, x, t):
x=self.predictor(x)
t=t.reshape((params['word_cnt']*params['batch_size']))
loss=functions.softmax_cross_entropy(x, t)
accuracy=functions.accuracy(x, t)
reporter.report({'loss': loss, 'accuracy': accuracy}, self)
return loss, accuracy
# controller.py
# 控制训练和测试的类
from network import Network, Classifier
import pickle, os, random
import thulac
import numpy as np
import chainer
from chainer import functions
from chainer import links
from chainer import training
from chainer.training import extensions
class Controller:
def __init__(self, params):
# dir_path contain data/ and label/
self.params=params
self.map={'.': 0}
def process(self, path):
datapath=path+'/data'
labelpath=path+'/label'
if os.path.exists(path+"/dataset.pkl"):
dataset=pickle.load(open(path+"/dataset.pkl", "rb"))
print("read dataset from .pkl")
return dataset
dataset=[]
for file_step, filename in enumerate(os.listdir(datapath)):
file_data=open(datapath+'/'+filename, "r")
file_label=open(labelpath+'/'+filename, "r")
sentences=file_data.read().split('\n')[:-1]
labels=file_label.read().split('\n')[:-1]
for index, (data_in, label_in) in enumerate(zip(sentences, labels)):
if len(label_in)!=self.params['word_cnt']:
print("warning: data block", len(label_in))
continue
data_in+='.'*(self.params['word_cnt']-len(data_in))
data=[]
for step, (char, sign) in enumerate(zip(data_in, label_in)):
if char not in self.map:
self.map[char]=len(self.map)
data.append([self.map[char], int(sign)])
dataset.append(data)
print("#%04d file '%s', datasize %d*64 (%d)"%(file_step, filename, len(dataset), len(dataset)*64))
random.shuffle(dataset)
pickle.dump(dataset, open(path+"/dataset.pkl", "wb"))
pickle.dump(self.map, open(self.params['save_path']+"/map.pkl", "wb"))
return dataset
def train(self):
dataset={}
dataset['test']=self.process(self.params['test_path'])
dataset['train']=self.process(self.params['train_path'])
batchset=[dataset['train'][step:step+self.params['batch_size']]\
for step in range(0, len(dataset['train']-self.params['batch_size']+1), self.params['batch_size'])]
self.net=Classifier(Network())
self.optim=chainer.optimizers.Adam()
self.optim.setup(self.net)
for epoch in range(self.params['epoch']):
batch={'data':[], 'label':[]}
for step, batch in enumerate(batchset):
batch=np.array(batch, dtype=int)
data=batch[:,:,0]
label=batch[:,:,1]
self.net.predictor.reset_state()
self.net.cleargrads()
loss, accuracy=self.net(data, label)
loss.backward()
self.optim.update()
print("#%08d step(epoch %02d) loss=%.8f accuracy=%.8f"%(step, epoch, loss.data, accuracy.data))
if epoch%2==0:
self.sendmail_try("#%02d epoch loss=%.8f accuracy=%.8f"%(epoch, loss.data, accuracy.data), "126")
self.save()
self.sendmail_try(self.params["name"]+" training done.", "126")
def test(self):
self.net=Network()
self.load()
while True:
sentence=input(">> ")
ifcontinue=False;x=[]
for char in sentence:
if char not in self.map:
print(char, "not in map.")
ifcontinue=True
break
else:
x.append(self.map[char])
if ifcontinue: continue
self.net.reset_state()
pred=self.net(np.array(x, dtype=int))
for x, char in zip(pred.data, sentence):
sign=np.where(x==x.max())[0][0]
print(char, end='')
if sign==2: print("/", end='')
print('')
def save(self):
chainer.serializers.save_npz(self.params['save_path']+'/'+self.params['name']+'.model', self.net.predictor)
chainer.serializers.save_npz(self.params['save_path']+'/'+self.params['name']+'.optim', self.optim)
def load(self):
chainer.serializers.load_npz(self.params['save_path']+'/'+self.params['name']+'.model', self.net)
self.map=pickle.load(open(self.params['save_path']+"/map.pkl", "rb"))
def sendmail_try(self, msg, mtype):
try:
self.sendmail(msg, mtype)
except:
pass
def sendmail(self, msg, mtype):
msg = MIMEText(msg, 'plain', 'utf-8')
smtp=""
if mtype=='163':
smtp="smtp.163.com"
sender_addr="...@163.com"
password="..."
elif mtype=='126':
smtp="smtp.126.com"
sender_addr="...@126.com"
password="..."
server = smtplib.SMTP(smtp, 25)
server.set_debuglevel(1)
server.login(sender_addr, password)
server.sendmail(sender_addr, ["...@126.com"], msg.as_string())
server.quit()
接下来拿去训练即可
模型测试
现在没什么时间了,其他模型等以后补完吧...
- 对第一个模型来说,正确率0.82
看起来还不错,其实结果真的不怎么的
幸好下面的贝叶斯分类器把尊严挽回了,不然又要在这费时间了
记intel杯比赛中各种bug与debug【其四】:基于长短时记忆神经网络的中文分词的实现的更多相关文章
- 记intel杯比赛中各种bug与debug【其一】:安装intel caffe
因为intel杯创新软件比赛过程中,并没有任何记录.现在用一点时间把全过程重演一次用作记录. 学习 pytorch 一段时间后,intel比赛突然不让用 pytoch 了,于是打算转战intel ca ...
- 记intel杯比赛中各种bug与debug【其二】:intel caffe的使用和大坑
放弃使用pytorch,学习caffe 本文仅记录个人观点,不免存在许多错误 Caffe 学习 caffe模型生成需要如下步骤 编写network.prototxt 编写solver.prototxt ...
- 记intel杯比赛中各种bug与debug【其五】:朴素贝叶斯分类器的实现和针对性的优化
咱这个项目最主要的就是这个了 贝叶斯分类器用于做可以统计概率的二元分类 典型的例子就是垃圾邮件过滤 理论基础 对于贝叶斯算法,这里附上两个链接,便于理解: 朴素贝叶斯分类器的应用-阮一峰的网络日志 基 ...
- 记intel杯比赛中各种bug与debug【其三】:intel chainer的安装与使用
现在在训练模型,闲着来写一篇 顺着这篇文章,顺利安装上intel chainer 再次感谢 大黄老鼠 intel chainer 使用 头一次使用chainer,本以为又入了一个大坑,实际尝试感觉非常 ...
- postgres中的中文分词zhparser
postgres中的中文分词zhparser postgres中的中文分词方法 基本查了下网络,postgres的中文分词大概有两种方法: Bamboo zhparser 其中的Bamboo安装和使用 ...
- SQL Server 字段类型 decimal(18,6)小数点前是几位?记一次数据库SP的BUG处理
原文:SQL Server 字段类型 decimal(18,6)小数点前是几位?记一次数据库SP的BUG处理 SQL Server 字段类型 decimal(18,6)小数点前是几位? 不可否认,这是 ...
- 那些盒模型在IE6中的BUG们,工程狮的你可曾遇到过?
HTML5学堂 那些盒模型在IE6中的BUG们,工程狮的你可曾遇到过? IE6已经渐渐的开始退出浏览器的历史舞台.虽然当年IE6作为微软的一款利器击败网景,但之后也因为版本的持续不更新而被火狐和谷歌三 ...
- 转:移动开发中一些bug及解决方案
网页开发要面对各种各样的浏览器,让人很头疼,而移动开发中,你不但要面对浏览器,还要面对各种版本的手机,iOS好一点,而安卓就五花八门了,你可能在开发中也被它们折磨过,或者正在被它们折磨,我在这里说几个 ...
- 写代码的心得,怎么减少编程中的 bug?
遭遇 bug 的时候,理性的程序员会说:这个 bug 能复现吗? 自负型:这不可能,在我这是好好的. 经验型:不应该,以前怎么没问题? 幻想型:可能是数据有问题. 无辜型:我好几个星期都没碰这块代码了 ...
随机推荐
- IP地址的正则表达式写法
这里讲的是IPv4的地址格式,总长度 32位=4段*8位,每段之间用.分割, 每段都是0-255之间的十进制数值. 将0-255用正则表达式表示,可以分成一下几块来分别考虑: 取值区间 特点 正则写法 ...
- Jlink如何校验Hex
打开SEGGER J-Flash ARM,记住必须设置好工程属性后才能校验,否则校验和为0 设置好工程属性后,直接将Hex拖入到工程中即可.在LOG窗口中会显示CRC的值 如何校验芯片中的程序的版本号 ...
- css3实现轮播图
css3动画属性简写: animation: name duration timing-function delay iteration-count direction fill-mode ...
- 使用3ds Max制作卡通狗教程
使用软件::3ds Max 软件下载:http://www.xy3dsmax.com/xiazai.html 全教程完,学完记得交作业.如果本教程对您有所帮助,请推荐给你的朋友. 全教程完,学完记得交 ...
- 移动端的vue项目,启动错误:Module build failed: Error: No PostCSS Config found in:
新建一个postcss.config.js 写上下面代码 `module.exports = { plugins: { 'autoprefixer': {browsers: 'last 5 versi ...
- wordpress 后台登录增加访问效验,优化退出效果
之前记录了 wordpress 后台登录增加访问效验, 记录了增加后台访问地址被直接访问的困难性的修改步骤. 还有一个地方需要补充一下,就是退出. 退出的时候不做调整会直接跳到首页,这样体验很不好. ...
- 利用js自带函数 数组去重
<script> ,,]; //原数组 var a=[]; //定义空数组 arr.map(function(x){ //用 map 遍历数组 ){ //如果当前值没有存在空数组中 a.p ...
- Manacher 求最长回文子串算法
Manacher算法,是由一个叫Manacher的人在1975年发明的,可以在$O(n)$的时间复杂度里求出一个字符串中的最长回文子串. 例如这两个回文串“level”.“noon”,Manacher ...
- 从A小程序跳转到B小程序
从A小程序跳转到B小程序: A小程序 wxml: <navigator target="miniProgram" open-type="navigate" ...
- [luogu] P4514 上帝造题的七分钟 (树状数组,二维差分)
P4514 上帝造题的七分钟 题目背景 裸体就意味着身体. 题目描述 "第一分钟,X说,要有矩阵,于是便有了一个里面写满了0的n×m矩阵. 第二分钟,L说,要能修改,于是便有了将左上角为(a ...