About my poor performance in anomaly detection

username: Koganei
cooked: <p>I trained an autoencoder for screw image anomaly detection, the model is like:<br>
class Autoencoder(nn.Module):<br>
def <strong>init</strong>(self):<br>
super(Autoencoder, self).<strong>init</strong>()<br>
self.encoder = nn.Sequential(<br>
nn.Linear(256, 128),<br>
nn.ReLU(True),<br>
nn.Linear(128, 64),<br>
nn.ReLU(True),<br>
nn.Linear(64, 32))</p>
<pre><code>    self.decoder = nn.Sequential(
        nn.Linear(32, 64),
        nn.ReLU(True),
        nn.Linear(64, 128),
        nn.ReLU(True),
        nn.Linear(128, 256),
        nn.Tanh())

def forward(self, x):
    y = self.encoder(x)
    y = self.decoder(y)
    return y
</code></pre>
<p>the training loss and valid loss went well<br>
and the threshold is set in this way.<br>
but it gave a really poor outcome, anyone can give me a hint?<br>
<div class="lightbox-wrapper"><a class="lightbox" href="https://discuss.pytorch.org/uploads/default/original/3X/0/2/024d99dd86a132127dac60332b0fec8e582c14c3.png" data-download-href="https://discuss.pytorch.org/uploads/default/024d99dd86a132127dac60332b0fec8e582c14c3" title="image"><img src="https://discuss.pytorch.org/uploads/default/optimized/3X/0/2/024d99dd86a132127dac60332b0fec8e582c14c3_2_275x500.png" alt="image" data-base62-sha1="kndi8gPMBmI6KASVCrkvPMMZAT" width="275" height="500" srcset="https://discuss.pytorch.org/uploads/default/optimized/3X/0/2/024d99dd86a132127dac60332b0fec8e582c14c3_2_275x500.png, https://discuss.pytorch.org/uploads/default/optimized/3X/0/2/024d99dd86a132127dac60332b0fec8e582c14c3_2_412x750.png 1.5x, https://discuss.pytorch.org/uploads/default/optimized/3X/0/2/024d99dd86a132127dac60332b0fec8e582c14c3_2_550x1000.png 2x" data-dominant-color="ECEFF1"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">image</span><span class="informations">738×1340 146 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div></p>

username: blackbirdbarber
cooked: <aside class="quote no-group" data-username="Koganei" data-post="1" data-topic="158234">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/letter_avatar_proxy/v4/letter/k/a9a28c/48.png" class="avatar"> Koganei:</div>
<blockquote>
<p>image anomaly detection</p>
</blockquote>
</aside>
<p>What is the size of your images?</p>

username: Koganei
cooked: <p><div class="lightbox-wrapper"><a class="lightbox" href="https://discuss.pytorch.org/uploads/default/original/3X/7/e/7ecbd80f97ae2c0ce2d0aadad94a3117610f3cd4.png" data-download-href="https://discuss.pytorch.org/uploads/default/7ecbd80f97ae2c0ce2d0aadad94a3117610f3cd4" title="image"><img src="https://discuss.pytorch.org/uploads/default/optimized/3X/7/e/7ecbd80f97ae2c0ce2d0aadad94a3117610f3cd4_2_689x210.png" alt="image" data-base62-sha1="i5GTup6VhF3SHGSC5qxF3XX55m4" width="689" height="210" srcset="https://discuss.pytorch.org/uploads/default/optimized/3X/7/e/7ecbd80f97ae2c0ce2d0aadad94a3117610f3cd4_2_689x210.png, https://discuss.pytorch.org/uploads/default/optimized/3X/7/e/7ecbd80f97ae2c0ce2d0aadad94a3117610f3cd4_2_1033x315.png 1.5x, https://discuss.pytorch.org/uploads/default/original/3X/7/e/7ecbd80f97ae2c0ce2d0aadad94a3117610f3cd4.png 2x" data-dominant-color="E1E1E1"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">image</span><span class="informations">1206×368 68.8 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div><br>
that’s the transform and I reshape it to 1 dimension when I sent it to train</p>

username: blackbirdbarber
cooked: <p>And what is your original image size before resize?</p>

username: Koganei
cooked: <p><img src="https://discuss.pytorch.org/uploads/default/original/3X/9/5/95f92e568fa63142bac08bd4a96db259f6080b67.png" alt="image" data-base62-sha1="loJ0G4vR6IVwlOsOZINDbOQvR9t" width="458" height="140"><br>
I think is 1024<em>1024</em>3</p>

username: blackbirdbarber
cooked: <p>This is quite a resize. May🐝 you do like this:</p>
<pre><code class="lang-auto">nn.Linear(1024*1024*3, 1024),
nn.ReLU(True),
nn.Linear(1024, 64),
nn.ReLU(True),
nn.Linear(64, 32))
</code></pre>
<p>and create a symmetrical decoder. What is your specific task of anomaly detection. Noise reduction?</p>

