def _test_three_recurrent_children(self, gpu):
        # Test if https://github.com/chainer/chainer/issues/6053 is addressed
        in_size = 2
        out_size = 6

        rseq = StatelessRecurrentSequential(
            L.NStepLSTM(1, in_size, 3, 0),
            L.NStepGRU(2, 3, 4, 0),
            L.NStepRNNTanh(5, 4, out_size, 0),
        )

        if gpu >= 0:
            chainer.cuda.get_device_from_id(gpu).use()
            rseq.to_gpu()
        xp = rseq.xp

        seqs_x = [
            xp.random.uniform(-1, 1, size=(4, in_size)).astype(np.float32),
            xp.random.uniform(-1, 1, size=(1, in_size)).astype(np.float32),
            xp.random.uniform(-1, 1, size=(3, in_size)).astype(np.float32),
        ]

        # Make and load a recurrent state to check if the order is correct.
        _, rs = rseq.n_step_forward(seqs_x, None, output_mode='concat')
        _, _ = rseq.n_step_forward(seqs_x, rs, output_mode='concat')

        _, rs = rseq.n_step_forward(seqs_x, None, output_mode='split')
        _, _ = rseq.n_step_forward(seqs_x, rs, output_mode='split')
示例#2
0
 def make_q_func(self, env):
     n_hidden_channels = 10
     return StatelessRecurrentSequential(
         L.Linear(env.observation_space.low.size, n_hidden_channels),
         F.elu,
         L.NStepRNNTanh(1, n_hidden_channels, n_hidden_channels, 0),
         L.Linear(n_hidden_channels, env.action_space.n),
         DiscreteActionValue,
     )
    def _test_n_step_forward_with_tuple_output(self, gpu):
        in_size = 5
        out_size = 6

        def split_output(x):
            return tuple(F.split_axis(x, [2, 3], axis=1))

        rseq = StatelessRecurrentSequential(
            L.NStepRNNTanh(1, in_size, out_size, 0),
            split_output,
        )

        if gpu >= 0:
            chainer.cuda.get_device_from_id(gpu).use()
            rseq.to_gpu()
        xp = rseq.xp

        # Input is a list of two variables.
        seqs_x = [
            xp.random.uniform(-1, 1, size=(3, in_size)).astype(np.float32),
            xp.random.uniform(-1, 1, size=(2, in_size)).astype(np.float32),
        ]

        # Concatenated output should be a tuple of three variables.
        concat_out, concat_state = rseq.n_step_forward(seqs_x,
                                                       None,
                                                       output_mode='concat')
        self.assertIsInstance(concat_out, tuple)
        self.assertEqual(len(concat_out), 3)
        self.assertEqual(concat_out[0].shape, (5, 2))
        self.assertEqual(concat_out[1].shape, (5, 1))
        self.assertEqual(concat_out[2].shape, (5, 3))

        # Split output should be a list of two tuples, each of which is of
        # three variables.
        split_out, split_state = rseq.n_step_forward(seqs_x,
                                                     None,
                                                     output_mode='split')
        self.assertIsInstance(split_out, list)
        self.assertEqual(len(split_out), 2)
        self.assertIsInstance(split_out[0], tuple)
        self.assertIsInstance(split_out[1], tuple)
        for seq_x, seq_out in zip(seqs_x, split_out):
            self.assertEqual(len(seq_out), 3)
            self.assertEqual(seq_out[0].shape, (len(seq_x), 2))
            self.assertEqual(seq_out[1].shape, (len(seq_x), 1))
            self.assertEqual(seq_out[2].shape, (len(seq_x), 3))

        # Check if output_mode='concat' and output_mode='split' are consistent
        xp.testing.assert_allclose(
            F.concat([F.concat(seq_out, axis=1) for seq_out in split_out],
                     axis=0).array,
            F.concat(concat_out, axis=1).array,
        )
