Почему моя функция градиентного спуска для составления полиномиального уравнения для sinx не может работать ⇐ Python
Почему моя функция градиентного спуска для составления полиномиального уравнения для sinx не может работать
Мне нужно написать программу, которая будет использовать градиентный спуск, чтобы подогнать полиномиальное уравнение к sin(x). И я не могу не использовать автоград pytorch, поэтому мне нужно манипулировать собой.
Я проверял свой код много раз, но не могу найти проблем. Я думаю, что процесс градиента не вызывает проблем. И я использую простой x, y для проверки вперед и назад в моем коде. результат кода такой же, как и в моей статье.
Однако правда в том, что потеря модели происходит постепенно. Может кто-нибудь может мне помочь? Это домашнее задание моего учителя. Помогите! Возможно, код немного длинный, я буду искренне признателен вам, если вы сможете взгляд!
код следующий:
импортировать фонарик из torch.utils.data импортировать набор данных, DataLoader импортировать matplotlib.pyplot как plt ##DataSet и DataLoader класс MyDataset(Набор данных): защита __init__(сам): self.x = torch.linspace(0,10,500) self.y = torch.sin(self.x) def __getitem__(сам, индекс): возврат (self.x[индекс],self.y[индекс]) защита __len__(сам): вернуть len(self.x) набор данных = МойНаборДанных() dataloader = DataLoader(набор данных,batch_size=50,num_workers=0,shuffle=True) ##Модель класс МояМодель(): защита __init__(self,n): утверждать n>=1 self.n = n self.parameters = torch.randn((1,n+1)) #[1,n+1],Θ0,Θ1...Θn def back(self,weight,x): """ вес: (партия,1) y_pred-y х : (партия, 1) """ x = x.expand(x.shape[0],self.n).clone() #size:(batch,1) -> (batch,n) x = torch.concat((torch.ones(x.shape[0],1),x),dim=1) #size:(batch,n) -> size:(batch,n+1) градиент_тензор = torch.zeros_like(self.parameters) для я в диапазоне (self.n+1): градиент_тензор[0,i] = torch.mean(torch.pow(x[:,i],i).unsqueeze(-1) * вес,dim=0) вернуть градиент_тензор защита вперед (сам, x): x = x.expand(x.shape[0],self.n).clone() #size:(batch,1) -> (batch,n) x = torch.concat((torch.ones(x.shape[0],1),x),dim=1) #,size:(batch,n) -> (batch,n+!) для я в диапазоне (self.n + 1): x[:,i] = torch.pow(x[:,i],i) вернуть x @ self.parameters.T шаг защиты (self,gradient_tensor,lr): self.parameters = self.parameters - lr *gradient_tensor защита __call__(self,x): вернуть self.forward(x) модель = MyModel(5) Полином #5 ##процесс обучения def train(модель:MyModel,epoch=500,lr=1e-5,name=''): список_потерь = [] для меня в диапазоне (эпоха): общий_убыток = 0 для x,y в загрузчике данных: x,y = x.unsqueeze(-1),y.unsqueeze(-1) #size:(50) -> (50,1) y_pred = модель (х) y_difference = (y_pred - y) потеря = (0,5 * (y_difference ** 2)).mean() total_loss += потеря градиент_тензор = model.backward(y_difference,x) model.step(gradient_tensor,lr) print(f"эпоха:{i}/{эпоха} потеря:{total_loss}") loss_list.append(общая_потеря) print(f"завершить обучение модели {name}") вернуть список_потерь ##тренироваться loss_3 = поезд (модель, имя = '3', эпоха = 10, lr = 1e-8) проверка прямого кода (модель — 5-полиномиальная):
x = torch.tensor([0,torch.pi/2],dtype=torch.float64).unsqueeze(-1) y = torch.tensor([0,1],dtype=torch.float64).unsqueeze(-1) model.parameters = torch.tensor([1,1,1,1,1,1],dtype=torch.float64).unsqueeze(0) y_pred = модель (х) y_pred ##выход #tensor([[ 1.0000], # [24.5652]]) температура = torch.pi/2 1 + температура + температура ** 2 + температура ** 3 + температура ** 4 + температура ** 5 ##выход:24.565165351269908 проверка обратного кода:
y_difference = y_pred - y градиент_тензор = model.backward(y_difference,x) градиент_тензор #output:tensor([[ 12.2826, 18.5080, 29.0724, 45.6668, 71.7332, 112.6782]]) вес = y_difference[1].item() temp_gradient = torch.tensor([[1,0,0,0,0,0], [вес * 1,вес * (torch.pi/2),вес * (torch.pi/2) ** 2,вес * (torch.pi/2) ** 3,вес * (torch.pi/2) ** 4,вес * (torch.pi/2) ** 5]],dtype=torch.float64) print(temp_gradient.mean(dim=0)) #output:tensor([ 12.2826, 18.5080, 29.0724, 45.6668, 71.7332, 112.6782])
Мне нужно написать программу, которая будет использовать градиентный спуск, чтобы подогнать полиномиальное уравнение к sin(x). И я не могу не использовать автоград pytorch, поэтому мне нужно манипулировать собой.
Я проверял свой код много раз, но не могу найти проблем. Я думаю, что процесс градиента не вызывает проблем. И я использую простой x, y для проверки вперед и назад в моем коде. результат кода такой же, как и в моей статье.
Однако правда в том, что потеря модели происходит постепенно. Может кто-нибудь может мне помочь? Это домашнее задание моего учителя. Помогите! Возможно, код немного длинный, я буду искренне признателен вам, если вы сможете взгляд!
код следующий:
импортировать фонарик из torch.utils.data импортировать набор данных, DataLoader импортировать matplotlib.pyplot как plt ##DataSet и DataLoader класс MyDataset(Набор данных): защита __init__(сам): self.x = torch.linspace(0,10,500) self.y = torch.sin(self.x) def __getitem__(сам, индекс): возврат (self.x[индекс],self.y[индекс]) защита __len__(сам): вернуть len(self.x) набор данных = МойНаборДанных() dataloader = DataLoader(набор данных,batch_size=50,num_workers=0,shuffle=True) ##Модель класс МояМодель(): защита __init__(self,n): утверждать n>=1 self.n = n self.parameters = torch.randn((1,n+1)) #[1,n+1],Θ0,Θ1...Θn def back(self,weight,x): """ вес: (партия,1) y_pred-y х : (партия, 1) """ x = x.expand(x.shape[0],self.n).clone() #size:(batch,1) -> (batch,n) x = torch.concat((torch.ones(x.shape[0],1),x),dim=1) #size:(batch,n) -> size:(batch,n+1) градиент_тензор = torch.zeros_like(self.parameters) для я в диапазоне (self.n+1): градиент_тензор[0,i] = torch.mean(torch.pow(x[:,i],i).unsqueeze(-1) * вес,dim=0) вернуть градиент_тензор защита вперед (сам, x): x = x.expand(x.shape[0],self.n).clone() #size:(batch,1) -> (batch,n) x = torch.concat((torch.ones(x.shape[0],1),x),dim=1) #,size:(batch,n) -> (batch,n+!) для я в диапазоне (self.n + 1): x[:,i] = torch.pow(x[:,i],i) вернуть x @ self.parameters.T шаг защиты (self,gradient_tensor,lr): self.parameters = self.parameters - lr *gradient_tensor защита __call__(self,x): вернуть self.forward(x) модель = MyModel(5) Полином #5 ##процесс обучения def train(модель:MyModel,epoch=500,lr=1e-5,name=''): список_потерь = [] для меня в диапазоне (эпоха): общий_убыток = 0 для x,y в загрузчике данных: x,y = x.unsqueeze(-1),y.unsqueeze(-1) #size:(50) -> (50,1) y_pred = модель (х) y_difference = (y_pred - y) потеря = (0,5 * (y_difference ** 2)).mean() total_loss += потеря градиент_тензор = model.backward(y_difference,x) model.step(gradient_tensor,lr) print(f"эпоха:{i}/{эпоха} потеря:{total_loss}") loss_list.append(общая_потеря) print(f"завершить обучение модели {name}") вернуть список_потерь ##тренироваться loss_3 = поезд (модель, имя = '3', эпоха = 10, lr = 1e-8) проверка прямого кода (модель — 5-полиномиальная):
x = torch.tensor([0,torch.pi/2],dtype=torch.float64).unsqueeze(-1) y = torch.tensor([0,1],dtype=torch.float64).unsqueeze(-1) model.parameters = torch.tensor([1,1,1,1,1,1],dtype=torch.float64).unsqueeze(0) y_pred = модель (х) y_pred ##выход #tensor([[ 1.0000], # [24.5652]]) температура = torch.pi/2 1 + температура + температура ** 2 + температура ** 3 + температура ** 4 + температура ** 5 ##выход:24.565165351269908 проверка обратного кода:
y_difference = y_pred - y градиент_тензор = model.backward(y_difference,x) градиент_тензор #output:tensor([[ 12.2826, 18.5080, 29.0724, 45.6668, 71.7332, 112.6782]]) вес = y_difference[1].item() temp_gradient = torch.tensor([[1,0,0,0,0,0], [вес * 1,вес * (torch.pi/2),вес * (torch.pi/2) ** 2,вес * (torch.pi/2) ** 3,вес * (torch.pi/2) ** 4,вес * (torch.pi/2) ** 5]],dtype=torch.float64) print(temp_gradient.mean(dim=0)) #output:tensor([ 12.2826, 18.5080, 29.0724, 45.6668, 71.7332, 112.6782])
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Почему моя функция градиентного спуска дает мне большие отрицательные значения?
Anonymous » » в форуме Python - 0 Ответы
- 60 Просмотры
-
Последнее сообщение Anonymous
-