Exemplo n.º 1
0
    def compute(self):
        """Returns the classification regions of network restricted to line.

        Returns a list with one tuple (pre_regions, corresponding_labels) for
        each line in self.lines. pre_regions is a list of tuples of endpoints
        that partition each input line.
        """
        if self.computed:
            return self.classifications

        self.partial_compute()

        self.classifications = []
        classify_network = Network([ArgMaxLayer()])
        for pre, post in self.transformed_lines:
            # First, we take each of the linear regions and split them where
            # the ArgMax changes.
            lines = list(zip(post[:-1], post[1:]))
            classify_transformed_lines = classify_network.exactlines(
                lines, compute_preimages=False, include_post=False)

            split_pre = []
            split_post = []
            for i, endpoints in enumerate(classify_transformed_lines):
                pre_delta = pre[i + 1] - pre[i]
                post_delta = post[i + 1] - post[i]
                for point_ratio in endpoints:
                    point_pre = pre[i] + (point_ratio * pre_delta)
                    point_post = post[i] + (point_ratio * post_delta)
                    if i == 0 or not point_ratio == 0.0:
                        split_pre.append(point_pre)
                        split_post.append(point_post)

            # Now, in each of the resulting regions, we compute the
            # corresponding label.
            region_labels = []
            for i in range(len(split_pre) - 1):
                mid_post = 0.5 * (split_post[i] + split_post[i + 1])
                region_labels.append(np.argmax(mid_post))

            # Finally, we merge segments with the same classification.
            merged_pre = []
            merged_labels = []
            for i, label in enumerate(region_labels):
                if not merged_labels or label != merged_labels[-1]:
                    merged_pre.append(split_pre[i])
                    merged_labels.append(label)
            merged_pre.append(split_pre[-1])
            regions = list(zip(merged_pre[:-1], merged_pre[1:]))
            self.classifications.append((regions, merged_labels))
        self.computed = True
        return self.classifications
Exemplo n.º 2
0
def test_exactlines():
    import pysyrenn.frontend.transformer_client
    transform_lines_ = pysyrenn.frontend.transformer_client.transform_lines

    input_dims = np.random.randint(1, 32)
    output_dims = np.random.randint(1, 64)

    weights = np.random.uniform(size=(input_dims, output_dims))
    biases = np.random.uniform(size=(output_dims))

    fullyconnected_layer = FullyConnectedLayer(weights, biases)
    relu_layer = ReluLayer()

    network = Network([fullyconnected_layer, relu_layer])
    lines = list(np.random.uniform(size=(100, 2, input_dims)))

    def transform_lines_mock(query_network,
                             query_lines,
                             query_include_post=False):
        assert query_network.serialize() == network.serialize()
        if len(query_lines) == 1:
            assert np.allclose(query_lines, lines[:1])
        else:
            assert np.allclose(query_lines, lines)
        output_lines = []
        for i, line in enumerate(query_lines):
            output_lines.append((np.array([0.0, 1.0 / float(i + 1),
                                           1.0]), np.array([float(2.0 * i)])))
        return output_lines

    pysyrenn.frontend.transformer_client.transform_lines = transform_lines_mock

    ratios = network.exactlines(lines,
                                compute_preimages=False,
                                include_post=False)
    assert np.allclose(
        ratios, np.array([[0.0, 1.0 / float(i + 1), 1.0] for i in range(100)]))
    ratio = network.exactline(*lines[0],
                              compute_preimages=False,
                              include_post=False)
    assert np.allclose(ratio, ratios[0])

    def interpolate(line_i, ratio):
        start, end = lines[line_i]
        return start + (ratio * (end - start))

    preimages = network.exactlines(lines,
                                   compute_preimages=True,
                                   include_post=False)
    assert np.allclose(
        preimages,
        np.array([[
            interpolate(i, 0.0),
            interpolate(i, 1.0 / float(i + 1)),
            interpolate(i, 1.0)
        ] for i in range(100)]))
    preimage = network.exactline(*lines[0],
                                 compute_preimages=True,
                                 include_post=False)
    assert np.allclose(preimage, preimages[0])

    transformed = network.exactlines(lines,
                                     compute_preimages=True,
                                     include_post=True)
    pre, post = zip(*transformed)
    assert np.allclose(
        pre,
        np.array([[
            interpolate(i, 0.0),
            interpolate(i, 1.0 / float(i + 1)),
            interpolate(i, 1.0)
        ] for i in range(100)]))
    assert np.allclose(post, np.array([[float(2.0 * i)] for i in range(100)]))
    transformed_single = network.exactline(*lines[0],
                                           compute_preimages=True,
                                           include_post=True)
    assert np.allclose(transformed_single[0], transformed[0][0])
    assert np.allclose(transformed_single[1], transformed[0][1])