当前位置:   article > 正文

pytorch 实现gru_知识干货-动手学深度学习(pytorch)-13 循环神经网络进阶

pytorch实现gru网络

412676b412bcfa9c0c2eff36f416c817.png

GRU
RNN存在的问题:梯度较容易出现衰减或爆炸(BPTT)
⻔控循环神经⽹络:捕捉时间序列中时间步距离较⼤的依赖关系RNN:

8bbfd3c1496c75312fd1f11b84f4b2e8.png

GRU:

1176423dfb2680802f41959d000b7c25.png

d6d4ab04c26df23e4a5fe2576dfd4208.png

载入数据集

  1. import os
  2. os.listdir('/home/kesci/input')
  3. import numpy as np
  4. import torch
  5. from torch import nn, optim
  6. import torch.nn.functional as F
  7. import sys
  8. sys.path.append("../input/")
  9. import d2l_jay9460 as d2l
  10. device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
  11. (corpus_indices, char_to_idx, idx_to_char, vocab_size) = d2l.load_data_jay_lyrics()

初始化参数

  1. num_inputs, num_hiddens, num_outputs = vocab_size, 256, vocab_size
  2. print('will use', device)
  3. def get_params():
  4. def _one(shape):
  5. ts = torch.tensor(np.random.normal(0, 0.01, size=shape), device=device, dtype=torch.float32) #正态分布
  6. return torch.nn.Parameter(ts, requires_grad=True)
  7. def _three():
  8. return (_one((num_inputs, num_hiddens)),
  9. _one((num_hiddens, num_hiddens)),
  10. torch.nn.Parameter(torch.zeros(num_hiddens, device=device, dtype=torch.float32), requires_grad=True))
  11. W_xz, W_hz, b_z = _three() # 更新门参数
  12. W_xr, W_hr, b_r = _three() # 重置门参数
  13. W_xh, W_hh, b_h = _three() # 候选隐藏状态参数
  14. # 输出层参数
  15. W_hq = _one((num_hiddens, num_outputs))
  16. b_q = torch.nn.Parameter(torch.zeros(num_outputs, device=device, dtype=torch.float32), requires_grad=True)
  17. return nn.ParameterList([W_xz, W_hz, b_z, W_xr, W_hr, b_r, W_xh, W_hh, b_h, W_hq, b_q])
  18. def init_gru_state(batch_size, num_hiddens, device): #隐藏状态初始化
  19. return (torch.zeros((batch_size, num_hiddens), device=device), )

GRU模型

  1. def gru(inputs, state, params):
  2. W_xz, W_hz, b_z, W_xr, W_hr, b_r, W_xh, W_hh, b_h, W_hq, b_q = params
  3. H, = state
  4. outputs = []
  5. for X in inputs:
  6. Z = torch.sigmoid(torch.matmul(X, W_xz) + torch.matmul(H, W_hz) + b_z)
  7. R = torch.sigmoid(torch.matmul(X, W_xr) + torch.matmul(H, W_hr) + b_r)
  8. H_tilda = torch.tanh(torch.matmul(X, W_xh) + R * torch.matmul(H, W_hh) + b_h)
  9. H = Z * H + (1 - Z) * H_tilda
  10. Y = torch.matmul(H, W_hq) + b_q
  11. outputs.append(Y)
  12. return outputs, (H,)

训练模型

  1. num_epochs, num_steps, batch_size, lr, clipping_theta = 160, 35, 32, 1e2, 1e-2
  2. pred_period, pred_len, prefixes = 40, 50, ['分开', '不分开']
  3. d2l.train_and_predict_rnn(gru, get_params, init_gru_state, num_hiddens,
  4. vocab_size, device, corpus_indices, idx_to_char,
  5. char_to_idx, False, num_epochs, num_steps, lr,
  6. clipping_theta, batch_size, pred_period, pred_len,
  7. prefixes)
  8. out:
  9. epoch 40, perplexity 149.271885, time 1.17 sec
  10. - 分开 我想我不不 我想你的让我 你想我的让我 你想我不想 我想你我想想想想想你想你的可爱人 坏我的让我
  11. - 不分开 我想你我不想 你不我 我想你的爱爱 我想你的让我 我想你我想想想想想想你的可爱人 坏我的让我 我
  12. epoch 160, perplexity 1.427383, time 1.16 sec
  13. - 分开 我已带口 你已已是不起 让你知没面对我 甩散球我满腔的怒火 我想揍你已经很久 别想躲 说你眼睛看着
  14. - 不分开 整过 是你开的玩笑 想通 却又再考倒我 说散 你想很久了吧? 败给你的黑色幽默 说散 你想很久了吧