示例#4
0
 def test(self):
     # Check if it can properly detect recurrent child links
     link = stateless_recurrent.StatelessRecurrentChainList(
         L.Linear(3, 4),
         L.NStepLSTM(1, 3, 2, 0),
         L.Linear(4, 5),
         stateless_recurrent.StatelessRecurrentChainList(
             L.NStepRNNTanh(1, 2, 5, 0), ),
     )
     self.assertEqual(len(link.recurrent_children), 2)
     self.assertIs(link.recurrent_children[0], link[1])
     self.assertIs(link.recurrent_children[1], link[3])
     self.assertEqual(len(link.recurrent_children[1].recurrent_children), 1)
     self.assertIs(link.recurrent_children[1].recurrent_children[0],
                   link[3][0])
示例#5
0
 def make_q_func(self, env):
     obs_size = env.observation_space.low.size
     hidden_size = 64
     return iqn.StatelessRecurrentImplicitQuantileQFunction(
         psi=chainerrl.links.StatelessRecurrentSequential(
             L.Linear(obs_size, hidden_size),
             F.relu,
             L.NStepRNNTanh(1, hidden_size, hidden_size, 0),
         ),
         phi=chainerrl.links.Sequence(
             chainerrl.agents.iqn.CosineBasisLinear(32, hidden_size),
             F.relu,
         ),
         f=L.Linear(hidden_size, env.action_space.n,
                    initialW=chainer.initializers.LeCunNormal(1e-1)),
     )
def make_distrib_recurrent_q_func(env):
    n_atoms = 51
    v_max = 10
    v_min = -10
    return chainerrl.links.StatelessRecurrentSequential(
        L.NStepRNNTanh(1, env.observation_space.low.size, 20, 0),
        chainerrl.q_functions.
        DistributionalFCStateQFunctionWithDiscreteAction(  # NOQA
            20,
            env.action_space.n,
            n_atoms=n_atoms,
            v_min=v_min,
            v_max=v_max,
            n_hidden_channels=None,
            n_hidden_layers=0,
        ),
    )
    def _test_n_step_forward_with_tuple_input(self, gpu):
        in_size = 5
        out_size = 3

        def concat_input(*args):
            return F.concat(args, axis=1)

        rseq = StatelessRecurrentSequential(
            concat_input,
            L.NStepRNNTanh(1, in_size, out_size, 0),
        )

        if gpu >= 0:
            chainer.cuda.get_device_from_id(gpu).use()
            rseq.to_gpu()
        xp = rseq.xp

        # Input is list of tuples. Each tuple has two variables.
        seqs_x = [
            (xp.random.uniform(-1, 1, size=(3, 2)).astype(np.float32),
             xp.random.uniform(-1, 1, size=(3, 3)).astype(np.float32)),
            (xp.random.uniform(-1, 1, size=(1, 2)).astype(np.float32),
             xp.random.uniform(-1, 1, size=(1, 3)).astype(np.float32)),
        ]

        # Concatenated output should be a variable.
        concat_out, concat_state = rseq.n_step_forward(seqs_x,
                                                       None,
                                                       output_mode='concat')
        self.assertEqual(concat_out.shape, (4, out_size))

        # Split output should be a list of variables.
        split_out, split_state = rseq.n_step_forward(seqs_x,
                                                     None,
                                                     output_mode='split')
        self.assertIsInstance(split_out, list)
        self.assertEqual(len(split_out), len(seqs_x))
        for seq_x, seq_out in zip(seqs_x, split_out):
            self.assertEqual(seq_out.shape, (len(seq_x), out_size))

        # Check if output_mode='concat' and output_mode='split' are consistent
        xp.testing.assert_allclose(
            F.concat(split_out, axis=0).array,
            concat_out.array,
        )
