1
$\begingroup$

I am trying to build an intuition on what really a feature is. I created a toy example as following. In my mind a scalar feature should be enough to represent my data. Couldn't the model in this case learn a mapping from binary numbers to decimal? For example, the scalar feature for [0,0,0] = 0, [0,0,1] = 1, [0,1,0] = 2 etc. I know feature space is continuous but I could draw the same assumption for continuous feature values. I.e, [0,0,0] belongs to the [-0.5, 0.5) feature space range, [0,0,1] to [0.5, 1.5) etc.

In my example, the autoencoder predicts [0,0,0] for every input? Is my intuition just wrong about the meaning of features? If so, how would you explain it?

import torch
import torch.utils.data
from torch import nn
import tqdm


# This autoencoder has only one feature as latent space
class AE(nn.Module):
    def __init__(self):
        super().__init__()
        self.encoder = nn.Sequential(nn.Linear(3, 1, bias=False), nn.ReLU())
        self.decoder = nn.Sequential(nn.Linear(1, 3, bias=False), nn.ReLU())

    def forward(self, x):
        z = self.encoder(x)
        xhat = self.decoder(z)
        return xhat


class dummyData(torch.utils.data.Dataset):
    def __init__(self):
        self.samples = [[0, 0, 0],
                        [0, 0, 1],
                        [0, 1, 0],
                        [0, 1, 1],
                        [1, 0, 0],
                        [1, 0, 1],
                        [1, 1, 0],
                        [1, 1, 1]]

    def __getitem__(self, item):
        return torch.tensor(self.samples[item]).type(torch.float32)

    def __len__(self):
        return len(self.samples)

autoencoder = AE()
optimizer = torch.optim.Adam(autoencoder.parameters())
dummyDataset = dummyData()
dataloader = torch.utils.data.DataLoader(dummyDataset, batch_size=2, shuffle=False)
criterion = nn.MSELoss()

for epoch in tqdm.tqdm(range(10000)):
    for sample in dataloader:
        pred = autoencoder(sample)
        loss = criterion(pred, sample)
        loss.backward()
        optimizer.step()
        optimizer.zero_grad()

print("TEST")
autoencoder.eval()
print(autoencoder.encoder(torch.tensor([0., 0., 0.])))
print(autoencoder(torch.tensor([0., 0., 0.])))
print(autoencoder.encoder(torch.tensor([0., 0., 1.])))
print(autoencoder(torch.tensor([0., 0., 1.])))
print(autoencoder.encoder(torch.tensor([0., 1., 1.])))
print(autoencoder(torch.tensor([0., 1., 1.])))
print(autoencoder.encoder(torch.tensor([1., 0., 0.])))
print(autoencoder(torch.tensor([1., 0., 0.])))
´´´
$\endgroup$
2
  • 1
    $\begingroup$ Does the loss decrease during training? Your intuition about encoding is correct, you can express these 3-bit vectors $x$ as floats $y$, because $[4,2,1]^\top x=y$ (but because the training is unsupervised wrt $y$, the model doesn't know that you want these weights, particularly). The ReLU activation isn't needed here because the encoding is linear. $\endgroup$
    – Sycorax
    Commented Jan 13, 2023 at 15:51
  • $\begingroup$ It does in every run until approx epoch 1000 and then it gets stuck in the same value forever $\endgroup$
    – ElPotac
    Commented Jan 13, 2023 at 15:57

1 Answer 1

1
$\begingroup$

If we write out the problem, the neural network you're using is trying to estimate $A, B$ in

$$ x = (Ax)B $$ where $x$ has shape $3 \times 1$, $A$ has shape $1 \times 3$ and $B$ has shape $1 \times 3$. (I've omitted the activation here.)

It would be tempting to write $$ B^{-1}x=Ax $$ but this isn't possible because in the proposed network $A,B$ are vectors, not square matrices. (Indeed, if you use $3\times 3$ matrices instead, then the problem is easily solved, but one must wonder if this demonstration has accomplished anything at all.)

The encoding step $Ax$ can be expressed as a linear operation, because these 3-bit vectors $x$ have identical floats $y$, because $[4,2,1]^\top x=y$.

However, the decoding task is to go from float $y$ back to binary $x$: $z ^\top y = z$ for a fixed $z$ of shape $1 \times 3$. This isn't expressible as a vector-vector product.

In general, we're seeking solutions of the form

$$ x = [ay, by, cy] $$

but there is not a way to choose fixed $a,b,c$ from among real numbers so that $x$ is binary and $y$ is the integers 0 through 7. For $y=7$, you want $a = 1/7$, but that fails for $y=2$ because the result is $2/7$.

$\endgroup$
1
  • $\begingroup$ That makes a lot of sense. Thanks for the answer. I think at least my intuition about "what a feature is" was not way off which is what I was trying to understand with this example. $\endgroup$
    – ElPotac
    Commented Jan 13, 2023 at 17:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.