简洁实现

  1. num_hiddens=256
  2. num_epochs, num_steps, batch_size, lr, clipping_theta = 160, 35, 32, 1e2, 1e-2
  3. pred_period, pred_len, prefixes = 40, 50, ['分开', '不分开']
  4. lr = 1e-2 # 注意调整学习率
  5. gru_layer = nn.GRU(input_size=vocab_size, hidden_size=num_hiddens)
  6. model = d2l.RNNModel(gru_layer, vocab_size).to(device)
  7. d2l.train_and_predict_rnn_pytorch(model, num_hiddens, vocab_size, device,
  8. corpus_indices, idx_to_char, char_to_idx,
  9. num_epochs, num_steps, lr, clipping_theta,
  10. batch_size, pred_period, pred_len, prefixes)
  11. #output
  12. epoch 40, perplexity 1.016101, time 0.89 sec
  13. - 分开始想像 爸和妈当年的模样 说著一口吴侬软语的姑娘缓缓走过外滩 消失的 旧时光 一九四三 回头看 的片
  14. - 不分开暴风圈来不及逃 我不能再想 我不能再想 我不 我不 我不能 爱情走的太快就像龙卷风 不能承受我已无处
  15. epoch 80, perplexity 1.010881, time 0.96 sec
  16. - 分开都会值得去做 我想大声宣布 对你依依不舍 连隔壁邻居都猜到我现在的感受 河边的风 在吹着头发飘动 牵
  17. - 不分开暴风圈来不及逃 我不能再想 我不能再想 我不 我不 我不能 爱情走的太快就像龙卷风 不能承受我已无处
  18. epoch 120, perplexity 1.011403, time 0.95 sec
  19. - 分开的我爱你看棒球 想这样没担忧 唱着歌 一直走 我想就这样牵着你的手不放开 爱可不可以简简单单没有伤害
  20. - 不分开暴风圈来不及逃 我不能再想 我不能再想 我不 我不 我不能 爱情走的太快就像龙卷风 不能承受我已无处
  21. epoch 160, perplexity 1.058085, time 0.88 sec
  22. - 分开始打呼 管到当初爱你的时空 停格内容不忠 所有回忆对着我进攻 简单爱情来的太快就像龙卷风 离不开
  23. - 不分开始打呼 管家是一只是我怕眼泪撑不住 不懂 你给我抬起头 有话去对医药箱说 别怪我 别怪我 说你怎么面

LSTM

长短期记忆long short-term memory :
遗忘门:控制上一时间步的记忆细胞 输入门:控制当前时间步的输入
输出门:控制从记忆细胞到隐藏状态
记忆细胞:⼀种特殊的隐藏状态的信息的流动

bd4287f2691e5cfc8e6914ade6202ec7.png

f2a43d38f6cdcb28a63d3a3bb6fc6702.png

初始化参数

  1. num_inputs, num_hiddens, num_outputs = vocab_size, 256, vocab_size
  2. print('will use', device)
  3. def get_params():
  4. def _one(shape):
  5. ts = torch.tensor(np.random.normal(0, 0.01, size=shape), device=device, dtype=torch.float32)
  6. return torch.nn.Parameter(ts, requires_grad=True)
  7. def _three():
  8. return (_one((num_inputs, num_hiddens)),
  9. _one((num_hiddens, num_hiddens)),
  10. torch.nn.Parameter(torch.zeros(num_hiddens, device=device, dtype=torch.float32), requires_grad=True))
  11. W_xi, W_hi, b_i = _three() # 输入门参数
  12. W_xf, W_hf, b_f = _three() # 遗忘门参数
  13. W_xo, W_ho, b_o = _three() # 输出门参数
  14. W_xc, W_hc, b_c = _three() # 候选记忆细胞参数
  15. # 输出层参数
  16. W_hq = _one((num_hiddens, num_outputs))
  17. b_q = torch.nn.Parameter(torch.zeros(num_outputs, device=device, dtype=torch.float32), requires_grad=True)
  18. return nn.ParameterList([W_xi, W_hi, b_i, W_xf, W_hf, b_f, W_xo, W_ho, b_o, W_xc, W_hc, b_c, W_hq, b_q])
  19. def init_lstm_state(batch_size, num_hiddens, device):
  20. return (torch.zeros((batch_size, num_hiddens), device=device),
  21. torch.zeros((batch_size, num_hiddens), device=device))

