class ResidualBiRNNBuilder: """ A residual network with bidirectional first layer """ def __init__(self, num_layers, input_dim, hidden_dim, add_to_output=False, dropout=None, exp_global=Ref(Path("exp_global"))): assert num_layers > 1 assert hidden_dim % 2 == 0 self.forward_layer = UniLSTMSeqTransducer(exp_global=exp_global, input_dim=input_dim, hidden_dim=hidden_dim/2, dropout=dropout) self.backward_layer = UniLSTMSeqTransducer(exp_global=exp_global, input_dim=input_dim, hidden_dim=hidden_dim/2, dropout=dropout) self.residual_network = ResidualRNNBuilder(exp_global=exp_global, num_layers=num_layers - 1, input_dim=hidden_dim, hidden_dim=hidden_dim, add_to_output=add_to_output, dropout=dropout) def get_final_states(self): return self._final_states def add_inputs(self, es): return PseudoState(self, self.transduce(es)) def transduce(self, es): forward_e = self.forward_layer(es) backward_e = self.backward_layer(ReversedExpressionSequence(es)) self._final_states = [FinalTransducerState(dy.concatenate([self.forward_layer.get_final_states()[0].main_expr(), self.backward_layer.get_final_states()[0].main_expr()]), dy.concatenate([self.forward_layer.get_final_states()[0].cell_expr(), self.backward_layer.get_final_states()[0].cell_expr()]))] output = self.residual_network.transduce(ExpressionSequence(expr_list=[dy.concatenate([f,b]) for f,b in zip(forward_e, ReversedExpressionSequence(backward_e))])) self._final_states += self.residual_network.get_final_states() return output def initial_state(self): return PseudoState(self)
class ResidualBiRNNBuilder(object): """ A residual network with bidirectional first layer. Note: This is currently not serializable and therefore can't be directly specified in the config file; use :class:`xnmt.residual.ResidualLSTMSeqTransducer` instead. Args: num_layers (int): number of layers input_dim (int): input dimension; if None, use exp_global.default_layer_dim hidden_dim (int): hidden dimension; if None, use exp_global.default_layer_dim add_to_output (bool): whether to add a residual connection to the output layer dropout (float): dropout probability; if None, use exp_global.dropout exp_global (ExpGlobal): ExpGlobal object to acquire DyNet params and global settings. By default, references the experiment's top level exp_global object. """ def __init__(self, num_layers, input_dim, hidden_dim, add_to_output=False, dropout=None, exp_global=Ref(Path("exp_global"))): assert num_layers > 1 assert hidden_dim % 2 == 0 self.forward_layer = UniLSTMSeqTransducer(exp_global=exp_global, input_dim=input_dim, hidden_dim=hidden_dim//2, dropout=dropout) self.backward_layer = UniLSTMSeqTransducer(exp_global=exp_global, input_dim=input_dim, hidden_dim=hidden_dim//2, dropout=dropout) self.residual_network = ResidualRNNBuilder(exp_global=exp_global, num_layers=num_layers - 1, input_dim=hidden_dim, hidden_dim=hidden_dim, add_to_output=add_to_output, dropout=dropout) def get_final_states(self): return self._final_states def add_inputs(self, es): return PseudoState(self, self.transduce(es)) def transduce(self, es): forward_e = self.forward_layer(es) backward_e = self.backward_layer(ReversedExpressionSequence(es)) self._final_states = [FinalTransducerState(dy.concatenate([self.forward_layer.get_final_states()[0].main_expr(), self.backward_layer.get_final_states()[0].main_expr()]), dy.concatenate([self.forward_layer.get_final_states()[0].cell_expr(), self.backward_layer.get_final_states()[0].cell_expr()]))] output = self.residual_network.transduce(ExpressionSequence(expr_list=[dy.concatenate([f,b]) for f,b in zip(forward_e, ReversedExpressionSequence(backward_e))])) self._final_states += self.residual_network.get_final_states() return output def initial_state(self): return PseudoState(self)