Выход нейронной сети всегда сходится к тому же значению с пользовательскими потери косинусного углаPython

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Выход нейронной сети всегда сходится к тому же значению с пользовательскими потери косинусного угла

Сообщение Anonymous »

Для моего независимого исследовательского проекта в школе я использовал область формы вентилятора, чтобы нарисовать взаимосвязь между углом и значением COS, и поставил ее в качестве функции потери. Вот почему функция потери немного сложна. Но это может быть дифференцировано, и это не отрицательно, поэтому я подумал, что это работает должным образом.
, но выход модели всегда сходится к некоторому числу. Я дал штраф, уменьшил уровень нормализации, масштабировал вход через журнал, установил инициализацию модели, или также представил планировщика для решения этой проблемы. но результат был таким же.
Почему это происходит, и как это исправить?class Model(nn.Module):
def __init__(self):
super().__init__()
self.model = nn.Sequential(
nn.Linear(1, 128),
nn.LeakyReLU(negative_slope=0.01),
nn.LayerNorm(128),

nn.Linear(128, 512),
nn.LeakyReLU(),

nn.Linear(512, 512),
nn.LeakyReLU(),

nn.Linear(512, 128),
nn.LeakyReLU(),
nn.LayerNorm(128),

nn.Linear(128, 1),
nn.Sigmoid()
)
< /code>

loss_fuction < /p>
class Compute_fucs():
def __init__(self):
self.grid = torch.linspace(0, 1, steps=10000000, dtype=torch.float64)
self.scale = 1
def compute_circle(self, cos):
cos = cos.to('cuda')
starts = cos
xs = starts + (self.grid.to('cuda') * (1 - starts))
length = (self.grid[1]-self.grid[0])*(1 - starts)
length = length.to('cuda')
ys = torch.sqrt(torch.clamp(1 - xs**2, min = 1e-6))
result = length*ys
return result.sum(dim=1)

def compute_triangle(self, cos):
cos = cos.to('cuda')
return cos*torch.sqrt(torch.clamp(1 - cos**2,min = 1e-6))

def loss_fn(self, output, target,panerty):
cos = output

out1 = self.compute_circle(cos)
out2 = self.compute_triangle(cos)

output = 2*out1 + out2
target = target*(torch.pi / 180)

loss = torch.mean((target*self.scale - output*self.scale)**2)
return loss + panerty
< /code>

trainer < /p>
class Modeltrainer():
def __init__(self,model = None, opt = None, best_loss = None):
self.model = copy.deepcopy(model)
self._init_weights()
self.model = self.model.to('cuda')
self.opt = opt if opt is not None else torch.optim.Adam(model.parameters(), lr=0.001)
self.compute = Compute_fucs()
self.loss_fn = self.compute.loss_fn
self.best_loss = best_loss if best_loss is not None else 1e30
self.best_state = None
self.opt_best_state = None
self.scheduler = CyclicLR(self.opt,
base_lr=0.0001,
max_lr=0.006,
step_size_up=113,
mode='exp_range',
gamma=0.99994
)

def _init_weights(self):
for m in self.model.modules():
if isinstance(m, nn.Linear) and m.out_features != 1:
nn.init.kaiming_normal_(
m.weight,
a=0.01,
mode='fan_in',
nonlinearity='leaky_relu'
)
if m.bias is not None:
nn.init.constant_(m.bias, 0)
if isinstance(m, nn.Linear) and m.out_features == 1:
nn.init.xavier_uniform_(m.weight, gain=nn.init.calculate_gain('sigmoid'))
if m.bias is not None:
nn.init.constant_(m.bias, 0)

def is_decrease(self,y,x,creat_graph=None):
dy_dx = torch.autograd.grad(y.sum(), x,create_graph=creat_graph)[0]
dec = torch.tensor(0.0, dtype=torch.float64, device='cuda')
if (dy_dx > 0).any() == True:
dec += torch.sum(dy_dx[dy_dx > 0])

if (dy_dx < -1).any() == True:
dec += torch.sum(torch.abs(dy_dx[dy_dx < -1]))

return dec

def train(self,x,y,num_epochs):

self.best_state = copy.deepcopy(self.model.state_dict())
self.opt_best_state = copy.deepcopy(self.opt.state_dict())
finished = False
eval_loss = []
dataset = TensorDataset(x, y)
g = torch.Generator()
g.manual_seed(42)
train_loader = DataLoader(dataset, batch_size=8, shuffle=True, generator=g)
for epoch in range(num_epochs):

loop = tqdm(train_loader, desc=f"Epoch {epoch+1}/{num_epochs}",leave=False)
for x, y in loop:
x = x.to('cuda')
y = y.to('cuda')

self.opt.zero_grad()
output = self.model(x)
panerty = self.is_decrease(output,x,creat_graph=True)
loss = self.loss_fn(output, y, panerty)
loss.backward(retain_graph=True)
self.opt.step()

loop.set_postfix(loss=loss.item())
self.scheduler.step()
< /code>


train_model.py
< /blockquote>
data = torch.linspace(0, 90, steps=901, dtype=torch.float64)
data = data[:,None]
datax = torch.log(data+1).requires_grad_(True)
model = set.Model().double()
opt = torch.optim.Adam(model.parameters(), lr=0.001)
try:
trainer.train(datax,data,num_epochs=10**5)
finally:
torch.save( {'model_state_dict': trainer.best_state,
'optimizer_state_dict': trainer.opt_best_state,
'best_loss': trainer.best_loss}, './model.pth')
< /code>

Это коды, которые, как мне кажется, необходимы для воспроизведения проблемы. < /p>

Пример выхода < /p>
< /blockquote>
0.7720421077095195
0.7720421077352624
0.7720421077415953
0.772042107744354
0.7720421077458866
0.7720421077468598
.
.
.


Подробнее здесь: https://stackoverflow.com/questions/796 ... e-angle-lo
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»