Diff of /model.lua [000000] .. [6d0c6b]

Switch to unified view

a b/model.lua
1
require 'torch'
2
require 'nn'
3
require './util/LSTM'
4
require './util/ReverseSequence'
5
require('./util/OneHot.lua')
6
7
8
local Model, parent = torch.class('nn.Model', 'nn.Module')
9
10
11
local function create_lstm(self, reverse)
12
  local lstm = nn.Sequential()
13
14
  if reverse then lstm:add(nn.ReverseSequence(2,self.gpu)) end
15
16
  for i = 1, self.rnn_layers do
17
    local prev_dim = self.rnn_size
18
    if i == 1 then prev_dim = self.wordvec_dim end
19
    local rnn = nn.LSTM(prev_dim, self.rnn_size)
20
    rnn.remember_states = false
21
    table.insert(self.rnns, rnn)
22
    lstm:add(rnn)
23
    if self.dropout > 0 then
24
      lstm:add(nn.Dropout(self.dropout))
25
    end
26
  end
27
28
  if reverse then lstm:add(nn.ReverseSequence(2,self.gpu)) end
29
30
  return lstm
31
end
32
33
34
function Model:__init(opt)
35
  self.gpu = opt.gpu
36
  self.rnn_size = opt.rnn_size
37
  self.rnn_layers = opt.rnn_layers
38
  self.dropout = opt.dropout
39
  self.batchnorm = opt.batchnorm
40
  self.unidirectional = opt.unidirectional
41
  self.wordvec_dim  = #(opt.alphabet)  -- ACGT = 4
42
  self.cnn = opt.cnn
43
  self.rnn = opt.rnn
44
  self.cnn_filters = tablex.map(tonumber, opt.cnn_filters:split('-'))
45
  self.cnn_size = opt.cnn_size
46
  self.cnn_pool = opt.cnn_pool
47
  self.batch_size = opt.batch_size
48
  self.num_classes = opt.num_classes
49
50
  self.rnns = {}
51
  self.model = nn.Sequential()
52
53
  -- Create input embedding (we always use onehot-encoded matrix in this project)
54
  self.model:add(OneHot(self.wordvec_dim))
55
56
  ------------------------------------------
57
  -------- RNN and CNN-RNN Models ----------
58
  ------------------------------------------
59
  if self.rnn then
60
    local CNN = nn.Sequential()
61
    local RNN = nn.Sequential()
62
63
    -----------------------------
64
    ---------- CNN-RNN ----------
65
    -----------------------------
66
    if self.cnn then
67
      -- only use 1 layer of convolution in CNN-RNN
68
      local pad_size = math.floor(self.cnn_filters[1]/2)
69
      CNN:add(nn.SpatialZeroPadding(0,0,pad_size, pad_size))
70
      CNN:add(nn.TemporalConvolution(self.wordvec_dim, self.cnn_size, self.cnn_filters[1]))
71
      CNN:add(nn.ReLU())
72
      self.model:add(CNN)
73
      self.wordvec_dim = self.cnn_size
74
    end
75
76
    -----------------------------
77
    ------------ RNN ------------
78
    -----------------------------
79
    local fwd = create_lstm(self, false)
80
    fwd:add(nn.Mean(2)) -- take mean of output vectors over time dimension
81
    local bwd = create_lstm(self, true)
82
    bwd:add(nn.Mean(2)) -- take mean of output vectors over time dimension
83
84
    local concat = nn.ConcatTable()
85
    local output_size
86
87
    if self.unidirectional then
88
      concat:add(fwd) -- uese ConcatTable for consistency w/ b-lstm
89
      output_size = self.rnn_size
90
    else
91
      concat:add(fwd)
92
      concat:add(bwd)
93
      output_size = self.rnn_size*2
94
    end
95
96
    RNN:add(concat)
97
    RNN:add(nn.JoinTable(2))
98
99
    self.model:add(RNN)
100
101
    -- Create output classifier of (CNN-)RNN
102
    self.model:add(nn.Linear((output_size), self.num_classes))
103
    self.model:add(nn.LogSoftMax())
104
105
  ---------------------------------------
106
  -------------- CNN Model --------------
107
  ---------------------------------------
108
  else
109
    -- Need to compute output sequnece size to be fed to linear classifier
110
    local input_size = self.wordvec_dim
111
112
    -- Create layers
113
    for layer = 1,#self.cnn_filters-1 do
114
      self.model:add(nn.TemporalConvolution(input_size, self.cnn_size, self.cnn_filters[layer]))
115
      input_size = self.cnn_size
116
      self.model:add(nn.ReLU())
117
      self.model:add(nn.TemporalMaxPooling(self.cnn_pool,self.cnn_pool))
118
      if self.dropout > 0 then self.model:add(nn.Dropout(self.dropout)) end
119
    end
120
121
    -- Last layer of convolution
122
    self.model:add(nn.TemporalConvolution(input_size, self.cnn_size, self.cnn_filters[#self.cnn_filters]))
123
    self.model:add(nn.ReLU())
124
    if self.dropout > 0 then self.model:add(nn.Dropout(self.dropout)) end
125
126
    -- Max pool across entire sequence to get unfiform output size,
127
    -- and transpose (view) to feed into linear classifier
128
    self.model:add(nn.Max(2))
129
    self.model:add(nn.View(-1,self.cnn_size))
130
131
    -- Output classifier of CNN --
132
    self.model:add(nn.Linear(self.cnn_size,self.num_classes))
133
    self.model:add(nn.LogSoftMax())
134
  end
135
136
  print('-------- Model Architechture ----------')
137
  print(self.model)
138
end
139
140
141
142
-- Model Functions
143
function Model:updateOutput(input)
144
  return self.model:forward(input)
145
end
146
147
function Model:backward(input, gradOutput, scale)
148
  return self.model:backward(input, gradOutput, scale)
149
end
150
151
function Model:parameters()
152
  return self.model:parameters()
153
end
154
155
function Model:training()
156
  self.model:training()
157
  parent.training(self)
158
end
159
160
function Model:evaluate()
161
  self.model:evaluate()
162
  parent.evaluate(self)
163
end
164
165
function Model:resetStates()
166
  for i, rnn in ipairs(self.rnns) do rnn:resetStates() end
167
end
168
169
function Model:clearState()
170
  self.model:clearState()
171
end