Guest User

Untitled

a guest
Apr 26th, 2018
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.95 KB | None | 0 0
  1. # Michael A. Alcorn
  2.  
  3. import torch
  4. import torch.autograd as autograd
  5. import torch.nn as nn
  6.  
  7.  
  8. def create_lstm(params):
  9. """Create a LSTM from a dictionary of parameters.
  10.  
  11. :param params:
  12. :return:
  13. """
  14. return nn.LSTM(**params)
  15.  
  16.  
  17. def create_h_0_c_0(params):
  18. """Create variables containing LSTM initial hidden state.
  19.  
  20. :param params:
  21. :return:
  22. """
  23. num_directions = 2 if params["bidirectional"] else 1
  24. l_by_d = params["num_layers"] * num_directions
  25. params["num_directions"] = num_directions
  26. params["l_by_d"] = l_by_d
  27. hidden_size = params["hidden_size"]
  28.  
  29. h_0_var = autograd.Variable(torch.randn(l_by_d, hidden_size), requires_grad = True)
  30. c_0_var = autograd.Variable(torch.randn(l_by_d, hidden_size), requires_grad = True)
  31.  
  32. return (h_0_var, c_0_var)
  33.  
  34.  
  35. # Define the size of the input at each step for the encoder and decoder.
  36. input_size = {"e": 6, "d": 4}
  37.  
  38. # Create the encoder.
  39. e_d = {"e": {"input_size": input_size["e"],
  40. "hidden_size": 5,
  41. "num_layers": 3,
  42. "batch_first": True,
  43. "bidirectional": True}}
  44. encoder = create_lstm(e_d["e"])
  45.  
  46. # Create the initial hidden state variables for the encoder.
  47. h_0 = {}
  48. c_0 = {}
  49. (h_0["e"], c_0["e"]) = create_h_0_c_0(e_d["e"])
  50.  
  51. # Create the decoder.
  52. input_size_d = input_size["d"] + e_d["e"]["num_directions"] * e_d["e"]["hidden_size"]
  53. e_d["d"] = {"input_size": input_size_d,
  54. "hidden_size": 9,
  55. "num_layers": 2,
  56. "batch_first": True,
  57. "bidirectional": False}
  58. decoder = create_lstm(e_d["d"])
  59.  
  60. # Create initial hidden state variables for the decoder.
  61. (h_0["d"], c_0["d"]) = create_h_0_c_0(e_d["d"])
  62.  
  63. # Create the attention mechanism.
  64. attn = nn.Linear(e_d["e"]["num_directions"] * e_d["e"]["hidden_size"] + e_d["d"]["hidden_size"], 1)
  65. attn_weights = nn.Softmax(dim = 1)
  66.  
  67. # Create dummy input and output sequences.
  68. seq_lens = {"e": 7, "d": 8}
  69. seqs = {}
  70. for (e_or_d, seq_len) in seq_lens.items():
  71. x = [autograd.Variable(torch.randn((1, input_size[e_or_d]))) for _ in range(seq_len)]
  72. seqs[e_or_d] = torch.cat(x).view(1, len(x), input_size[e_or_d])
  73.  
  74. # Calculate encoder outputs.
  75. (out, (h_e, c_e)) = encoder(seqs["e"], (h_0["e"].unsqueeze(1), c_0["e"].unsqueeze(1)))
  76.  
  77. # Calculate hidden states for decoder using attention mechanism.
  78. (h_t, c_t) = (h_0["d"].unsqueeze(1), c_0["d"].unsqueeze(1))
  79. num_directions_d = e_d["d"]["num_directions"]
  80. hidden_size_d = e_d["d"]["hidden_size"]
  81. input_size_d = input_size["d"]
  82.  
  83. for i in range(seqs["d"].size(1)):
  84. # h[0] is the output of the bottom layer.
  85. h_att = h_t[0].squeeze(1).unsqueeze(0)
  86. h_ex = h_att.expand(1, seq_lens["e"], hidden_size_d)
  87. concat = torch.cat((out, h_ex), 2)
  88.  
  89. att = attn(concat)
  90. att_w = attn_weights(att)
  91. attn_applied = torch.bmm(att_w.view(1, 1, seq_lens["e"]),
  92. out)
  93.  
  94. new_input = torch.cat((seqs["d"][0, i].view(1, 1, input_size_d), attn_applied), dim = 2)
  95. (out_t, (h_t, c_t)) = decoder(new_input, (h_t, c_t))
Add Comment
Please, Sign In to add comment