omegaconf
omegaconf copied to clipboard
negative list indices in variable interpolation
This issue is based on https://github.com/facebookresearch/hydra/issues/1674.
Describe the bug Negative list indices do not work in interpolations
To Reproduce
from omegaconf import OmegaConf
cfg = OmegaConf.create(
{
"list": [8, 16, 32],
"interp": "${list[0]}",
"interp_negative": "${list[-1]}",
}
)
assert cfg.interp == 8
assert cfg.interp_negative == 32 # raises InterpolationKeyError
Expected behavior Negative list indices work in interpolations.
Additional context
- OmegaConf version: master
- Python version: 3.9.5
This is a feature request, not a bug. Interpolation into a list using negative index never worked (and this is the first time someone asks for it). It only seems appropriate because of the new support for brackets in interpolation syntax.
Using the supported syntax in 2.0 will look like this:
cfg = OmegaConf.create(
{
"list": [8, 16, 32],
"interp": "${list.0}",
"interp_negative": "${list.-1}",
}
)
We can consider this for 2.2, but I don't think it's high pri.
Using the supported syntax in 2.0 will look like this:
FYI the "${list.-1}"
syntax is not working for me.
I tried it on the 2.0 branch (gives ConfigKeyError) and on 2.1/master (gives InterpolationKeyError).
Using the supported syntax in 2.0 will look like this:
FYI the
"${list.-1}"
syntax is not working for me. I tried it on the 2.0 branch (gives ConfigKeyError) and on 2.1/master (gives InterpolationKeyError).
This was never supported functionality.
The reason I mentioned ${list.-1}
is because it's equivalent to ${list[-1]}
. The fact that we added support for bracketed access in interpolation does not mean this is a real list. We also do not support slice syntax (and we probably shouldn't support it).
Just my own 2 cents, IMHO This is a very important feature for anything related with ML and Deep Learning model configurations. Many times I would like to be able to access the last element of feature layer lists - It makes everything so much easier.
Many times I would like to be able to access the last element of feature layer lists - It makes everything so much easier.
You can still do it with something like:
OmegaConf.register_new_resolver("last", lambda lst: lst[-1])
layers:
- input
- hidden
- output
last_layer: ${last:${layers}}
Or even:
OmegaConf.register_new_resolver("getindex", lambda lst, idx: lst[idx])
layers:
- input
- hidden
- output
last_layer: ${getindex:${layers}, -1}
@Jasha10 @odelalleau Thanks for the suggestions, it works for me. I have an additional question, is somehow possible to incorporate those resolvers inside list literals? something like that:
layers: [${getindex:${layers_previous_model}, -1}, 32, 16, 4]
is somehow possible to incorporate those resolvers inside list literals? something like that:
layers: [${getindex:${layers_previous_model}, -1}, 32, 16, 4]
Yes, this should work. You might just need to quote the interpolation so that YAML doesn't complain.
Thanks! I was missing the quotes :-)