Open murphyk opened 1 year ago
Avalanche benchmarks already support this use case. We are missing some examples of benchmarks with blurry tasks and a high-level generator. We will definitely add them in the future since this setting is becoming quite popular.
Can you point me to any examples of your existing functionality? We are hoping to submit a paper to COLLAS (https://lifelong-ml.cc/Conferences/2023/call) on March 6th, so would like to try this ASAP. Thx.
Hi @murphyk ,
AFAIK we currently don't have an example that creates streams with smooth transitions, but one way to do this is to use OnlineCLScenario
from avalanche.benchmarks.scenarios.online_scenario
to convert the list of experiences in a continual learning stream to a sequence of sub-experiences.
For example, if we have a continual learning stream with five experiences $S = [e_1, e_2, ..., e_5]$, we can convert it to a stream of smaller experiences i.e. an online stream as below:
ocl_benchmark = OnlineCLScenario(
original_streams=benchmark.streams.values(),
experiences=benchmark.train_stream,
experience_size=10,
access_task_boundaries=True
)
by setting the size of each "sub-experience".
By default, the transition between the original experiences is "abrupt" since OnlineCLScenario
creates generators for each experience in the original stream in a sequential order and goes through them one by one and outputs sub-experiences, so the final stream will look like this:
$S = [e{1}^{(1)}, e{1}^{(2)}, ..., e{1}^{(L)}, e{2}^{(1)}, ..., e{2}^{(L)}, e{e}^{(1)}, ..., e_{5}^{(L)}]$
For smooth transitions, the exps_iter()
function in avalanche.benchmarks.scenarios.online_scenario
(here) needs to be changed. This function defines how and in which order the sub-experience generators should be iterated through :
def exps_iter():
for exp in original_stream:
for sub_exp in split_foo(exp, experience_size):
yield sub_exp
the split_foo
function is the default generator that creates sub-experiences for a given experience. As a naive example, I modified the source code and tried a completely random sampler that first samples a random iterator from one of the experiences in the original stream and then returns a sub-experience from it (next(exp_iter)
).
def exps_iter():
exp_iterators = [split_foo(exp, experience_size) for exp in original_stream]
for i in range(100000):
exp_iter = random.choice(exp_iterators)
try:
yield next(exp_iter)
except StopIteration:
continue
It should be possible to replace the random sampler with another sampler for an arbitrary smooth transition to create streams like: $S = [e{1}^{(1)}, e{1}^{(2)}, ..., e{1}^{(L-8)}, e{1}^{(L-9)}, e{2}^{(1)}, e{2}^{(2)}, e{1}^{(L-8)}, e{2}^{(3)}..., ]$
@AntonioCarta, perhaps we can make exp_iter()
an optional input argument to OnlineCLScneario
?
@AntonioCarta, perhaps we can make exp_iter() an optional input argument to OnlineCLScneario?
I think it's better to add a separate stream generator for it since they are different scenarios.
Just a minor comment: your last exps_iter
function is choosing a single empirical distribution for each minibatch, while I think in smooth scenarios you draw samples independently so you can have different tasks in the same minibatch (but it's easy to adapt your code).
@murphyk we are also working on a CoLLAs submission so it's unlikely that we can push this before the CoLLAs deadline but I think @HamedHemati comment should be a good starting point.
ok, thanks.
It would be very helpful to support smoothly changing distributions, as illustrated below (from FOO-VB paper, which uses permuted mnist).