Hi,
Using this as loss criterion:
class TripletLoss(torch.nn.Module):
def __init__(self, margin):
super(TripletLoss, self).__init__()
self.margin = margin
def forward(self, anchor, positive, negative):
distance_positive = (anchor - positive).pow(2).sum(1)
distance_negative = (anchor - negative).pow(2).sum(1)
losses = torch.nn.functional.relu(distance_positive - distance_negative + self.margin)
return losses.mean()
And this as a network:
class Net(torch.nn.Module):
def __init__(self):
super().__init__()
self.conv1 = torch.nn.Conv2d(1, 16, 5)
self.pool1 = torch.nn.MaxPool2d(2)
self.conv2 = torch.nn.Conv2d(16, 64, 3)
self.pool2 = torch.nn.MaxPool2d(2)
self.conv3 = torch.nn.Conv2d(64, 128, 3)
self.pool3 = torch.nn.MaxPool2d(2)
self.linear1 = torch.nn.Linear(1152, 512)
self.linear2 = torch.nn.Linear(512, 64)
def forward(self, x):
x = torch.nn.functional.relu(self.conv1(x))
x = self.pool1(x)
x = torch.nn.functional.relu(self.conv2(x))
x = self.pool2(x)
x = torch.nn.functional.relu(self.conv3(x))
x = self.pool3(x)
x = x.view(x.shape[0], -1)
x = torch.nn.functional.relu(self.linear1(x))
x = torch.nn.functional.relu(self.linear2(x))
return x
I train the network with random data. I also print the value of the loss returned by the criterion.
if __name__ == '__main__':
model = Net()
criterion = TripletLoss(0.5)
optimizer = torch.optim.Adam(model.parameters(), lr=0.01)
model.train()
for x in range(10000):
optimizer.zero_grad()
x = torch.tensor(np.random.normal(size=[1, 1, 40, 40])).float()
y = torch.tensor(np.random.normal(size=[1, 1, 40, 40])).float()
z = torch.tensor(np.random.normal(size=[1, 1, 40, 40])).float()
anchor = model(x)
positive = model(y)
negative = model(z)
loss = criterion(anchor, positive, negative)
print(loss)
loss.backward()
optimizer.step()
As the input data is random I expect for the network to learn nothing(i.e., get random error values).
The problem that I have is that the loss quickly converges to 0.5. The weights of the different layers of the network also converge to stable values.
...
tensor(0.5000, grad_fn=<MeanBackward1>)
tensor(0.5000, grad_fn=<MeanBackward1>)
tensor(0.5000, grad_fn=<MeanBackward1>)
...
The same happens when using real data(non random data).
Why is this happening?