本篇文章5784字,读完约14分钟
雷锋。这篇文章是由magicly博客转载并经作者授权的。要阅读原文,请参阅:magicly.me/2017/04/07/rnn-lstm-generate-name/? UTM _ source = tui cool & UTM _ media = reference .
Magicly:我以前翻译过一篇关于rnn的文章,但是我从来没有看到作者写一篇关于lstm的新博客,所以我找到了其他材料来研究。本文首先介绍了lstm,然后利用lstm对金庸和古龙的名字进行训练,从而生成新的武术名称。如果你感兴趣,你也可以收集更多的名字给孩子命名。哈哈,只是为了好玩,每个人都很开心…
Rnn回顾了rnn的出现,以解决状态记忆问题。解决方法很简单。每个时间点t的隐藏状态h(t)不再简单地依赖于数据,而是还依赖于先前时间节点t-1的隐藏状态h (t-1)。可以看出,这是一个递归定义(因此递归神经网络也称为递归神经网络)。h(t-1)取决于h(t-2),h(t-2)取决于h(t-3)...所以h(t)取决于之前每个时间点的输入,这意味着H (t)记得之前的一切
如果上述数字随时间扩展,可以看出rnn实际上是普通神经网络的时间堆栈。
Rnn问题:长期依赖一切似乎都是完美的,但如果h(t)依赖于h(t-1000),依赖路径很长,这将导致梯度计算时梯度的消失,并且训练时间太长,无法实际使用。下面是一个长依赖路径的示例:
1来自我的家乡[成都]。。。[这里省略了500字]。。。我们经常在那里吃火锅。。。
Lstmlong短期记忆神经网络,即lstm,由hochreiter & schmidhuber于1997年发表。它似乎解决了长期依赖的问题,近年来出现了许多改进版本。目前,它被应用于许多领域(包括机器翻译、对话机器人、语音识别、图像字幕等)。)。
在标准rnn中,重复模块只是一个非常简单的结构,如下图所示:
Lstm是一个类似的链表结构,但是它的内部结构要复杂得多:
上图中的图标具有以下含义:
lstm的核心思想是单元状态(类似于隐藏状态,一些lstm变体结合了单元状态和隐藏状态,如gru)以及三种门:输入门、遗忘门和输出门。
每一次,细胞状态作为输入被传送到下一个时间点,并且在一些线性变化之后,它继续到下一个时间点(我还没有阅读原始的论文,并且我不知道为什么在我有隐藏状态之后我需要细胞状态。幸运的是,有一个结合了这两者的改进版本,所以我暂时不讨论它)。
门的概念来自电路设计(如果我没学过,我就不敢炫耀)。在lstm中,门控制着通过门后能留下多少信息。如下图所示,sigmoid层输出值[0,1],该值决定有多少数据可以通过门。0表示没有人能通过,1表示所有人都通过。
让我们看看每个“门”都在做什么。
首先,我们必须决定需要保留多少先前的单元状态。根据h(t-1)和x(t),它计算一个数字[0,1],并确定保留多少单元状态。0表示全部丢弃,1表示全部保留。我们为什么要扔掉它?尽可能多地保留它不是更好吗?假设lstm正在生成一篇小明和小红的文章。小明在看电视,小红在厨房做饭。如果当前的主题是小明,好的,那么lstm应该输出电视相关的项目,如寻找一个遥控器和改变频道。如果话题已经转到小红身上,最好暂时忘掉电视,输出洗菜、酱油、电饭煲等等。
第二步是决定输入对单元状态的影响程度。这个地方由两部分组成,一部分是计算sigmoid函数还剩多少数据,另一部分是通过tanh函数计算候选c(t)。这个地方就像主题从小明切换到小红,所以电视应该切换到厨房。
然后,我们将剩余的单元状态(在时间t-1)与新添加的单元状态相结合,以获得时间t的单元状态。
最后,我们通过tanh将单元状态压缩为[-1,1],然后将其发送到输出门([0,1]决定输出多少)。
现在有许多不同的lstm,感兴趣的人可以在这里看到。此外,lstm只是为了解决rnn的长期依赖性,其他人已经从另一个角度解决了这个问题,如koutnik等人(2014)的时钟工作rnn。
给我看看密码!我使用了安德烈·卡普西的代码,做了一些小改动。这段代码的优点是它不依赖于任何深度学习框架,只需要numpy立即运行!
"""
最小字符级普通rnn模型。作者:andrej karpathy (@karpathy)
bsd许可证
"""
将numpy作为np导入
#数据i/o
data = open( input.txt,r)。read() #应该是简单的纯文本文件
all _ name = set(data . split(" \ n "))
chars =列表(集合(数据))
data_size,vocab_size = len(数据),len(字符)
打印(数据有%d个字符,%d个唯一字符。% (data_size,vocab_size))
char_to_ix = {ch: i代表I,ch在枚举中(chars)}
ix_to_char = {i: ch for i,ch in enumerate(chars)}
#打印(char_to_ix,ix_to_char)
#超参数
hidden_size = 100 #神经元隐藏层的大小
seq_length = 25 #展开rnn的步骤数
学习率= 1e-1
#模型参数
wxh = NP . random . randn(hidden _ size,vocab_size) * 0.01 #输入至hidden
whh = np.random.randn(隐藏_大小,隐藏_大小)* 0.01 #隐藏到隐藏
为什么= np.random.randn(vocab_size,hidden_size) * 0.01 #输出隐藏
BH = NP . zero((hidden _ size,1)) #隐藏偏差
by = NP . zero((vocab _ size,1)) #输出偏置
def lossfun(输入、目标、hprev):
"""
输入、目标都是整数列表。
hprev是初始隐藏状态的hx1数组
返回损失、模型参数的梯度和最后的隐藏状态
"""
xs,hs,ys,ps = {},{},{},{}
hs[-1] = np.copy(hprev)
损耗= 0
#向前传球
对于测试范围(len(输入)):
xs[t] =
xs[t][输入[t]] = 1
hs[t] = np.tanh(np.dot(wxh,xs[t]) + np.dot(whh,
hs[t - 1]) + bh) #隐藏状态
#下一个字符的非标准化日志概率
ys[t] = np.dot(为什么,hs[t]) + by
下一个字符的概率
PS[t]= NP . exp(ys[t])/NP . sum(NP . exp(ys[t])
损失+= -np.log(ps[t][targets[t],0]) # softmax(交叉熵损失)
#反向通过:计算反向渐变
dwxh,dwhh,dwhy = np.zeros _ like(
wxh),NP . zero _ like(whh),NP . zero _ like(为什么)
dbh,dby = NP . zero _ like(BH),NP . zero _ like(by)
dhnext = np.zeros_like(hs[0])
对于反向测试(范围(len(输入))):
dy = np.copy(ps[t])
#返回y .参见
# cs231n.github.io/neural-networks-case-study/#grad如果困惑
#这里
dy[targets[t]] -= 1
dwhy += np.dot(dy,hs[t]。t)
dby += dy
dh = np.dot(why.t,dy)+dhnext # back drop进入h
dhraw = (1 - hs[t] * hs[t]) * dh #通过tanh非线性反向传播
dbh += dhraw
dwxh += np.dot(dhraw,xs[t]。t)
dwhh += np.dot(dhraw,hs[t - 1]。t)
dhnext = np.dot(whh.t,dhraw)
对于[dwxh,dwhh,dwhy,dbh,dby]中的dparam:
#剪辑以减轻爆炸梯度
np.clip(dparam,-5,5,out=dparam)
回波损耗,dwxh,dwhh,dwhy,dbh,dby,hs[len(输入)- 1]
def样本(h,seed_ix,n):
"""
从模型中采样一系列整数
h为记忆状态,seed_ix为第一步的种子字母
"""
x = NP . zero((vocab _ size,1))
x[seed_ix] = 1
ixes = []
对于范围(n)内的t:
h = np.tanh(np.dot(wxh,x) + np.dot(whh,h) + bh)
y = np.dot(为什么,h) + by
p = np.exp(y) / np.sum(np.exp(y))
ix = np.random.choice(范围(vocab_size),p=p.ravel())
x = NP . zero((vocab _ size,1))
x[ix] = 1
IX . append(IX)
返回ixes
n,p = 0,0
mwxh,mwhh,mwhy = NP . zero like(wxh),NP . zero like(whh),NP . zero like(为什么)
mbh,mby = np.zeros_like(bh),NP . zeros _ like(by)# adagrad的内存变量
smooth _ loss =-NP . log(1.0/vocab _ size)* seq _ length #迭代0时的损失
虽然正确:
#准备输入(我们在seq_length步骤中从左向右扫描
#长)
如果p + seq_length + 1 >= len(数据)或n == 0:
HP rev = NP . zeross((hidden _ size,1)) #复位rnn存储器
p = 0 #从数据开始
输入=[数据中ch的char _ to _ IX[ch ][ p:p+seq _ length]]
目标=[数据中ch的char _ to _ IX[ch ][ p+1:p+seq _ length+1]]
#不时从模型中取样
如果n % 100 == 0:
sample_ix = sample(hprev,输入[0],200)
txt =。连接(样本ix中ix的ix_to_char[ix])
打印(- \n %s \n - % (txt,)
#将seq_length字符通过网络转发并获取渐变
loss,dwxh,dwhh,dwhy,dbh,dby,hprev = lossfun(输入,目标,hprev)
平滑_损失=平滑_损失* 0.999 +损失* 0.001
如果n % 100 == 0:
打印(iter %d,损耗:%f % (n,smooth_loss)) #打印进度
#使用adagrad执行参数更新
对于param,dparam,mem in zip([wxh,whh,why,bh,by],
[dwxh,dwhh,dwhy,dbh,dby],
[mwxh、mwhh、mwhy、mbh、mby]:
mem += dparam * dparam
param += -learning_rate * dparam / \
np.sqrt(mem + 1e-8) # adagrad更新
p += seq_length #移动数据指针
n += 1 #迭代计数器
如果((平滑_损失= 20000)):
sample_ix = sample(hprev,inputs[0],2000)
txt =。连接(样本ix中ix的ix_to_char[ix])
expected _ name = set(txt . split(" \ n "))
新名称=预测名称-所有名称
打印(新名称)
打印(预测名称len: %d,新名称len: %d,\n % (len(预测名称),len(新名称)))
破裂
viewrawmin-char-rnn . py hosted with?bygithub
然后我从网上找到金庸小说的名字,做了一些预处理,每行一个名字,保存在input.txt中,然后运行代码。顾龙没有找到完整的名字,只有这份武术名单,只有100多人。
以下是基于这两个列表的训练结果,相同的名字(如段宇)都被去掉了,所以以下都是lstm的“新创造和发明”的名字。来,猜猜哪一个是金庸的,哪一个是古龙的。
{姜增铁、袁、石、郭万臣、、程、王铁之、陈毅、薛铁、哈赤、尹、钟小艳、冯一刀、鲍兰、齐,若无其事,王老营、钟、、石、李元珍、曹兰、赵桑飞西、上官红喜红、刘志宇、童怀道、周云鹤、田、冯、奚灵素、大治湖石、阮土忠、王兆能、袁正义、尚保和、常伯峰 冯一弼、曹阙、、曾铁文、顾若芝、、、崔百真、陈冠、陈仲、倪凤峰、梅原道、徐、任彤都、上官铁楚容、大建台、、盛、南、南转、石双镇、海铁山、尹和珍、司、德晓、吴若思、、田青
{邀请函3,熊猫凯,鹰星,陆凯,华,薛玉洛平,南宫主,南宫九,孙夫人,景冬梅,铁急,裴都,,满,陆子无齿,连,钟,,方达,叶魂,落寞红,叶,雷。约请一郎、东楼、铁十一红、、伍伟柳老峰三、萧茂儿、东郭先锋、李顺、狄先生、孟建兴、蒋晓峰、华双楼、、邱珏、白坏刹、阎悲、冀北岩、董、陆丰、碧玉波等流颜南田、萧连景、龙步岩、董国玉、司东郭金田、薛、熊宝玉、吴、刘、、刘、东莞小雨、渐飞、陆鱼、吹王、傲骨 谢郎唐傲、铁夜帝、蒋晓峰、孙玉叶、邱任重、柴兴富、詹夫人、贾斯珀、老吴俞、铁铁铁花、杜、薛龚玥九、老郭和尚、龙冠飞、东郭鲁大、司臧、李倩、孙柏芝、南双平、王惠、纪元庆、孙瑜、东郭大路、白玉罗生、高二、董觉天、萧望尚、九、关垂学、上官晓峰、邱上官金飞、陆上龙晓天、空灵魂、衣服邀请人
感兴趣的人也可以用古代诗人、诗人等的名字。训练。如果你有好的机器或时间,你可以训练更多。你训练得越多,你就越准确。
综上所述,rnn由于其记忆功能,在自然语言处理、语音、计算机视觉等诸多领域显示出巨大的优势。实际上,rnn相当于图灵。
如果训练普通神经网络是对函数的优化,那么训练递归网络就是对程序的优化。
Lstm是一种常用且实用的rnn算法,主要解决rnn的长期依赖性问题。此外,rnn一直在进行新的研究,如注意机制。又有空要介绍了。。。
referscolah.github.io/posts/2015-08-understanding-lstms/
karpathy.github.io/2015/05/21/rnn-effectiveness/
胡志/问题/29411132
gist.github/karpathy/d4dee566867f8291f086
深度学习4j/lstm雷锋网雷锋网(公开号:雷锋网)
相关文章:
谷歌大脑科学家理解lstm:一个关于“遗忘”和“记忆”的故事
老板来了:人脸识别+手机按键,老板来了你马上就知道了!
雷锋文章版权所有。严禁擅自转载。详情请参考转载说明。
来源:搜狐微门户
标题:用金庸、古龙群侠名称训练 LSTM 会生成多么奇葩的名字?
地址:http://www.shwmhw.com/shxw/60042.html