Beispiel #1
0
def test_concat_scheduler_3_schedulers():
    tensor = torch.zeros([1], requires_grad=True)
    optimizer = torch.optim.SGD([tensor], lr=0)

    scheduler_1 = LinearCyclicalScheduler(optimizer,
                                          "lr",
                                          start_value=1.0,
                                          end_value=0.5,
                                          cycle_size=20)
    scheduler_2 = LinearCyclicalScheduler(optimizer,
                                          "lr",
                                          start_value=0.5,
                                          end_value=0.45,
                                          cycle_size=10)
    scheduler_3 = LinearCyclicalScheduler(optimizer,
                                          "lr",
                                          start_value=0.5,
                                          end_value=0.0,
                                          cycle_size=20)
    durations = [10, 5]

    concat_scheduler = ConcatScheduler(
        schedulers=[scheduler_1, scheduler_2, scheduler_3],
        durations=durations,
        save_history=True)
    state_dict = concat_scheduler.state_dict()

    data = [0] * 10
    max_epochs = 2
    simulated_values = ConcatScheduler.simulate_values(
        num_events=len(data) * max_epochs,
        schedulers=[scheduler_1, scheduler_2, scheduler_3],
        durations=durations)

    def save_lr(engine):
        lrs.append(optimizer.param_groups[0]['lr'])

    trainer = Engine(lambda engine, batch: None)
    trainer.add_event_handler(Events.ITERATION_STARTED, concat_scheduler)
    trainer.add_event_handler(Events.ITERATION_COMPLETED, save_lr)

    for _ in range(2):
        lrs = []
        trainer.run(data, max_epochs=max_epochs)

        assert lrs == list(
            map(
                pytest.approx,
                [
                    # Cycle 1 of the first LinearCyclicalScheduler
                    1.0,
                    0.95,
                    0.9,
                    0.85,
                    0.8,
                    0.75,
                    0.7,
                    0.65,
                    0.6,
                    0.55,
                    # Cycle 1 of the second LinearCyclicalScheduler
                    0.5,
                    0.49,
                    0.48,
                    0.47,
                    0.46,
                    # Cycle 1 of the third LinearCyclicalScheduler
                    0.5,
                    0.45,
                    0.4,
                    0.35,
                    0.3,
                ]))

        state_lrs = trainer.state.param_history['lr']
        assert len(state_lrs) == len(lrs)
        # Unpack singleton lists
        assert [group[0] for group in state_lrs] == lrs

        assert lrs == pytest.approx([v for i, v in simulated_values])
        concat_scheduler.load_state_dict(state_dict)
Beispiel #2
0
    def _test(duration_vals_as_np_int):
        scheduler_1 = LinearCyclicalScheduler(optimizer,
                                              "lr",
                                              start_value=1.0,
                                              end_value=0.0,
                                              cycle_size=10)
        scheduler_2 = CosineAnnealingScheduler(optimizer,
                                               "lr",
                                               start_value=0.0,
                                               end_value=1.0,
                                               cycle_size=10)

        durations = [
            10,
        ]
        if duration_vals_as_np_int:
            durations = [np.int64(t) for t in durations]

        concat_scheduler = ConcatScheduler(
            schedulers=[scheduler_1, scheduler_2],
            durations=durations,
            save_history=True)
        state_dict = concat_scheduler.state_dict()

        data = [0] * 10
        max_epochs = 2
        simulated_values = ConcatScheduler.simulate_values(
            num_events=len(data) * max_epochs,
            schedulers=[scheduler_1, scheduler_2],
            durations=durations)

        def save_lr(engine):
            lrs.append(optimizer.param_groups[0]['lr'])

        trainer = Engine(lambda engine, batch: None)
        trainer.add_event_handler(Events.ITERATION_STARTED, concat_scheduler)
        trainer.add_event_handler(Events.ITERATION_COMPLETED, save_lr)

        for _ in range(2):
            lrs = []
            trainer.run(data, max_epochs=max_epochs)

            assert lrs == list(
                map(
                    pytest.approx,
                    [
                        # Cycle 1 of the LinearCyclicalScheduler
                        1.0,
                        0.8,
                        0.6,
                        0.4,
                        0.2,
                        0.0,
                        0.2,
                        0.4,
                        0.6,
                        0.8,
                        # Cycle 1 of the CosineAnnealingScheduler
                        0.0,
                        0.02447174185242318,
                        0.09549150281252627,
                        0.20610737385376332,
                        0.3454915028125263,
                        0.5,
                        0.6545084971874737,
                        0.7938926261462365,
                        0.9045084971874737,
                        0.9755282581475768,
                    ]))

            state_lrs = trainer.state.param_history['lr']
            assert len(state_lrs) == len(lrs)
            # Unpack singleton lists
            assert [group[0] for group in state_lrs] == lrs
            assert lrs == pytest.approx([v for i, v in simulated_values])
            concat_scheduler.load_state_dict(state_dict)