示例#8
0
def construct_RNN(unit_type, bidirection, n_layers, n_input, n_units, dropout):
    rnn = None
    if unit_type == 'lstm':
        if bidirection:
            rnn = L.NStepBiLSTM(n_layers, n_input, n_units, dropout)
        else:
            rnn = L.NStepLSTM(n_layers, n_input, n_units, dropout)
    elif unit_type == 'gru':
        if bidirection:
            rnn = L.NStepBiGRU(n_layers, n_input, n_units, dropout)
        else:
            rnn = L.NStepGRU(n_layers, n_input, n_units, dropout)
    else:
        if bidirection:
            rnn = L.NStepBiRNNTanh(n_layers, n_input, n_units, dropout)
        else:
            rnn = L.NStepRNNTanh(n_layers, n_input, n_units, dropout)

    print('# RNN unit: {}, dropout={}'.format(rnn, rnn.__dict__['dropout']),
          file=sys.stderr)
    for i, c in enumerate(rnn._children):
        print('#   {}-th param'.format(i), file=sys.stderr)
        print('#      0 - W={}, b={}'.format(c.w0.shape, c.b0.shape),
              file=sys.stderr)
        print('#      1 - W={}, b={}'.format(c.w1.shape, c.b1.shape),
              file=sys.stderr)

        if unit_type == 'gru' or unit_type == 'lstm':
            print('#      2 - W={}, b={}'.format(c.w2.shape, c.b2.shape),
                  file=sys.stderr)
            print('#      3 - W={}, b={}'.format(c.w3.shape, c.b3.shape),
                  file=sys.stderr)
            print('#      4 - W={}, b={}'.format(c.w4.shape, c.b4.shape),
                  file=sys.stderr)
            print('#      5 - W={}, b={}'.format(c.w5.shape, c.b5.shape),
                  file=sys.stderr)

        if unit_type == 'lstm':
            print('#      6 - W={}, b={}'.format(c.w6.shape, c.b6.shape),
                  file=sys.stderr)
            print('#      7 - W={}, b={}'.format(c.w7.shape, c.b7.shape),
                  file=sys.stderr)

    return rnn
