Могу ли я указать в PyTorch скорость обучения с учетом веса ядра?
Я хотел бы установить конкретную скорость обучения для каждого параметра на самом низком уровне. Т.е. каждое значение в весе ядер и смещениях должно иметь свою скорость обучения.
Я могу указать такие скорости обучения с использованием фильтров:
optim = torch.optim.SGD([{'params': model.conv1.weight, 'lr': 0.1},], lr=0.01)
Но когда я хочу перейти на уровень ниже, вот так:
optim = torch.optim.SGD([{'params': model.conv1.weight[0, 0, 0, 0], 'lr': 0.1},], lr=0.01)
Я получаю сообщение об ошибке: ValueError: can't optimize a non-leaf Tensor
Я также попытался указать скорость обучения, которая имеет ту же форму, что и фильтр, например 'lr': torch.ones_like(model.conv1.weight)
, но и это не сработало.
Есть ли способ сделать это с помощью torch.optim
?
2 ответа
Возможно, я нашел решение. Поскольку можно ввести только полные веса и смещения слоя Conv, нам нужно вставить скорость обучения, имеющую ту же форму, что и тензор веса / смещения.
Вот пример использования torch.optim.Adam
:
torch.optim.CustomAdam([{'params': param, 'lr': torch.ones_like(param, requires_grad=False) * lr}
for name, param in model.named_parameters()])
Затем нам нужно изменить строку в самом оптимизаторе. Для этого я создал собственный оптимизатор:
class CustomAdam(torch.optim.Adam):
def step(self, closure=None):
...
# change the last line: p.data.addcdiv_(-step_size, exp_avg, denom) to
p.data.add_((-step_size * (exp_avg / denom)))
Простая уловка - создать новый тензор с именем learning_rate
который имеет тот же размер, что и модель. Затем, когда вы применяете градиенты, вы умножаетеgradients
тензор с learning_rate
тензор. Пожалуйста, дайте мне знать, работает ли это для вас.