sru源码--language model
import sys
import os
import argparse
import time
import random
import math import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.autograd import Variable import cuda_functional as MF def read_corpus(path, eos="</s>"):
data = [ ]
with open(path) as fin:
for line in fin:
data += line.split() + [ eos ]
return data def create_batches(data_text, map_to_ids, batch_size, cuda=True):
data_ids = map_to_ids(data_text)
N = len(data_ids)
L = ((N-1) // batch_size) * batch_size
x = np.copy(data_ids[:L].reshape(batch_size,-1).T)
y = np.copy(data_ids[1:L+1].reshape(batch_size,-1).T)#x和y的结果基本相同
x, y = torch.from_numpy(x), torch.from_numpy(y)
x, y = x.contiguous(), y.contiguous()
if cuda:
x, y = x.cuda(), y.cuda()
return x, y class EmbeddingLayer(nn.Module):#为语料中每一个单词对应的其相应的词向量
def __init__(self, n_d, words, fix_emb=False):
super(EmbeddingLayer, self).__init__()
word2id = {}
for w in words:
if w not in word2id:
word2id[w] = len(word2id)#把文本映射到数字上。 self.word2id = word2id
self.n_V, self.n_d = len(word2id), n_d#n_V应该是指词库大小,n_d指hidden state size
self.embedding = nn.Embedding(self.n_V, n_d)#赋予每个单词相应的词向量 def forward(self, x):
return self.embedding(x) def map_to_ids(self, text):#映射
return np.asarray([self.word2id[x] for x in text],
dtype='int64'
) class Model(nn.Module):
def __init__(self, words, args):
super(Model, self).__init__()
self.args = args
self.n_d = args.d
self.depth = args.depth
self.drop = nn.Dropout(args.dropout)#防止过拟合的层,变分dropout
self.embedding_layer = EmbeddingLayer(self.n_d, words)
self.n_V = self.embedding_layer.n_V
if args.lstm:
self.rnn = nn.LSTM(self.n_d, self.n_d,#self.rnn = nn.LSTM( # if use nn.RNN(), it hardly learns
input_size=INPUT_SIZE,
hidden_size=64, # rnn hidden unit
num_layers=1, # number of rnn layer
batch_first=True, # input & output will has batch size as 1s dimension. e.g. (batch, time_step, input_size)
) self.depth,
dropout = args.rnn_dropout
)
else:
self.rnn = MF.SRU(self.n_d, self.n_d, self.depth,
dropout = args.rnn_dropout,
rnn_dropout = args.rnn_dropout,
use_tanh = 0
)
self.output_layer = nn.Linear(self.n_d, self.n_V)
# tie weights
self.output_layer.weight = self.embedding_layer.embedding.weight
self.init_weights()
if not args.lstm:
self.rnn.set_bias(args.bias) def init_weights(self):#initial c
val_range = (3.0/self.n_d)**0.5
for p in self.parameters():
if p.dim() > 1: # matrix
p.data.uniform_(-val_range, val_range)
else:
p.data.zero_() def forward(self, x, hidden):
emb = self.drop(self.embedding_layer(x))
output, hidden = self.rnn(emb, hidden)#rnn的输入和输出都有两个,即输入和上一层的隐层的值
output = self.drop(output)
output = output.view(-1, output.size(2))#改变tensor的size,size(2)表示计算第三维的大小,如size 4x6x7,则.size(3)就等于7
output = self.output_layer(output)
return output, hidden def init_hidden(self, batch_size):
weight = next(self.parameters()).data
zeros = Variable(weight.new(self.depth, batch_size, self.n_d).zero_())
if self.args.lstm:
return (zeros, zeros)
else:
return zeros def print_pnorm(self):#输出范数,范数常常被用来度量某个向量空间(或矩阵)中的每个向量的长度或大小。正则化中就是用范数
norms = [ "{:.0f}".format(x.norm().data[0]) for x in self.parameters() ]
sys.stdout.write("\tp_norm: {}\n".format(
norms
)) def train_model(epoch, model, train):
model.train()
args = model.args unroll_size = args.unroll_size
batch_size = args.batch_size
N = (len(train[0])-1)//unroll_size + 1
lr = args.lr total_loss = 0.0
criterion = nn.CrossEntropyLoss(size_average=False)#每个小批次的损失将被相加。
hidden = model.init_hidden(batch_size)
for i in range(N):
x = train[0][i*unroll_size:(i+1)*unroll_size]
y = train[1][i*unroll_size:(i+1)*unroll_size].view(-1)#view(-1)是指按列展开
x, y = Variable(x), Variable(y)
hidden = (Variable(hidden[0].data), Variable(hidden[1].data)) if args.lstm \
else Variable(hidden.data) model.zero_grad()
output, hidden = model(x, hidden)
assert x.size(1) == batch_size
loss = criterion(output, y) / x.size(1)#.size(1)计算列数.size(0)计算行数,must be (1. nn output, 2. target), the target label is NOT one-hotted
loss.backward() torch.nn.utils.clip_grad_norm(model.parameters(), args.clip_grad)#nn.utils.clip_grad_norm()对网络进行梯度裁剪,因为RNN中容易出现梯度爆炸的问题。
for p in model.parameters():
if p.requires_grad:
if args.weight_decay > 0:
p.data.mul_(1.0-args.weight_decay)
p.data.add_(-lr, p.grad.data)
if math.isnan(loss.data[0]) or math.isinf(loss.data[0]):#如果发生梯度消失或梯度爆炸则退出程序
sys.exit(0) #math.isinf(x):如果x = ±inf(inf:infinity ,译为无穷)也就是±∞返回True
return #math.isnan(x):如果x = Non (not a number) 返回True; total_loss += loss.data[0] / x.size(0)
if i%10 == 0:
sys.stdout.write("\r{}".format(i))
sys.stdout.flush() return np.exp(total_loss/N) def eval_model(model, valid):
model.eval()
args = model.args
total_loss = 0.0
unroll_size = model.args.unroll_size
criterion = nn.CrossEntropyLoss(size_average=False)
hidden = model.init_hidden(1)
N = (len(valid[0])-1)//unroll_size + 1
for i in range(N):
x = valid[0][i*unroll_size:(i+1)*unroll_size]
y = valid[1][i*unroll_size:(i+1)*unroll_size].view(-1)
x, y = Variable(x, volatile=True), Variable(y)
hidden = (Variable(hidden[0].data), Variable(hidden[1].data)) if args.lstm \
else Variable(hidden.data)
output, hidden = model(x, hidden)
loss = criterion(output, y)
total_loss += loss.data[0]
avg_loss = total_loss / valid[1].numel()#numel()返回张量所含元素的个数
ppl = np.exp(avg_loss)
return ppl def main(args):
train = read_corpus(args.train)
dev = read_corpus(args.dev)
test = read_corpus(args.test) model = Model(train, args)
model.cuda()
sys.stdout.write("vocab size: {}\n".format(
model.embedding_layer.n_V
))
sys.stdout.write("num of parameters: {}\n".format(
sum(x.numel() for x in model.parameters() if x.requires_grad)
))
model.print_pnorm()
sys.stdout.write("\n") map_to_ids = model.embedding_layer.map_to_ids
train = create_batches(train, map_to_ids, args.batch_size)
dev = create_batches(dev, map_to_ids, 1)
test = create_batches(test, map_to_ids, 1) unchanged = 0
best_dev = 1e+8
for epoch in range(args.max_epoch):
start_time = time.time()#返回当前时间的时间戳(1970纪元后经过的浮点秒数)。
if args.lr_decay_epoch>0 and epoch>=args.lr_decay_epoch:
args.lr *= args.lr_decay
train_ppl = train_model(epoch, model, train)
dev_ppl = eval_model(model, dev)
sys.stdout.write("\rEpoch={} lr={:.4f} train_ppl={:.2f} dev_ppl={:.2f}"
"\t[{:.2f}m]\n".format(
epoch,
args.lr,
train_ppl,
dev_ppl,
(time.time()-start_time)/60.0
))
model.print_pnorm()
sys.stdout.flush() if dev_ppl < best_dev:
unchanged = 0
best_dev = dev_ppl
start_time = time.time()
test_ppl = eval_model(model, test)
sys.stdout.write("\t[eval] test_ppl={:.2f}\t[{:.2f}m]\n".format(
test_ppl,
(time.time()-start_time)/60.0
))
sys.stdout.flush()
else:
unchanged += 1
if unchanged >= 30: break
sys.stdout.write("\n") if __name__ == "__main__":
argparser = argparse.ArgumentParser(sys.argv[0], conflict_handler='resolve')
argparser.add_argument("--lstm", action="store_true")
argparser.add_argument("--train", type=str, required=True, help="training file")
argparser.add_argument("--dev", type=str, required=True, help="dev file")
argparser.add_argument("--test", type=str, required=True, help="test file")
argparser.add_argument("--batch_size", "--batch", type=int, default=32)
argparser.add_argument("--unroll_size", type=int, default=35)
argparser.add_argument(" ", type=int, default=300)
argparser.add_argument("--d", type=int, default=910)
argparser.add_argument("--dropout", type=float, default=0.7,
help="dropout of word embeddings and softmax output"
)
argparser.add_argument("--rnn_dropout", type=float, default=0.2,
help="dropout of RNN layers"
)
argparser.add_argument("--bias", type=float, default=-3,
help="intial bias of highway gates",
)
argparser.add_argument("--depth", type=int, default=6)
argparser.add_argument("--lr", type=float, default=1.0)
argparser.add_argument("--lr_decay", type=float, default=0.98)
argparser.add_argument("--lr_decay_epoch", type=int, default=175)
argparser.add_argument("--weight_decay", type=float, default=1e-5)
argparser.add_argument("--clip_grad", type=float, default=5) args = argparser.parse_args()
print (args)
sru源码--language model的更多相关文章
- 关于sru源码class Model的parameters
class Model(nn.Module): def __init__(self, words, args): super(Model, self).__init__() self.args = a ...
- yii2 源码分析 model类分析 (五)
模型类是数据模型的基类.此类继承了组件类,实现了3个接口 先介绍一下模型类前面的大量注释说了什么: * 模型类是数据模型的基类.此类继承了组件类,实现了3个接口 * 实现了IteratorAggreg ...
- django源码分析---- Model类型&Field类型
djiango在数据库这方式自己实现了orm(object relationship mapping 对象关系模型映射).这个主要是用到python 元类这一 项python中的高级技术来实现的. c ...
- [原创]在Windows和Linux中搭建PostgreSQL源码调试环境
张文升http://ode.cnblogs.comEmail:wensheng.zhang#foxmail.com 配图太多,完整pdf下载请点这里 本文使用Xming.Putty和VMWare几款工 ...
- Mybatis Generator的model生成中文注释,支持oracle和mysql(通过修改源码的方式来实现)
在看本篇之前,最好先看一下上一篇通过实现CommentGenerator接口的方法来实现中文注释的例子,因为很多操作和上一篇基本是一致的,所以本篇可能不那么详细. 首先说一下上篇通过实现Comment ...
- Backbone源码解析(二):Model(模型)模块
Model(模型)模块在bk框架中的作用主要是存储处理数据,它对外和对内都有很多操作数据的接口和方法.它与视图(Views)模块精密联系着,通过set函数改变数据结构从而改变视图界面的变化.下面我们来 ...
- PureMVC(JS版)源码解析(十一):Model类
这篇博文讲PureMVC三个核心类——Model类.Model类的构造函数及工厂函数[即getInstance()方法]和View类.Controller类是一样的,这里就不重复讲解了,只 ...
- ZRender源码分析2:Storage(Model层)
回顾 上一篇请移步:zrender源码分析1:总体结构 本篇进行ZRender的MVC结构中的M进行分析 总体理解 上篇说到,Storage负责MVC层中的Model,也就是模型,对于zrender来 ...
- BIZ中model.getSql源码分析
功能:根据model.xml文件中配置的sql,获取对应的动态sql结果. 实例代码:String sql1 = model.getSql(dao.dbMeta());String sql2 = mo ...
随机推荐
- RF相关知识
前言:下文中的总结都是来自于网络,有的来自与博客,有的来自于维基百科/百度百科,仅仅是为了方便查看. ASK: ASK:幅移键控调制的简写,例如二进制的,把二进制符号0和1分别用不同的幅度来表示, ...
- 九省LNOI2018退役记
立个flag不会退役. Day 0: 水一发. 大连大学的键盘敲起来就跟敲纸似的. 膜拜要进队的gqh,yxd,sjq. (都进啦2333) (高斯消元,高原反应,分麾下治……) 给我这只弱鸡烧根香. ...
- java回文算法
1987891这个就是回文,判断“1987891”是不是回文? 1 public static boolean isPalindrome(String str) { return str.equals ...
- Java的容器类
程序总是根据运行时才知道的某些条件去创建新对象.需要在任意时刻和任意位置创建任意数量的对象. 如果你想保存一组基本数据类型数据,建议使用数组,但是数组有固定的尺寸. 一般情况下,你在写程序时并不知道将 ...
- 一个最简单的使用Entity Framework 查询SQL 数据库的例子
1.ADO.NET 3.5 Entity Framework是随着.net framework 3.5一起发布的,确认开发环境版本是大于等于3.5版本 2.确认已经安装了ADO.NET 3.5 Ent ...
- mysql 对应 binlog 查看
什么是 binlog binlog,即二进制日志,它记录了数据库上的所有改变. 改变数据库的SQL语句执行结束时,将在binlog的末尾写入一条记录,同时通知语句解析器,语句执行完毕. binlog格 ...
- Cloudstack系统配置(三)
系统配置 CloudStack提供一个基于web的UI,管理员和终端用户能够使用这个界面.用户界面版本依赖于登陆时使用的凭证不同而不同.用户界面是适用于大多数流行的浏览器包括IE7,IE8,IE9,F ...
- P1993 小K的农场 && 差分约束
首先第一篇讨论的是差分约束系统解的存在 差分约束系统是有 \(n\) 个变量及 \(m\) 个(如 \(x_{i} - x_{j} \leq a_{k}\) )关系组成的系统 差分约束解的求解可以转化 ...
- SQL Server 2008定期的备份数据库--差异+完整
https://www.cnblogs.com/l1pe1/p/7885207.html https://www.cnblogs.com/tylerflyn/p/8051398.html https: ...
- np.diff函数
np.diff函数 觉得有用的话,欢迎一起讨论相互学习~Follow Me 数组中a[n]-a[n-1] import numpy as np a=np.array([1, 6, 7, 8, 12]) ...