The model itself seems to be working and is able to overfit a small data sample perfectly:
model = Model()
optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)
data = torch.randn(10, 3, 140, 140)
target = torch.randint(0, 10, (10,))
criterion = nn.CrossEntropyLoss()

for epoch in range(100):
    optimizer.zero_grad()
    out = model(data)
    loss = criterion(out, target)
    loss.backward()
    optimizer.step()
    print('epoch {}, loss {}'.format(epoch, loss.item()))

model.eval()
pred = model(data)
pred = torch.argmax(pred, dim=1)
acc = (pred == target).float().mean()
print(acc)
> tensor(1.)