记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 能复现吗? 自负型:这不可能,在我这是好好的. 经验型:不应该,以前怎么没问题? 幻想型:可能是数据有问题. 无辜型:我好几个星期都没碰这块代码了 ...
随机推荐
- ios问题bug收录——1
**[2713:59682] *** Assertion failure in -[MBProgressHUD show:], /Users/lu/Desktop/****/Pods/MBProgr ...
- C#如何生成一个随机种子for Random?
就这么写: Random rand = new Random((int)DateTime.Now.Ticks); 或者这么写: Random rand = new Random(new Guid(). ...
- Kafka Consumer1
本文的代码基于kafka的0.10.1的版本. 重新设计的原因 0.9以前的consumer是通过zookeeper来进行状态管理里的. 羊群效应 任何Broker或者Consumer的增减都会触发所 ...
- 51nod 1307 绳子与重物 (标记父节点更新即可)
1307 绳子与重物 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 有N条绳子编号 0 至 N - 1,每条绳子后面栓了一个重物重量为Wi,绳子的最大负重为Ci. ...
- shell-3.bash的基本功能:输入输出重定向
1. 2. 3. 4.
- 2,HTTP请求应答返回码
200 OK 请求成功,一般用于Get和Post请求 300 多种选择.请求的资源可包括多个位置,响应的返回一个资源特征与地址的列表用于浏览器(client)选择 Multiple Choices 3 ...
- 监控RMAN操作进度的脚本
REM ------------------------------- REM Script to monitor rman backup/restore operations REM To run ...
- Promise语法
转自:廖雪峰的官方网站 在JavaScript的世界中,所有代码都是单线程执行的. 由于这个“缺陷”,导致JavaScript的所有网络操作,浏览器事件,都必须是异步执行.异步执行可以用回调函数实现: ...
- HDU Integer's Power(容斥原理)
题意 求[l,r]的最大指数和(1<=l,r<=10^18) 最大指数和(如64=8^2=4^3=2^6,所以64的最大指数和是6) 题解 很明显我们可以先求出[1,n]的最大指数和,然后 ...
- java用jxl实现导出execl表格
//先将需要导出的数据放到list中 //然后将list中的数据放到execl表中 @RequestMapping(params="exportExecl") public Str ...