LSTM模型

  1. def lstm(inputs, state, params):
  2. [W_xi, W_hi, b_i, W_xf, W_hf, b_f, W_xo, W_ho, b_o, W_xc, W_hc, b_c, W_hq, b_q] = params
  3. (H, C) = state
  4. outputs = []
  5. for X in inputs:
  6. I = torch.sigmoid(torch.matmul(X, W_xi) + torch.matmul(H, W_hi) + b_i)
  7. F = torch.sigmoid(torch.matmul(X, W_xf) + torch.matmul(H, W_hf) + b_f)
  8. O = torch.sigmoid(torch.matmul(X, W_xo) + torch.matmul(H, W_ho) + b_o)
  9. C_tilda = torch.tanh(torch.matmul(X, W_xc) + torch.matmul(H, W_hc) + b_c)
  10. C = F * C + I * C_tilda
  11. H = O * C.tanh()
  12. Y = torch.matmul(H, W_hq) + b_q
  13. outputs.append(Y)
  14. return outputs, (H, C)

训练模型

  1. num_epochs, num_steps, batch_size, lr, clipping_theta = 160, 35, 32, 1e2, 1e-2
  2. pred_period, pred_len, prefixes = 40, 50, ['分开', '不分开']
  3. d2l.train_and_predict_rnn(lstm, get_params, init_lstm_state, num_hiddens,
  4. vocab_size, device, corpus_indices, idx_to_char,
  5. char_to_idx, False, num_epochs, num_steps, lr,
  6. clipping_theta, batch_size, pred_period, pred_len,
  7. prefixes)
  8. #output
  9. epoch 40, perplexity 211.457328, time 1.51 sec
  10. - 分开 我不的我 我不的我 我不不 我不的我 我不不 我不的我 我不不 我不的我 我不不 我不的我 我不不
  11. - 不分开 我不不 我不的我 我不不 我不的我 我不不 我不的我 我不不 我不的我 我不不 我不的我 我不不
  12. epoch 80, perplexity 68.458662, time 1.50 sec
  13. - 分开 我想你这你 我不要这你 我不要这你 我不要这你 我不要这你 我不要这你 我不要这你 我不要这你 我
  14. - 不分开 我想你你的你 我想要你 我不要 我不要 我不要 我不要 我不要 我不要 我不要 我不要 我不要 我

简洁实现

  1. num_hiddens=256
  2. num_epochs, num_steps, batch_size, lr, clipping_theta = 160, 35, 32, 1e2, 1e-2
  3. pred_period, pred_len, prefixes = 40, 50, ['分开', '不分开']
  4. lr = 1e-2 # 注意调整学习率
  5. lstm_layer = nn.LSTM(input_size=vocab_size, hidden_size=num_hiddens)
  6. model = d2l.RNNModel(lstm_layer, vocab_size)
  7. d2l.train_and_predict_rnn_pytorch(model, num_hiddens, vocab_size, device,
  8. corpus_indices, idx_to_char, char_to_idx,
  9. num_epochs, num_steps, lr, clipping_theta,
  10. batch_size, pred_period, pred_len, prefixes)
  11. epoch 40, perplexity 1.019881, time 1.04 sec
  12. - 分开始打呼 管家是一只会说法语举止优雅的猪 吸血前会念约翰福音做为弥补 拥有一双蓝色眼睛的凯萨琳公主 专
  13. - 不分开的玩笑 想通 却又再考倒我 说散 你想很久了吧? 败给你的黑色幽默 不想太多 我想一定是我听错弄错搞
  14. epoch 80, perplexity 1.013078, time 1.01 sec
  15. - 分开的话像语言暴力 我已无能为力再提起 决定中断熟悉 然后在这里 不限日期 然后将过去 慢慢温习 让我爱
  16. - 不分开的玩笑 想通 却又再考倒我 说散 你想很久了吧? 败给你的黑色幽默 说散 你想很久了吧? 我的认真败

