blob: d5a9d881a7d74572c65302a0817b9e0d046a291d [file] [log] [blame]
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
from singa import autograd, layer, model
class QAModel_mlp(model.Model):
def __init__(self, hidden_size):
super().__init__()
self.linear_q = layer.Linear(hidden_size)
self.linear_a = layer.Linear(hidden_size)
def forward(self, q, a_batch):
q = autograd.reshape(q, (q.shape[0], -1)) # bs, seq_q*data_s
a_batch = autograd.reshape(a_batch,
(a_batch.shape[0], -1)) # 2bs, seq_a*data_s
q = self.linear_q(q) # bs, hid_s
a_batch = self.linear_a(a_batch) # 2bs, hid_s
a_pos, a_neg = autograd.split(a_batch, 0,
[q.shape[0], q.shape[0]]) # 2*(bs, hid)
sim_pos = autograd.cossim(q, a_pos)
sim_neg = autograd.cossim(q, a_neg)
return sim_pos, sim_neg
class QAModel(model.Model):
def __init__(self,
hidden_size,
num_layers=1,
bidirectional=True,
return_sequences=False):
super(QAModel, self).__init__()
self.hidden_size = hidden_size
self.lstm_q = layer.CudnnRNN(hidden_size=hidden_size,
bidirectional=bidirectional,
return_sequences=return_sequences)
self.lstm_a = layer.CudnnRNN(hidden_size=hidden_size,
bidirectional=bidirectional,
return_sequences=return_sequences)
def forward(self, q, a_batch):
q = self.lstm_q(q) # bs, Hidden*2
a_batch = self.lstm_a(a_batch) # 2bs, Hidden*2
bs_a = q.shape[0]
# bs, hid*2
a_pos, a_neg = autograd.split(a_batch, 0, [bs_a, bs_a])
sim_pos = autograd.cossim(q, a_pos)
sim_neg = autograd.cossim(q, a_neg)
return sim_pos, sim_neg
class QAModel_mean(model.Model):
def __init__(self, hidden_size, bidirectional=True, return_sequences=True):
super(QAModel_mean, self).__init__()
self.hidden_size = hidden_size
self.lstm_q = layer.CudnnRNN(hidden_size=hidden_size,
batch_first=True,
bidirectional=bidirectional,
return_sequences=return_sequences)
self.lstm_a = layer.CudnnRNN(hidden_size=hidden_size,
batch_first=True,
bidirectional=bidirectional,
return_sequences=return_sequences)
def forward(self, q, a_batch):
q = self.lstm_q(q) # bs, seq, Hidden*2
a_batch = self.lstm_a(a_batch) # 2bs, seq, Hidden*2
# bs, hid*2
q = autograd.reduce_mean(q, [1], keepdims=0)
# (2bs, hid*2)
a_batch = autograd.reduce_mean(a_batch, [1], keepdims=0)
# 2*(bs, seq, hid*2)
a_pos, a_neg = autograd.split(a_batch, 0, [q.shape[0], q.shape[0]])
sim_pos = autograd.cossim(q, a_pos)
sim_neg = autograd.cossim(q, a_neg)
return sim_pos, sim_neg
class QAModel_maxpooling(model.Model):
def __init__(self,
hidden_size,
q_seq,
a_seq,
num_layers=1,
bidirectional=True,
return_sequences=True):
super(QAModel_maxpooling, self).__init__()
self.hidden_size = hidden_size
self.lstm_q = layer.CudnnRNN(hidden_size=hidden_size,
bidirectional=bidirectional,
return_sequences=return_sequences)
self.lstm_a = layer.CudnnRNN(hidden_size=hidden_size,
bidirectional=bidirectional,
return_sequences=return_sequences)
self.q_pool = layer.MaxPool2d((q_seq, 1))
self.a_pool = layer.MaxPool2d((a_seq, 1))
def forward(self, q, a_batch):
# bs, seq, Hidden*2
q = self.lstm_q(q)
# bs, 1, seq, hid*2
q = autograd.reshape(q, (q.shape[0], 1, q.shape[1], q.shape[2]))
# bs, 1, 1, hid*2
q = self.q_pool(q)
# bs, hid*2
q = autograd.reshape(q, (q.shape[0], q.shape[3]))
# 2bs, seq, Hidden*2
a_batch = self.lstm_a(a_batch)
# 2bs, 1, seq, hid*2
a_batch = autograd.reshape(
a_batch, (a_batch.shape[0], 1, a_batch.shape[1], a_batch.shape[2]))
# 2bs, 1, 1, hid*2
a_batch = self.a_pool(a_batch)
# 2bs, hid*2
a_batch = autograd.reshape(a_batch,
(a_batch.shape[0], a_batch.shape[3]))
# 2*(bs, hid*2)
a_pos, a_neg = autograd.split(a_batch, 0, [q.shape[0], q.shape[0]])
sim_pos = autograd.cossim(q, a_pos)
sim_neg = autograd.cossim(q, a_neg)
return sim_pos, sim_neg