Beispiel #3
0
def test_concat_scheduler_two_linear():
    tensor = torch.zeros([1], requires_grad=True)
    optimizer = torch.optim.SGD([tensor], lr=0)

    scheduler_1 = LinearCyclicalScheduler(optimizer,
                                          "lr",
                                          start_value=0.0,
                                          end_value=0.1,
                                          cycle_size=2)
    scheduler_2 = LinearCyclicalScheduler(optimizer,
                                          "lr",
                                          start_value=0.2,
                                          end_value=1.0,
                                          cycle_size=2)

    durations = [
        5,
    ]
    concat_scheduler = ConcatScheduler(schedulers=[scheduler_1, scheduler_2],
                                       durations=durations,
                                       save_history=True)
    state_dict = concat_scheduler.state_dict()

    assert concat_scheduler.get_param() == 0.0

    data = [0] * 10
    max_epochs = 2
    simulated_values = ConcatScheduler.simulate_values(
        num_events=len(data) * max_epochs,
        schedulers=[scheduler_1, scheduler_2],
        durations=durations)

    def save_lr(engine):
        lrs.append(optimizer.param_groups[0]['lr'])

    trainer = Engine(lambda engine, batch: None)
    trainer.add_event_handler(Events.ITERATION_STARTED, concat_scheduler)
    trainer.add_event_handler(Events.ITERATION_COMPLETED, save_lr)

    for _ in range(2):
        lrs = []
        trainer.run(data, max_epochs=max_epochs)

        assert lrs == list(
            map(
                pytest.approx,
                [
                    # first LinearCyclicalScheduler
                    0.0,
                    0.1,
                    0.0,
                    0.1,
                    0.0,
                    # second LinearCyclicalScheduler
                    0.2,
                    1.0,
                    0.2,
                    1.0,
                    0.2,
                    1.0,
                    0.2,
                    1.0,
                    0.2,
                    1.0,
                    0.2,
                    1.0,
                    0.2,
                    1.0,
                    0.2,
                ]))

        state_lrs = trainer.state.param_history['lr']
        assert len(state_lrs) == len(lrs)
        # Unpack singleton lists
        assert [group[0] for group in state_lrs] == lrs

        assert lrs == pytest.approx([v for i, v in simulated_values])
        concat_scheduler.load_state_dict(state_dict)
