[Insight-users] Parameter scales for registration (second try)
brian avants
stnava at gmail.com
Tue May 7 17:06:49 EDT 2013
we did not implement a RegularStep...Optimizerv4
that would be fairly trivial to implement in v4 - perhaps you are
interested in contributing ?
brian
On Tue, May 7, 2013 at 3:42 PM, Joël Schaerer <joel.schaerer at gmail.com>wrote:
> Hi Brian,
>
> I did read this code, but if I understand correctly,
> ModifyGradientByScales does the equivalent of the first scaling that was
> already done in the old itkRegularStepGradientOptimizer.
>
> However the whole point of my post is that it would make sense (I think!)
> to apply the scales *again* after adjusting the gradient for step size (or
> "learning rate"), which doesn't seem to be done in this code either.
>
> Note that in itkGradientDescentOptimizerv4, the gradient isn't normalized,
> so I don't think my change is needed. But if you implemented a
> RegularStepGradientOptimizerv4, I think re-applying the scales after
> scaling the gradient would be a good thing.
>
> joel
>
>
>
> On 05/07/2013 06:07 PM, brian avants wrote:
>
> yes - there is something you are missing. read the code below:
>
> /* Begin threaded gradient modification.
> * Scale by gradient scales, then estimate the learning
> * rate if options are set to (using the scaled gradient),
> * then modify by learning rate. The m_Gradient variable
> * is modified in-place. */
> this->ModifyGradientByScales();
> this->EstimateLearningRate();
> this->ModifyGradientByLearningRate();
>
> the call to this->ModifyGradientByScales(); changes the gradient
> according the scales, as the name suggests. the v4 optimizers all behave
> in this general manner although this is taken from the gradient descent
> class.
>
> so - the transform expects that the update was already modified by the
> scales so that the only thing the transform needs to do ( if anything at
> all) is multiply by a scalar
>
> also, you are looking at the base class which is only used if the
> derived class did not implement UpdateTransformParameters. for instance,
> the GaussianDisplacementField transform will also smooth the parameters
> when this function is called.
>
> is this clear enough?
>
>
>
> brian
>
>
>
>
> On Tue, May 7, 2013 at 11:59 AM, Joël Schaerer <joel.schaerer at gmail.com>wrote:
>
>> I spent a while looking at the v4 optimization framework. I can follow
>> your reasoning until UpdateTransformParameters is called on the transform.
>> However, at this state, the old scaling is still done:
>>
>> itkTransform.hxx:
>> if( factor == 1.0 )
>> {
>> for( NumberOfParametersType k = 0; k < numberOfParameters; k++ )
>> {
>> this->m_Parameters[k] += update[k];
>> }
>> }
>> else
>> {
>> for( NumberOfParametersType k = 0; k < numberOfParameters; k++ )
>> {
>> this->m_Parameters[k] += update[k] * factor;
>> }
>> }
>>
>> which makes sense, since parameters scales are an optimizer concept that
>> transforms know nothing about.
>>
>> So (if I understand correctly), the code has been shuffled around quite a
>> bit, but the behavior is still the same.
>>
>> Is there something I'm missing?
>>
>> joel
>>
>>
>>
>> On 07/05/2013 16:40, brian avants wrote:
>>
>> also - to take away a bit of the "mystery" surrounding v4 optimization,
>> let's see how the gradient descent AdvanceOneStep function works:
>>
>> void
>> GradientDescentOptimizerv4
>> ::AdvanceOneStep()
>> {
>> itkDebugMacro("AdvanceOneStep");
>>
>> /* Begin threaded gradient modification.
>> * Scale by gradient scales, then estimate the learning
>> * rate if options are set to (using the scaled gradient),
>> * then modify by learning rate. The m_Gradient variable
>> * is modified in-place. */
>> this->ModifyGradientByScales();
>> this->EstimateLearningRate();
>> this->ModifyGradientByLearningRate();
>>
>> try
>> {
>> /* Pass graident to transform and let it do its own updating */
>> this->m_Metric->UpdateTransformParameters( this->m_Gradient );
>> }
>> catch ( ExceptionObject & )
>> {
>> this->m_StopCondition = UPDATE_PARAMETERS_ERROR;
>> this->m_StopConditionDescription << "UpdateTransformParameters error";
>> this->StopOptimization();
>>
>> // Pass exception to caller
>> throw;
>> }
>>
>> this->InvokeEvent( IterationEvent() );
>> }
>>
>>
>> i hope this does not look too convoluted. then the base metric class
>> does this:
>>
>> template<unsigned int TFixedDimension, unsigned int TMovingDimension,
>> class TVirtualImage>
>> void
>> ObjectToObjectMetric<TFixedDimension, TMovingDimension, TVirtualImage>
>> ::UpdateTransformParameters( const DerivativeType & derivative,
>> ParametersValueType factor )
>> {
>> /* Rely on transform::UpdateTransformParameters to verify proper
>> * size of derivative */
>> this->m_MovingTransform->UpdateTransformParameters( derivative, factor
>> );
>> }
>>
>>
>> so the transform parameters should be updated in a way that is
>> consistent with:
>>
>> newPosition[j] = currentPosition[j] + transformedGradient[j] * factor /
>> scales[j];
>>
>> factor defaults to 1 .... anyway, as you can infer from the above
>> discussion, even the basic gradient descent optimizer can be used to take "
>> regular steps " if you want.
>>
>>
>>
>> brian
>>
>>
>>
>>
>> On Tue, May 7, 2013 at 10:23 AM, brian avants <stnava at gmail.com> wrote:
>>
>>> brad
>>>
>>> did this issue ever go up on jira? i do remember discussing with you
>>> at a meeting. our solution is in the v4 optimizers.
>>>
>>> the trivial additive parameter update doesnt work in more general
>>> cases e.g. when you need to compose parameters with parameter updates.
>>>
>>> to resolve this limitation, the v4 optimizers pass the update step to
>>> the transformations
>>>
>>> this implements the idea that " the transforms know how to update
>>> themselves "
>>>
>>> there are several other differences, as nick pointed out, that reduce
>>> the need for users to experiment with scales .
>>>
>>> for basic scenarios like that being discussed by joel, i prefer the
>>> conjugate gradient optimizer with line search.
>>>
>>> itkConjugateGradientLineSearchOptimizerv4.h
>>>
>>> when combined with the scale estimators, this leads to registration
>>> algorithms with very few parameters to tune. 1 parameter if you dont
>>> consider multi-resolution.
>>>
>>>
>>> brian
>>>
>>>
>>>
>>>
>>> On Tue, May 7, 2013 at 9:27 AM, Nick Tustison <ntustison at gmail.com>wrote:
>>>
>>>> Hi Brad,
>>>>
>>>> I certainly don't disagree with Joel's findings. It seems like a
>>>> good fix which should be put up on gerrit. There were several
>>>> components that we kept in upgrading the registration framework.
>>>> The optimizers weren't one of them.
>>>>
>>>> Also, could you elaborate a bit more on the "convoluted" aspects
>>>> of parameter advancement? There's probably a reason for it and
>>>> we could explain why.
>>>>
>>>> Nick
>>>>
>>>>
>>>>
>>
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.itk.org/pipermail/insight-users/attachments/20130507/45a9cece/attachment-0001.htm>
More information about the Insight-users
mailing list