示例#9
0
    def __init__(self,
                 input_size,
                 rnn_type,
                 bidirectional,
                 num_units,
                 num_proj,
                 num_layers,
                 dropout_input,
                 dropout_hidden,
                 subsample_list=[],
                 subsample_type='drop',
                 use_cuda=False,
                 merge_bidirectional=False,
                 num_stack=1,
                 splice=1,
                 input_channel=1,
                 conv_channels=[],
                 conv_kernel_sizes=[],
                 conv_strides=[],
                 poolings=[],
                 activation='relu',
                 batch_norm=False,
                 residual=False,
                 dense_residual=False,
                 num_layers_sub=0):

        super(RNNEncoder, self).__init__()

        if len(subsample_list) > 0 and len(subsample_list) != num_layers:
            raise ValueError(
                'subsample_list must be the same size as num_layers.')
        if subsample_type not in ['drop', 'concat']:
            raise TypeError('subsample_type must be "drop" or "concat".')
        if num_layers_sub < 0 or (num_layers_sub > 1
                                  and num_layers < num_layers_sub):
            raise ValueError('Set num_layers_sub between 1 to num_layers.')

        self.rnn_type = rnn_type
        self.bidirectional = bidirectional
        self.num_directions = 2 if bidirectional else 1
        self.num_units = num_units
        self.num_proj = num_proj if num_proj is not None else 0
        self.num_layers = num_layers
        self.dropout_input = dropout_input
        self.dropout_hidden = dropout_hidden
        self.merge_bidirectional = merge_bidirectional
        self.use_cuda = use_cuda

        # TODO: self.clip_activation = clip_activation

        # Setting for hierarchical encoder
        self.num_layers_sub = num_layers_sub

        # Setting for subsampling
        if len(subsample_list) == 0:
            self.subsample_list = [False] * num_layers
        else:
            self.subsample_list = subsample_list
        self.subsample_type = subsample_type
        # This implementation is bases on
        # https://arxiv.org/abs/1508.01211
        #     Chan, William, et al. "Listen, attend and spell."
        #         arXiv preprint arXiv:1508.01211 (2015).

        # Setting for residual connection
        assert not (residual and dense_residual)
        self.residual = residual
        self.dense_residual = dense_residual
        subsample_last_layer = 0
        for l_reverse, is_subsample in enumerate(subsample_list[::-1]):
            if is_subsample:
                subsample_last_layer = num_layers - l_reverse
                break
        self.residual_start_layer = subsample_last_layer + 1
        # NOTE: residual connection starts from the last subsampling layer

        with self.init_scope():
            # Setting for CNNs before RNNs# Setting for CNNs before RNNs
            if len(conv_channels) > 0 and len(conv_channels) == len(
                    conv_kernel_sizes) and len(conv_kernel_sizes) == len(
                        conv_strides):
                assert num_stack == 1 and splice == 1
                self.conv = CNNEncoder(input_size,
                                       input_channel=input_channel,
                                       conv_channels=conv_channels,
                                       conv_kernel_sizes=conv_kernel_sizes,
                                       conv_strides=conv_strides,
                                       poolings=poolings,
                                       dropout_input=0,
                                       dropout_hidden=dropout_hidden,
                                       activation=activation,
                                       use_cuda=use_cuda,
                                       batch_norm=batch_norm)
                input_size = self.conv.output_size
            else:
                input_size = input_size * splice * num_stack
                self.conv = None

            self.rnns = []
            self.projections = []
            for l in range(num_layers):
                if l == 0:
                    encoder_input_size = input_size
                elif self.num_proj > 0:
                    encoder_input_size = num_proj
                    if subsample_type == 'concat' and l > 0 and self.subsample_list[
                            l - 1]:
                        encoder_input_size *= 2
                else:
                    encoder_input_size = num_units * self.num_directions
                    if subsample_type == 'concat' and l > 0 and self.subsample_list[
                            l - 1]:
                        encoder_input_size *= 2

                if rnn_type == 'lstm':
                    if bidirectional:
                        rnn_i = L.NStepBiLSTM(n_layers=1,
                                              in_size=encoder_input_size,
                                              out_size=num_units,
                                              dropout=0)
                    else:
                        rnn_i = L.NStepLSTM(n_layers=1,
                                            in_size=encoder_input_size,
                                            out_size=num_units,
                                            dropout=0)

                elif rnn_type == 'gru':
                    if bidirectional:
                        rnn_i = L.NStepBiGRU(n_layers=1,
                                             in_size=encoder_input_size,
                                             out_size=num_units,
                                             dropout=0)
                    else:
                        rnn_i = L.NStepGRU(n_layers=1,
                                           in_size=encoder_input_size,
                                           out_size=num_units,
                                           dropout=0)

                elif rnn_type == 'rnn':
                    if bidirectional:
                        # rnn_i = L.NStepBiRNNReLU(
                        rnn_i = L.NStepBiRNNTanh(n_layers=1,
                                                 in_size=encoder_input_size,
                                                 out_size=num_units,
                                                 dropout=0)
                    else:
                        # rnn_i = L.NStepRNNReLU(
                        rnn_i = L.NStepRNNTanh(n_layers=1,
                                               in_size=encoder_input_size,
                                               out_size=num_units,
                                               dropout=0)
                else:
                    raise ValueError(
                        'rnn_type must be "lstm" or "gru" or "rnn".')

                if use_cuda:
                    rnn_i.to_gpu()
                setattr(self, rnn_type + '_l' + str(l), rnn_i)

                if l != self.num_layers - 1 and self.num_proj > 0:
                    proj_i = LinearND(num_units * self.num_directions,
                                      num_proj,
                                      dropout=dropout_hidden,
                                      use_cuda=use_cuda)

                    if use_cuda:
                        proj_i.to_gpu()
                    setattr(self, 'proj_l' + str(l), proj_i)
    def _test_n_step_forward(self, gpu):
        in_size = 2
        out_size = 6

        rseq = StatelessRecurrentSequential(
            L.Linear(in_size, 3),
            F.elu,
            L.NStepLSTM(1, 3, 4, 0),
            L.Linear(4, 5),
            L.NStepRNNTanh(1, 5, out_size, 0),
            F.tanh,
        )

        if gpu >= 0:
            chainer.cuda.get_device_from_id(gpu).use()
            rseq.to_gpu()
        xp = rseq.xp

        linear1 = rseq._layers[0]
        lstm = rseq._layers[2]
        linear2 = rseq._layers[3]
        rnn = rseq._layers[4]

        seqs_x = [
            xp.random.uniform(-1, 1, size=(4, in_size)).astype(np.float32),
            xp.random.uniform(-1, 1, size=(1, in_size)).astype(np.float32),
            xp.random.uniform(-1, 1, size=(3, in_size)).astype(np.float32),
        ]

        concat_out, concat_state = rseq.n_step_forward(
            seqs_x, None, output_mode='concat')
        self.assertEqual(concat_out.shape, (8, out_size))

        split_out, split_state = rseq.n_step_forward(
            seqs_x, None, output_mode='split')
        self.assertIsInstance(split_out, list)
        self.assertEqual(len(split_out), len(seqs_x))
        for seq_x, seq_out in zip(seqs_x, split_out):
            self.assertEqual(seq_out.shape, (len(seq_x), out_size))

        # Check if output_mode='concat' and output_mode='split' are consistent
        xp.testing.assert_allclose(
            F.concat(split_out, axis=0).array,
            concat_out.array,
        )

        (concat_lstm_h, concat_lstm_c), concat_rnn_h = concat_state
        (split_lstm_h, split_lstm_c), split_rnn_h = split_state
        xp.testing.assert_allclose(concat_lstm_h.array, split_lstm_h.array)
        xp.testing.assert_allclose(concat_lstm_c.array, split_lstm_c.array)
        xp.testing.assert_allclose(concat_rnn_h.array, split_rnn_h.array)

        # Check if the output matches that of step-by-step execution
        def manual_n_step_forward(seqs_x):
            sorted_seqs_x = sorted(seqs_x, key=len, reverse=True)
            transposed_x = F.transpose_sequence(sorted_seqs_x)
            lstm_h = None
            lstm_c = None
            rnn_h = None
            ys = []
            for batch in transposed_x:
                if lstm_h is not None:
                    lstm_h = lstm_h[:len(batch)]
                    lstm_c = lstm_c[:len(batch)]
                    rnn_h = rnn_h[:len(batch)]
                h = linear1(batch)
                h = F.elu(h)
                h, (lstm_h, lstm_c) = _step_lstm(lstm, h, (lstm_h, lstm_c))
                h = linear2(h)
                h, rnn_h = _step_rnn_tanh(rnn, h, rnn_h)
                y = F.tanh(h)
                ys.append(y)
            sorted_seqs_y = F.transpose_sequence(ys)
            # Undo sort
            seqs_y = [sorted_seqs_y[0], sorted_seqs_y[2], sorted_seqs_y[1]]
            return seqs_y

        manual_split_out = manual_n_step_forward(seqs_x)
        for man_seq_out, seq_out in zip(manual_split_out, split_out):
            xp.testing.assert_allclose(
                man_seq_out.array, seq_out.array, rtol=1e-5)

        # Finally, check the gradient (wrt linear1.W)
        concat_grad, = chainer.grad([F.sum(concat_out)], [linear1.W])
        split_grad, = chainer.grad(
            [F.sum(F.concat(split_out, axis=0))], [linear1.W])
        manual_split_grad, = chainer.grad(
            [F.sum(F.concat(manual_split_out, axis=0))], [linear1.W])
        xp.testing.assert_allclose(
            concat_grad.array, split_grad.array, rtol=1e-5)
        xp.testing.assert_allclose(
            concat_grad.array, manual_split_grad.array, rtol=1e-5)