Beispiel #4
0
def test_param_group_scheduler_asserts():

    t1 = torch.zeros([1], requires_grad=True)
    t2 = torch.zeros([1], requires_grad=True)
    optimizer = torch.optim.SGD([
        {
            "params": t1,
            'lr': 0.1
        },
        {
            "params": t2,
            'lr': 0.1
        },
    ])

    lr_scheduler1 = LinearCyclicalScheduler(optimizer,
                                            "lr",
                                            param_group_index=0,
                                            start_value=1.0,
                                            end_value=0.0,
                                            cycle_size=10)
    lr_scheduler2 = LinearCyclicalScheduler(optimizer,
                                            "lr",
                                            param_group_index=1,
                                            start_value=1.0,
                                            end_value=0.0,
                                            cycle_size=10)

    with pytest.raises(ValueError):
        ParamGroupScheduler(schedulers=[0, 1, 2], names=['a', 'b', 'c'])

    with pytest.raises(ValueError):
        ParamGroupScheduler(schedulers=[lr_scheduler1, '2'], names=['a', 'b'])

    with pytest.raises(ValueError):
        ParamGroupScheduler(schedulers=[lr_scheduler1, lr_scheduler2],
                            names='ab')

    with pytest.raises(ValueError):
        ParamGroupScheduler(schedulers=[lr_scheduler1, lr_scheduler2],
                            names=[
                                'a',
                            ])

    scheduler = ParamGroupScheduler(schedulers=[lr_scheduler1, lr_scheduler2],
                                    names=['a', 'b'])
    with pytest.raises(
            ValueError,
            match=
            r"Required state attribute 'schedulers' is absent in provided state_dict"
    ):
        scheduler.load_state_dict({'a': 1})

    with pytest.raises(
            ValueError,
            match=
            r"Input state_dict contains 0 state_dicts of param group schedulers"
    ):
        scheduler.load_state_dict({'schedulers': []})

    with pytest.raises(
            ValueError,
            match=r"Name of scheduler from input state dict does not "
            r"correspond to required one"):
        scheduler.load_state_dict({
            'schedulers': [('a', lr_scheduler1.state_dict()), ('bad_name', {})]
        })
Beispiel #5
0
def test_linear_scheduler():

    with pytest.raises(
            TypeError,
            match=r"Argument optimizer should be torch.optim.Optimizer"):
        LinearCyclicalScheduler({}, 'lr', 1, 0, cycle_size=0)

    tensor = torch.zeros([1], requires_grad=True)
    optimizer = torch.optim.SGD([tensor], lr=0.0)

    with pytest.raises(
            ValueError,
            match=r"Argument cycle_size should be positive and larger than 1"):
        LinearCyclicalScheduler(optimizer, 'lr', 1, 0, cycle_size=0)

    with pytest.raises(
            ValueError,
            match=r"Argument cycle_size should be positive and larger than 1"):
        LinearCyclicalScheduler(optimizer, 'lr', 1, 0, cycle_size=1)

    scheduler = LinearCyclicalScheduler(optimizer, 'lr', 1, 0, 10)
    state_dict = scheduler.state_dict()

    def save_lr(engine):
        lrs.append(optimizer.param_groups[0]['lr'])

    trainer = Engine(lambda engine, batch: None)
    trainer.add_event_handler(Events.ITERATION_STARTED, scheduler)
    trainer.add_event_handler(Events.ITERATION_COMPLETED, save_lr)

    for _ in range(2):
        lrs = []
        trainer.run([0] * 9, max_epochs=2)

        assert lrs == list(
            map(
                pytest.approx,
                [
                    # Cycle 1
                    1.0,
                    0.8,
                    0.6,
                    0.4,
                    0.2,
                    0.0,
                    0.2,
                    0.4,
                    0.6,
                    0.8,
                    # Cycle 2
                    1.0,
                    0.8,
                    0.6,
                    0.4,
                    0.2,
                    0.0,
                    0.2,
                    0.4,  # 0.6, 0.8,
                ]))
        scheduler.load_state_dict(state_dict)

    optimizer = torch.optim.SGD([tensor], lr=0)
    scheduler = LinearCyclicalScheduler(optimizer,
                                        'lr',
                                        1,
                                        0,
                                        10,
                                        cycle_mult=2)
    state_dict = scheduler.state_dict()

    trainer = Engine(lambda engine, batch: None)
    trainer.add_event_handler(Events.ITERATION_STARTED, scheduler)
    trainer.add_event_handler(Events.ITERATION_COMPLETED, save_lr)

    for _ in range(2):
        lrs = []
        trainer.run([0] * 10, max_epochs=3)

        assert lrs == list(
            map(
                pytest.approx,
                [
                    # Cycle 1
                    1.0,
                    0.8,
                    0.6,
                    0.4,
                    0.2,
                    0.0,
                    0.2,
                    0.4,
                    0.6,
                    0.8,
                    # Cycle 2
                    1.0,
                    0.9,
                    0.8,
                    0.7,
                    0.6,
                    0.5,
                    0.4,
                    0.3,
                    0.2,
                    0.1,
                    0.0,
                    0.1,
                    0.2,
                    0.3,
                    0.4,
                    0.5,
                    0.6,
                    0.7,
                    0.8,
                    0.9,
                ]))
        scheduler.load_state_dict(state_dict)

    # With float cycle_size
    optimizer = torch.optim.SGD([tensor], lr=0)
    scheduler = LinearCyclicalScheduler(optimizer,
                                        'lr',
                                        start_value=1.2,
                                        end_value=0.2,
                                        cycle_size=10.00000012,
                                        cycle_mult=1.0)
    state_dict = scheduler.state_dict()

    trainer = Engine(lambda engine, batch: None)
    trainer.add_event_handler(Events.ITERATION_STARTED, scheduler)
    trainer.add_event_handler(Events.ITERATION_COMPLETED, save_lr)

    for _ in range(2):
        lrs = []
        trainer.run([0] * 9, max_epochs=2)
        assert lrs == list(
            map(
                pytest.approx,
                [
                    # Cycle 1
                    1.2,
                    1.0,
                    0.8,
                    0.6,
                    0.4,
                    0.2,
                    0.4,
                    0.6,
                    0.8,
                    1.0,
                    # Cycle 2
                    1.2,
                    1.0,
                    0.8,
                    0.6,
                    0.4,
                    0.2,
                    0.4,
                    0.6,  # 0.8, 1.0,
                ]))
        scheduler.load_state_dict(state_dict)
