Bis zu Letztes Mal habe ich das Verhalten von PyTorchs DataLoader und DataSet verstanden. Dieses Mal wenden wir es an und erstellen Ihren eigenen Datensatz. Vielleicht habe ich auf die Quelle von [hier] verwiesen (https://github.com/adambielski/siamese-triplet).
Ich habe das Gefühl, dass ich mit dem Inhalt bis zum letzten Mal etwas Aufwändiges machen kann. Machen wir es möglich, Daten gut zurückzugeben, indem wir einen Datensatz erstellen.
Im jüngsten Trend des metrischen Lernens ist es erforderlich, ein Paar Bilder zu erstellen. Es wurden verschiedene Methoden vorgeschlagen, aber ich bin der Meinung, dass es vorerst nicht viel guten Code gibt, den man ausprobieren kann. Lassen Sie uns diesmal die Handhabung von Paaren vereinfachen, indem Sie als Beispiel selbst einen Datensatz erstellen.
Erstellen Sie zunächst eine Klasse. Erben Sie das DataSet von Torch. Darüber hinaus sollte der Konstruktor den MNIST-Datensatz erhalten. Das positive und das negative Paar von Metric Learning haben die folgende Beziehung.
Name | Inhalt |
---|---|
Positive Pair | Gleiches Etikett |
Negative Pair | Nicht identisches Etikett |
Da ich die Trainingsdaten mischen möchte, muss ich nur die Positionsbeziehung der Beschriftungen im Konstruktor erstellen, und für die Testdaten muss ich nur zuerst das Paarmuster erstellen, damit ich eine Liste von Indizes erstellen kann.
from torch.utils.data import Dataset
class PairMnistDataset(Dataset):
def __init__(self, mnist_dataset, train=True):
self.train = train
self.dataset = mnist_dataset
self.transform = mnist_dataset.transform
if self.train:
self.train_data = self.dataset.train_data
self.train_labels = self.dataset.train_labels
self.train_label_set = set(self.train_labels.numpy())
self.label_to_indices = {label: np.where(self.train_labels.numpy() == label)[0]
for label in self.train_label_set}
else:
self.test_data = self.dataset.test_data
self.test_labels = self.dataset.test_labels
self.test_label_set = set(self.test_labels.numpy())
self.label_to_indices = {label: np.where(self.test_labels.numpy() == label)[0]
for label in self.test_label_set}
#Ich werde nicht mischen, also entscheide zuerst das Paar
positive_pairs = [[i,
np.random.choice(self.label_to_indices[self.test_labels[i].item()]),
1]
for i in range(0, len(self.test_data), 2)]
negative_pairs = [[i,
np.random.choice(self.label_to_indices[np.random.choice(list(self.test_label_set - set([self.test_labels[i].item()])))]),
0]
for i in range(1, len(self.test_data), 2)]
self.test_pairs = positive_pairs + negative_pairs
__getitem__
Lassen Sie uns das getitem machen, das wir im vorherigen Artikel studiert haben. Sie müssen lediglich beschreiben, welche Daten zurückgegeben werden sollen, wenn der Index übergeben wird.
def __getitem__(self, index):
if self.train:
target = np.random.randint(0, 2)
# img1,label1 wird zuerst entschieden
img1, label1 = self.train_data[index], self.train_labels[index].item()
if target == 1:
# positive pair
#Verarbeitung zur Auswahl von Indizes mit derselben Bezeichnung
siamese_index = index
while siamese_index == index:
siamese_index = np.random.choice(self.label_to_indices[label1])
else:
# negative pair
#Verarbeitung zur Auswahl von Indizes mit unterschiedlichen Beschriftungen
siamese_label = np.random.choice(list(self.train_label_set - set([label1])))
siamese_index = np.random.choice(self.label_to_indices[siamese_label])
img2 = self.train_data[siamese_index]
else:
img1 = self.test_data[self.test_pairs[index][0]]
img2 = self.test_data[self.test_pairs[index][1]]
target = self.test_pairs[index][2]
img1 = Image.fromarray(img1.numpy(), mode='L')
img2 = Image.fromarray(img2.numpy(), mode='L')
if self.transform:
img1 = self.transform(img1)
img2 = self.transform(img2)
return (img1, img2), target #Ob die Bezeichnungen des metrischen Lernens gleich sind
def __len__(self):
return len(self.dataset)
Alles was Sie tun müssen, ist anzurufen, was Sie bisher gemacht haben. Der Code ist bisher lang und kompliziert, aber ich denke, wenn Sie ihn gut verwenden, können Sie die Daten reibungslos laden.
def main():
#Das übliche zuerst
train_dataset = datasets.MNIST(
'~/dataset/MNIST', #Gegebenenfalls ändern
train=True,
download=True,
transform=transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))
]))
test_dataset = datasets.MNIST(
'~/dataset/MNIST', #Gegebenenfalls ändern
train=False,
download=True,
transform=transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))
]))
#Selbst erstellter Datensatz und Datenlader
pair_train_dataset = PairMnistDataset(train_dataset, train=True)
pair_train_loader = torch.utils.data.DataLoader(
pair_train_dataset,
batch_size=16
)
pair_test_dataset = PairMnistDataset(test_dataset, train=False)
pair_test_loader = torch.utils.data.DataLoader(
pair_test_dataset,
batch_size=16
)
#Zum Beispiel können Sie es so nennen
for (data1, data2), label in pair_train_loader:
print(data1.shape)
print(data2.shape)
print(label)
Klicken Sie hier für die Ergebnisanzeige. Es wird ordnungsgemäß als Paar zurückgegeben, und das Flag, ob sie dieselbe Bezeichnung haben oder nicht, wird ebenfalls zurückgegeben. Wenn Sie diese Daten verwenden, können Sie problemlos metrisches Lernen durchführen.
torch.Size([16, 1, 28, 28])
torch.Size([16, 1, 28, 28])
tensor([1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1])
Das letzte Mal war es ziemlich lang, aber es war ein Artikel über das Verständnis von DataLoader und DataSet von PyTorch. Wie wäre es, wenn Sie die Daten für das kürzlich beliebte Metric Learning so lesen?
Recommended Posts