深度循环神经网络

2a3f681f845745b443cadadf98b8514a.png
  1. num_hiddens=256
  2. num_epochs, num_steps, batch_size, lr, clipping_theta = 160, 35, 32, 1e2, 1e-2
  3. pred_period, pred_len, prefixes = 40, 50, ['分开', '不分开']
  4. lr = 1e-2 # 注意调整学习率
  5. gru_layer = nn.LSTM(input_size=vocab_size, hidden_size=num_hiddens,num_layers=2)
  6. model = d2l.RNNModel(gru_layer, vocab_size).to(device)
  7. d2l.train_and_predict_rnn_pytorch(model, num_hiddens, vocab_size, device,
  8. corpus_indices, idx_to_char, char_to_idx,
  9. num_epochs, num_steps, lr, clipping_theta,
  10. batch_size, pred_period, pred_len, prefixes)
  11. #
  12. epoch 40, perplexity 12.840496, time 1.52 sec
  13. - 分开我 想你的话我在想再你的让我女疼 我想你 我有要有 想你你 想你的让我女沉 我想你你 想你的让我女沉
  14. - 不分开的经爱女人 坏坏的让我疯狂的可爱女人 坏坏的让我疯狂的可爱女人 坏坏的让我疯狂的可爱女人 坏坏的让我
  15. epoch 80, perplexity 1.247634, time 1.52 sec
  16. - 分开有一条热昏头的响尾蛇 无力的躺在干枯的河 在等待雨季来临变沼泽 灰狼啃食著水鹿的骨头 秃鹰盘旋死盯着
  17. - 不分开的会手 穿梭放受 一朵一朵因你而香 试图让夕阳飞翔 带领你我环绕大自然 迎著风 开始共渡每一天 手牵
  1. gru_layer = nn.LSTM(input_size=vocab_size, hidden_size=num_hiddens,num_layers=6)
  2. model = d2l.RNNModel(gru_layer, vocab_size).to(device)
  3. d2l.train_and_predict_rnn_pytorch(model, num_hiddens, vocab_size, device,
  4. corpus_indices, idx_to_char, char_to_idx,
  5. num_epochs, num_steps, lr, clipping_theta,
  6. batch_size, pred_period, pred_len, prefixes)

双向循环神经网络

198b3e42f6b350e2f427f887a6166b78.png
  1. num_hiddens=128
  2. num_epochs, num_steps, batch_size, lr, clipping_theta = 160, 35, 32, 1e-2, 1e-2
  3. pred_period, pred_len, prefixes = 40, 50, ['分开', '不分开']
  4. lr = 1e-2 # 注意调整学习率
  5. gru_layer = nn.GRU(input_size=vocab_size, hidden_size=num_hiddens,bidirectional=True)
  6. model = d2l.RNNModel(gru_layer, vocab_size).to(device)
  7. d2l.train_and_predict_rnn_pytorch(model, num_hiddens, vocab_size, device,
  8. corpus_indices, idx_to_char, char_to_idx,
  9. num_epochs, num_steps, lr, clipping_theta,
  10. batch_size, pred_period, pred_len, prefixes)
  11. epoch 40, perplexity 1.001741, time 0.91 sec
  12. - 分开始开始开始开始开始开始开始开始开始开始开始开始开始开始开始开始开始开始开始开始开始开始开始开始开始开
  13. - 不分开始开始开始开始开始开始开始开始开始开始开始开始开始开始开始开始开始开始开始开始开始开始开始开始开始开
  14. epoch 80, perplexity 1.000520, time 0.91 sec
  15. - 分开始开始开始开始开始开始开始开始开始开始开始开始开始开始开始开始开始开始开始开始开始开始开始开始开始开
  16. - 不分开始开始开始开始开始开始开始开始开始开始开始开始开始开始开始开始开始开始开始开始开始开始开始开始开始开
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/101490
推荐阅读
相关标签
  

闽ICP备14008679号