Beispiel #6
0
    def _test(save_history):
        tensor = torch.ones([1], requires_grad=True)
        optimizer = torch.optim.SGD([tensor], lr=0.001)

        max_epochs = 25
        lr_max_value = 0.4
        num_iterations_per_epoch = 128
        num_iterations = max_epochs * num_iterations_per_epoch
        warmup_duration = 5 * num_iterations_per_epoch
        cooldown_duration = 5 * num_iterations_per_epoch

        scheduler_1 = LinearCyclicalScheduler(
            optimizer,
            "lr",
            start_value=lr_max_value,
            end_value=lr_max_value * 0.9,
            cycle_size=(num_iterations - warmup_duration - cooldown_duration) *
            2)

        scheduler_2 = LinearCyclicalScheduler(optimizer,
                                              "lr",
                                              start_value=lr_max_value,
                                              end_value=0.0,
                                              cycle_size=cooldown_duration * 2)

        lr_scheduler = ConcatScheduler(schedulers=[scheduler_1, scheduler_2],
                                       durations=[
                                           num_iterations - warmup_duration -
                                           cooldown_duration,
                                       ],
                                       save_history=False)
        lr_values = [None] * num_iterations
        scheduler = create_lr_scheduler_with_warmup(
            lr_scheduler,
            warmup_start_value=0.0,
            warmup_end_value=lr_max_value,
            warmup_duration=warmup_duration,
            save_history=save_history,
            output_simulated_values=lr_values)
        state_dict = scheduler.state_dict()

        trainer = Engine(lambda engine, batch: None)

        @trainer.on(Events.ITERATION_COMPLETED)
        def save_lr(engine):
            lrs.append(optimizer.param_groups[0]['lr'])

        trainer.add_event_handler(Events.ITERATION_STARTED, scheduler)

        data = [0] * num_iterations_per_epoch

        for _ in range(2):
            lrs = []
            trainer.run(data, max_epochs=max_epochs)

            assert lrs == pytest.approx([v for i, v in lr_values])

            if save_history:
                param_history = trainer.state.param_history['lr']
                assert lrs == pytest.approx([v[0] for v in param_history])

            scheduler.load_state_dict(state_dict)
