| 78 | return output |
| 79 | |
| 80 | class APP_MATCHER(Dataset): |
| 81 | def __init__(self, root, train, download=False): |
| 82 | super(APP_MATCHER, self).__init__() |
| 83 | |
| 84 | # get MNIST dataset |
| 85 | self.dataset = datasets.MNIST(root, train=train, download=download) |
| 86 | |
| 87 | # as `self.dataset.data`'s shape is (Nx28x28), where N is the number of |
| 88 | # examples in MNIST dataset, a single example has the dimensions of |
| 89 | # (28x28) for (WxH), where W and H are the width and the height of the image. |
| 90 | # However, every example should have (CxWxH) dimensions where C is the number |
| 91 | # of channels to be passed to the network. As MNIST contains gray-scale images, |
| 92 | # we add an additional dimension to corresponds to the number of channels. |
| 93 | self.data = self.dataset.data.unsqueeze(1).clone() |
| 94 | |
| 95 | self.group_examples() |
| 96 | |
| 97 | def group_examples(self): |
| 98 | """ |
| 99 | To ease the accessibility of data based on the class, we will use `group_examples` to group |
| 100 | examples based on class. |
| 101 | |
| 102 | Every key in `grouped_examples` corresponds to a class in MNIST dataset. For every key in |
| 103 | `grouped_examples`, every value will conform to all of the indices for the MNIST |
| 104 | dataset examples that correspond to that key. |
| 105 | """ |
| 106 | |
| 107 | # get the targets from MNIST dataset |
| 108 | np_arr = np.array(self.dataset.targets.clone(), dtype=None, copy=None) |
| 109 | |
| 110 | # group examples based on class |
| 111 | self.grouped_examples = {} |
| 112 | for i in range(0,10): |
| 113 | self.grouped_examples[i] = np.where((np_arr==i))[0] |
| 114 | |
| 115 | def __len__(self): |
| 116 | return self.data.shape[0] |
| 117 | |
| 118 | def __getitem__(self, index): |
| 119 | """ |
| 120 | For every example, we will select two images. There are two cases, |
| 121 | positive and negative examples. For positive examples, we will have two |
| 122 | images from the same class. For negative examples, we will have two images |
| 123 | from different classes. |
| 124 | |
| 125 | Given an index, if the index is even, we will pick the second image from the same class, |
| 126 | but it won't be the same image we chose for the first class. This is used to ensure the positive |
| 127 | example isn't trivial as the network would easily distinguish the similarity between same images. However, |
| 128 | if the network were given two different images from the same class, the network will need to learn |
| 129 | the similarity between two different images representing the same class. If the index is odd, we will |
| 130 | pick the second image from a different class than the first image. |
| 131 | """ |
| 132 | |
| 133 | # pick some random class for the first image |
| 134 | selected_class = random.randint(0, 9) |
| 135 | |
| 136 | # pick a random index for the first image in the grouped indices based of the label |
| 137 | # of the class |