How to change Torchvision model input range from 0-1 to 0-256?

ProGamerGov: <p>How do I change a Torchvision model’s input range from 0-1 to 0-256?</p>
<p>I see here:</p>
<blockquote>
<p>The models expect a list of <code>Tensor[C, H, W]</code> , in the range <code>0-1</code></p>
</blockquote>
<p><a href="https://pytorch.org/docs/stable/torchvision/models.html#object-detection-instance-segmentation-and-person-keypoint-detection" class="onebox" target="_blank" rel="noopener nofollow ugc">https://pytorch.org/docs/stable/torchvision/models.html#object-detection-instance-segmentation-and-person-keypoint-detection</a></p>
<p>I’d like to be able to put an image into one of the default VGG models from Torchvision that has a range of 0-256.</p>
<p><strong>Edit:</strong></p>
<p>I want the image to remain in the 0-255 range when it’s put through the network/model. So I want to know how I change the model to support this?</p>

blackberry: <p>The conversion is done by the <a href="https://pytorch.org/docs/stable/torchvision/transforms.html#torchvision.transforms.ToTensor" rel="nofollow noopener">toTensor</a> function of <code>torchvision.transforms</code>.<br>
So, if you remove it from your pre-processing pipeline, your image will be in 0-255 range.<br>
But, if you omit it, you need to convert to Tensor yourself.</p>

ProGamerGov: <p>I should have worded the question better, I want to be able to use this code as PIL/Pillow loads an image with with a 0-1 range:</p>
<pre><code>image = Image.open(image_name).convert('RGB')
Loader = transforms.Compose([transforms.Resize(image_size), transforms.ToTensor()])
Normalize = transforms.Compose([transforms.Normalize(mean=[123.68, 116.779, 103.939], std=[1,1,1])])
tensor = Normalize(Loader(image) * 256).unsqueeze(0)
</code></pre>
<p>I want the image to remain in the 0-255 range when it’s put through the network.</p>

blackberry: <p>You should remove <code>transforms.ToTensor()</code>, which scales the image to 0-1 (see the docs).</p>

ProGamerGov: <p>So, there’s no issue with using a model trained on images of range 0-1, on images that have a range of 0-255? Because in testing, it looks like something is off.</p>

blackberry: <p>Of course there is. The image pixel values should be in the same range during training and testing.</p>

ProGamerGov: <p>Can I change the model after training so that the it accepts different pixel values?</p>

ProGamerGov: <p>Why doesn’t this work?</p>
<pre><code class="lang-auto">import torch
from collections import OrderedDict


model = torch.load('vgg-16.pth')


new_state_dict = OrderedDict()
for (k, v) in model.items():
            t = torch.ones(v.size()).float() *255
            v = v.mul(t.cuda())
            new_state_dict[k] = v

torch.save(new_state_dict, 'vgg-16-2.pth')
</code></pre>

blackberry: <p>If the model is trained with 0-1 input, it should be tested with 0-1 input (and with the same mean/std normalization), and the same for other input ranges. It will not work otherwise.</p>

ptrblck: <p>You cannot simply change the change of the input and multiply each parameter with the same factor to get the same results.</p>
<p>If you want to use image tensors in the range <code>[0, 255]</code>, then you would need to retrain the model using this data.</p>

Deeply: <p>I would have converted the model output to <code>[0, 255]</code>  instead. However, you’ll have to make sure that your targets / labels are also in the same range. There is no advantage of using an input with [0, 255] over [0, 1], as the model weight parameters will adapt to whatever input range, it is a scaling factor as you can see. However, the common practice and the best performance can be obtained when the input is normalized to [0, 1] or [-1, 1].</p>