def test_create_lr_scheduler_with_warmup():

    with pytest.raises(TypeError, match=r"Argument lr_scheduler should be a subclass of"):
        create_lr_scheduler_with_warmup(12, warmup_start_value=0.0, warmup_end_value=0.1, warmup_duration=10)

    t1 = torch.zeros([1], requires_grad=True)
    # A) opt lr != warmup_end_value
    optimizer = torch.optim.SGD([t1], lr=0.2)
    torch_lr_scheduler = torch.optim.lr_scheduler.ExponentialLR(optimizer=optimizer, gamma=0.98)

    with pytest.raises(ValueError, match=r"Argument warmup_duration should be at least 2 events"):
        create_lr_scheduler_with_warmup(
            torch_lr_scheduler, warmup_start_value=0.0, warmup_end_value=0.1, warmup_duration=1
        )

    with pytest.raises(ValueError, match=r"Argument warmup_duration should be at least 2 events"):
        create_lr_scheduler_with_warmup(
            torch_lr_scheduler, warmup_start_value=0.0, warmup_end_value=0.1, warmup_duration="abc"
        )

    with pytest.raises(TypeError, match=r"Argument output_simulated_values should be a list of None"):
        simulated_values = ()
        create_lr_scheduler_with_warmup(
            torch_lr_scheduler,
            warmup_start_value=0.0,
            warmup_end_value=0.1,
            warmup_duration=10,
            output_simulated_values=simulated_values,
        )

    def _test(lr_scheduler, optimizer, warmup_start_value, warmup_end_value, warmup_duration, warmup_end_next_value):
        num_iterations = 10
        max_epochs = 20

        simulated_values = [None] * (num_iterations * max_epochs)
        scheduler = create_lr_scheduler_with_warmup(
            lr_scheduler,
            warmup_start_value=warmup_start_value,
            warmup_end_value=warmup_end_value,
            warmup_duration=warmup_duration,
            output_simulated_values=simulated_values,
        )
        if warmup_end_value is None:
            warmup_end_value = optimizer.param_groups[0]["lr"]

        state_dict = scheduler.state_dict()
        trainer = Engine(lambda engine, batch: None)

        trainer.add_event_handler(Events.ITERATION_STARTED, scheduler)

        @trainer.on(Events.ITERATION_STARTED)
        def save_lr(engine):
            lrs.append(optimizer.param_groups[0]["lr"])

        data = [0] * num_iterations

        for _ in range(2):
            lrs = []
            trainer.run(data, max_epochs=max_epochs)

            assert lrs == pytest.approx([v for i, v in simulated_values])

            assert lrs[0] == pytest.approx(warmup_start_value), "lrs={}".format(lrs[: warmup_duration + num_iterations])
            assert lrs[warmup_duration - 1] == pytest.approx(warmup_end_value), "lrs={}".format(
                lrs[: warmup_duration + num_iterations]
            )
            assert lrs[warmup_duration] == pytest.approx(warmup_end_next_value), "lrs={}".format(
                lrs[: warmup_duration + num_iterations]
            )
            scheduler.load_state_dict(state_dict)

    t1 = torch.zeros([1], requires_grad=True)
    # A) opt lr != warmup_end_value
    optimizer = torch.optim.SGD([t1], lr=0.2)
    torch_lr_scheduler = torch.optim.lr_scheduler.ExponentialLR(optimizer=optimizer, gamma=0.98)
    _test(torch_lr_scheduler, optimizer, 0.01, 0.05, 10, 0.2)
    optimizer = torch.optim.SGD([t1], lr=0.2)
    torch_lr_scheduler = torch.optim.lr_scheduler.ExponentialLR(optimizer=optimizer, gamma=0.98)
    _test(torch_lr_scheduler, optimizer, 0.01, 0.05, 2, 0.2)

    # B) opt lr == warmup_end_value
    optimizer = torch.optim.SGD([t1], lr=0.2)
    torch_lr_scheduler = torch.optim.lr_scheduler.ExponentialLR(optimizer=optimizer, gamma=0.98)
    _test(torch_lr_scheduler, optimizer, 0.01, 0.2, 10, 0.2 * 0.98)
    optimizer = torch.optim.SGD([t1], lr=0.2)
    torch_lr_scheduler = torch.optim.lr_scheduler.ExponentialLR(optimizer=optimizer, gamma=0.98)
    _test(torch_lr_scheduler, optimizer, 0.01, 0.2, 2, 0.2 * 0.98)

    # C) lr_scheduler start_value != warmup_end_value
    t1 = torch.zeros([1], requires_grad=True)
    optimizer = torch.optim.SGD([t1], lr=0.0)
    lr_scheduler = LinearCyclicalScheduler(
        optimizer=optimizer, param_name="lr", start_value=0.8, end_value=0.0, cycle_size=10
    )
    _test(lr_scheduler, optimizer, 0.01, 0.05, 10, 0.8)
    optimizer = torch.optim.SGD([t1], lr=0.0)
    lr_scheduler = LinearCyclicalScheduler(
        optimizer=optimizer, param_name="lr", start_value=0.8, end_value=0.0, cycle_size=10
    )
    _test(lr_scheduler, optimizer, 0.01, 0.05, 2, 0.8)

    # D) lr_scheduler start_value == warmup_end_value
    t1 = torch.zeros([1], requires_grad=True)
    optimizer = torch.optim.SGD([t1], lr=0.0)
    lr_scheduler = LinearCyclicalScheduler(
        optimizer=optimizer, param_name="lr", start_value=0.8, end_value=0.0, cycle_size=10
    )
    _test(lr_scheduler, optimizer, 0.01, 0.8, 10, 0.8 - (0.8 / 5.0))
    optimizer = torch.optim.SGD([t1], lr=0.0)
    lr_scheduler = LinearCyclicalScheduler(
        optimizer=optimizer, param_name="lr", start_value=0.8, end_value=0.0, cycle_size=10
    )
    _test(lr_scheduler, optimizer, 0.01, 0.8, 2, 0.8 - (0.8 / 5.0))

    # E) warmup_end_value is None: fall back to case B)
    optimizer = torch.optim.SGD([t1], lr=0.2)
    torch_lr_scheduler = torch.optim.lr_scheduler.ExponentialLR(optimizer=optimizer, gamma=0.98)
    _test(torch_lr_scheduler, optimizer, 0.01, None, 10, 0.2 * 0.98)