username: Koganei
cooked: <p>I’ll let you know how it goes after I try it.</p>

username: Koganei
cooked: <p><img src="https://discuss.pytorch.org/uploads/default/original/3X/a/9/a9aee01fc117bd245517cf3473d931113f99d178.png" alt="image" data-base62-sha1="od5mpCpPIGqM1rxy9LYNLcx50jS" width="598" height="124"><br>
It turns slightly better after I modified the net size.</p>

username: sudomaze
cooked: <p>Can you share the training block of your code? You might have some bugs there. In addition, it seems that you are using default weight values provided by <code>PyTorch</code>, which isn’t ideal, <a href="https://discuss.pytorch.org/t/how-are-layer-weights-and-biases-initialized-by-default/13073">check this for more info</a>. It is better to initialize your layer weights with a better method, such as <code>Xavier</code>, to ensure the convergence and the stability of training, <a href="https://stackoverflow.com/a/49433937/5862635" rel="noopener nofollow ugc">check this Stackoverflow answer for more information.</a></p>

username: Koganei
cooked: <p>Here you go:<br>
<div class="lightbox-wrapper"><a class="lightbox" href="https://discuss.pytorch.org/uploads/default/original/3X/c/0/c0bc7062907b359270e03516a6955c3651db821e.png" data-download-href="https://discuss.pytorch.org/uploads/default/c0bc7062907b359270e03516a6955c3651db821e" title="image"><img src="https://discuss.pytorch.org/uploads/default/optimized/3X/c/0/c0bc7062907b359270e03516a6955c3651db821e_2_690x449.png" alt="image" data-base62-sha1="rv1oZforGxnKDGFbDtO5pHmzGMK" width="690" height="449" srcset="https://discuss.pytorch.org/uploads/default/optimized/3X/c/0/c0bc7062907b359270e03516a6955c3651db821e_2_690x449.png, https://discuss.pytorch.org/uploads/default/optimized/3X/c/0/c0bc7062907b359270e03516a6955c3651db821e_2_1035x673.png 1.5x, https://discuss.pytorch.org/uploads/default/optimized/3X/c/0/c0bc7062907b359270e03516a6955c3651db821e_2_1380x898.png 2x" data-dominant-color="EEEEEE"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">image</span><span class="informations">1494×974 135 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div></p>

username: sudomaze
cooked: <p>As you are dealing with images, why are you collapsing the image dim into a vector? Here is an example to show what you are doing:</p>
<pre><code class="lang-python">import copy

import numpy as np
from PIL import Image
import torch
import torchvision
import torchvision.transforms as T

x = np.random.rand(1024, 1024, 3)
img = Image.fromarray(np.uint8(x))
print(x.shape) # (1024, 1024, 3)
print(img.size) # (1024, 1024)

transform = T.Compose([
    torchvision.transforms.Resize((16,16)),
    T.ToTensor(),
])

imgs = torch.stack([copy.deepcopy(transform(img)) for i in range(10)])
print(imgs.shape) # torch.Size([10, 3, 16, 16])

imgs_ = imgs.view(imgs.size(0), -1)
print(imgs_.shape) # torch.Size([10, 768])
</code></pre>
<p>What are your loss, optimizer, and hyperparameters?</p>
<p>In addition, why do you need to normalize your image to be with the mean and the std of <code>0.5</code>? We usually normalize based on the dataset mean and std not setting up a mid-point value. This might suppress information.</p>
<p>In the future, please share code snippets rather than screenshots for code so we can test things.</p>
<p>Edit: noticed a bug in the above code</p>

username: Koganei
cooked: <p>I coded in Colab so I can’t subtly handle the datasets  due to the limited RAM.</p>
<p>The  hyperparameter: criterion = nn.MSELoss() and the SGD optimizer with lr = 1e-3, momentum = 0.9<br>
I also added scheduler back then to check the loss curve.</p>

username: sudomaze
cooked: <p>I believe your main issue is using an MLP to detect anomaly on images. It is better to have a feature extractor, ConvNet layers, then your MLP. In addition, we typically resize the images using <code>torchvision.transforms.Resize</code> to a lower size (e.g. (244,244)) to fit into GPU memory.</p>
<p>Having a feature extractor then an MLP means your MLP will have well-encoded and rich information coming from the feature extractor and the MLP will have an easier time finding pattern between the features for your desired task.</p>

username: Koganei
cooked: <p>Thanks your tips. I just inspired by the tutorial of anomaly detection for mnist. And it was build in tensorflow and its network consists of multiple linear units. So I did an impression based on it and it did not go well sadly.</p>
<p>Sometime the free GPU ran out so I have to switched the accelerator between of them.</p>

username: sudomaze
cooked: <p>MNIST is a pretty simple dataset as you have small, grayscale, and easy to classify images. However, for large, colored, and hard images, you will need a better model to learn the right features to solve the task at hand. It isn’t about using TensorFlow or PyTorch. It is about not solving the problem in the right way.</p>
<p>I am glad this helps!</p>