ToTensor scaling to [0,1] resulting in smaller gradients

CaglarDeniz: <p>Hi everyone,<br>
I’m trying to understand the reasoning behind the scaling of PIL 8-bit images from the range [0,255] to [0,1]. I am aware of whitening techniques and assume that this practice is something similar or aims to accomplish the same goal, but in practice this scaling feels counter productive.</p>
<p>I don’t have any rigorous understanding or backing for this, but when I’m training models, reconstruction losses like MSE always seem to work better with [0,255] images. Intuitively, I  assumed that calculating a numerically higher loss value results in higher gradients which result in a rapid update of parameters to better achieve better reconstruction. I would appreciate any clarification.</p>
<p>In addition to this, when I’m working with [0,255] images I tend to use the default 1e-3 as my learning rate. Based off of this, should I be using an even smaller learning rate when working with [0,1] images? Something like 1e-5 or 1e-4? Any advice would be very much</p>

Mah_Neh: <p>The underlying reason are derivatives, here is a simple idea of what happens.</p>
<p>The derivative of <code>f(x) = x^2</code> is <code>f'(x) = 2 x</code>. If we start at <code>x = 5</code> then <code>f(5)  = 25</code>.</p>
<p>We want to move to the minimum of <code>f(x)</code>. So here MSE is like <code>f(x)</code>.</p>
<p>SGD moves <code>x</code> to the minimum of <code>f(x)</code> by using this formula  <code>new_x = old_x - 2x * lr</code></p>
<p><code>lr</code> is controls the update to x; in fact, here <code>x</code> is like a weight.</p>
<p>With  <code>lr=1</code> we have <code>new_x = 5 - 10 = -5</code>,  and indeed we will keep oscillating forever.</p>
<p>With <code>lr=0.1</code> ? Then <code>new_x = 5  -  1 = 4</code> and this new <code>x</code> is closer to the minimum because <code>f(4)=16</code>.</p>
<p>We can extract some answers:</p>
<ul>
<li>If the learning rate is too high, the model wont converge (oscillates.)</li>
<li>If the learning rate is too small, it may take too long</li>
</ul>
<p>In the previous formula, the pixels are more like the <code>2</code> in <code>new_x = old_x - 2 x*lr</code></p>
<p>With large values instead of a <code>2</code> the gradient may become very large, for example:</p>
<p><code>new_x = 5 - 255 5*lr</code></p>
<p>We could use a very small learning rate here like <code>10^-8</code> but apparently this isn’t best in practice.</p>
<p>There is no good rule for the <code>lr</code> I normally start with <code>0.01</code> and automatically reduce it 10X when learning stagnates.</p>

CaglarDeniz: <p>Thank you so much for your answer! This is definitely informative. I just wanted to add, when you say you “automatically reduce the learning rate 10x when learning stagnates”, do you imply that you do this while training with code? Or do you train up to a checkpoint, analyze loss and gradient graphs and train with a lower learning rate from that checkpoint onward?</p>

Mah_Neh: <p>You are welcome.</p>
<p>No, there is an automatic LR scheduler that does this in torch, search for “pytorch learning rate scheduler”, to do it, it actually computes the Loss in the test set then changes the learning rate ( not fully sure, but I think it was like that.)</p>