def test_simulate_and_plot_values():

    import matplotlib

    matplotlib.use("Agg")

    def _test(scheduler_cls, **scheduler_kwargs):

        optimizer = None
        event = Events.ITERATION_STARTED
        if scheduler_cls == LRScheduler:
            scheduler_kwargs["optimizer"] = scheduler_kwargs["lr_scheduler"].optimizer
            optimizer = scheduler_kwargs["optimizer"]
            event = Events.ITERATION_COMPLETED
        elif scheduler_cls == ConcatScheduler:
            optimizer = scheduler_kwargs["optimizer"]
            del scheduler_kwargs["optimizer"]
        else:
            tensor = torch.zeros([1], requires_grad=True)
            scheduler_kwargs["optimizer"] = torch.optim.SGD([tensor], lr=0.1)
            optimizer = scheduler_kwargs["optimizer"]

        max_epochs = 2
        data = [0] * 10
        # simulated_values = scheduler_cls.simulate_values(num_events=len(data) * max_epochs, **scheduler_kwargs)

        scheduler = scheduler_cls(**scheduler_kwargs)

        lrs = []

        def save_lr(engine):
            lrs.append(optimizer.param_groups[0]["lr"])

        trainer = Engine(lambda engine, batch: None)
        trainer.add_event_handler(event, scheduler)
        trainer.add_event_handler(Events.ITERATION_STARTED, save_lr)
        trainer.run(data, max_epochs=max_epochs)

        # assert lrs == pytest.approx([v for i, v in simulated_values])

        if scheduler_cls == LRScheduler or scheduler_cls == ConcatScheduler:
            # As internal state of torch lr scheduler has been changed the following checks will fail
            return

        # reexecute to check if no internal changes
        # simulated_values = scheduler_cls.simulate_values(num_events=len(data) * max_epochs,
        #                                                  save_history=True,  # this will be removed
        #                                                  **scheduler_kwargs)
        # assert lrs == pytest.approx([v for i, v in simulated_values])

        # launch plot values
        scheduler_cls.plot_values(num_events=len(data) * max_epochs, **scheduler_kwargs)

    # LinearCyclicalScheduler
    _test(LinearCyclicalScheduler, param_name="lr", start_value=1.0, end_value=0.0, cycle_size=10)

    # CosineAnnealingScheduler
    _test(CosineAnnealingScheduler, param_name="lr", start_value=1.0, end_value=0.0, cycle_size=10)

    # LRScheduler
    tensor = torch.zeros([1], requires_grad=True)
    optimizer = torch.optim.SGD([tensor], lr=0.1)
    torch_lr_scheduler = torch.optim.lr_scheduler.ExponentialLR(optimizer=optimizer, gamma=0.5)

    _test(LRScheduler, lr_scheduler=torch_lr_scheduler)

    # ConcatScheduler = [LinearCyclicalScheduler, CosineAnnealingScheduler]
    scheduler_1 = LinearCyclicalScheduler(optimizer, "lr", start_value=1.0, end_value=0.0, cycle_size=20)
    scheduler_2 = CosineAnnealingScheduler(optimizer, "lr", start_value=0.0, end_value=1.0, cycle_size=10)
    durations = [10]
    _test(ConcatScheduler, optimizer=optimizer, schedulers=[scheduler_1, scheduler_2], durations=durations)

    # ConcatScheduler = [LinearCyclicalScheduler, LRScheduler]
    tensor = torch.ones([1], requires_grad=True)
    optimizer = torch.optim.SGD([tensor], lr=0.001)
    torch_lr_scheduler = torch.optim.lr_scheduler.ExponentialLR(optimizer=optimizer, gamma=1.5)
    scheduler_1 = LRScheduler(torch_lr_scheduler)
    scheduler_2 = LinearCyclicalScheduler(optimizer, "lr", start_value=0.1, end_value=0.0, cycle_size=10)
    durations = [10]
    _test(ConcatScheduler, optimizer=optimizer, schedulers=[scheduler_1, scheduler_2], durations=durations)

    # PiecewiseLinear
    tensor = torch.ones([1], requires_grad=True)
    optimizer = torch.optim.SGD([tensor], lr=0.001)
    _test(
        PiecewiseLinear,
        optimizer=optimizer,
        param_name="lr",
        milestones_values=[(10, 0.5), (20, 0.45), (21, 0.3), (30, 0.1), (40, 0.1)],
    )
def test_linear_scheduler():

    with pytest.raises(ValueError):
        LinearCyclicalScheduler({}, 'lr', 1, 0, cycle_size=0)

    with pytest.raises(ValueError):
        LinearCyclicalScheduler({}, 'lr', 1, 0, cycle_size=1)

    tensor = torch.zeros([1], requires_grad=True)
    optimizer = torch.optim.SGD([tensor], lr=0)

    scheduler = LinearCyclicalScheduler(optimizer, 'lr', 1, 0, 10)
    lrs = []

    def save_lr(engine):
        lrs.append(optimizer.param_groups[0]['lr'])

    trainer = Engine(lambda engine, batch: None)
    trainer.add_event_handler(Events.ITERATION_STARTED, scheduler)
    trainer.add_event_handler(Events.ITERATION_COMPLETED, save_lr)
    trainer.run([0] * 10, max_epochs=2)

    assert lrs == list(
        map(
            pytest.approx,
            [
                # Cycle 1
                1.0,
                0.8,
                0.6,
                0.4,
                0.2,
                0.0,
                0.2,
                0.4,
                0.6,
                0.8,
                # Cycle 2
                1.0,
                0.8,
                0.6,
                0.4,
                0.2,
                0.0,
                0.2,
                0.4,
                0.6,
                0.8,
            ]))

    optimizer = torch.optim.SGD([tensor], lr=0)
    scheduler = LinearCyclicalScheduler(optimizer,
                                        'lr',
                                        1,
                                        0,
                                        10,
                                        cycle_mult=2)

    trainer = Engine(lambda engine, batch: None)
    trainer.add_event_handler(Events.ITERATION_STARTED, scheduler)
    trainer.add_event_handler(Events.ITERATION_COMPLETED, save_lr)

    lrs = []
    trainer.run([0] * 10, max_epochs=3)

    assert lrs == list(
        map(
            pytest.approx,
            [
                # Cycle 1
                1.0,
                0.8,
                0.6,
                0.4,
                0.2,
                0.0,
                0.2,
                0.4,
                0.6,
                0.8,
                # Cycle 2
                1.0,
                0.9,
                0.8,
                0.7,
                0.6,
                0.5,
                0.4,
                0.3,
                0.2,
                0.1,
                0.0,
                0.1,
                0.2,
                0.3,
                0.4,
                0.5,
                0.6,
                0.7,
                0.8,
                0.9,
            ]))

    # With float cycle_size
    optimizer = torch.optim.SGD([tensor], lr=0)
    scheduler = LinearCyclicalScheduler(optimizer,
                                        'lr',
                                        start_value=1.2,
                                        end_value=0.2,
                                        cycle_size=10.00000012,
                                        cycle_mult=1.0)

    trainer = Engine(lambda engine, batch: None)
    trainer.add_event_handler(Events.ITERATION_STARTED, scheduler)
    trainer.add_event_handler(Events.ITERATION_COMPLETED, save_lr)

    lrs = []
    trainer.run([0] * 10, max_epochs=2)
    assert lrs == list(
        map(
            pytest.approx,
            [
                # Cycle 1
                1.2,
                1.0,
                0.8,
                0.6,
                0.4,
                0.2,
                0.4,
                0.6,
                0.8,
                1.0,
                # Cycle 2
                1.2,
                1.0,
                0.8,
                0.6,
                0.4,
                0.2,
                0.4,
                0.6,
                0.8,
                1.0,
            ]))
Beispiel #10
0
training_saver = ModelCheckpoint(args.log_dir + '/checkpoints',
                                 filename_prefix="checkpoint",
                                 save_interval=1,
                                 n_saved=1,
                                 save_as_state_dict=False,
                                 create_dir=True)
to_save = {
    "network": model,
    "model_state": model.state_dict(),
    "optimizer_state": optimizer.state_dict()
}

scheduler_1 = LinearCyclicalScheduler(optimizer,
                                      "lr",
                                      start_value=1e-2,
                                      end_value=1e-1,
                                      cycle_size=60)

trainer.add_event_handler(Events.EPOCH_COMPLETED, training_saver, to_save)
#trainer.add_event_handler(Events.ITERATION_STARTED, scheduler_1)


@trainer.on(Events.EPOCH_COMPLETED)
def print_loss(engine):
    print('Running Loss {:.2f}'.format(engine.state.metrics['smooth loss']))
    print('L_BC {:.2f}'.format(engine.state.output[1].item()))
    print('L_KL {:.2f}'.format(engine.state.output[-2].item()))


@trainer.on(Events.ITERATION_COMPLETED)