使用 HingeEmbeddingLoss() 函数进行二元分类时出现问题

问题描述 投票:0回答:1

我有 2 个数据集,它们组成了 2 条正弦曲线的 (x,y) 坐标及其各自的输出。 正弦曲线是同心的。

较大的正弦曲线的输出标签为 1,较小的正弦曲线的输出标签为 -1。

我必须训练一个模型,该模型将接受新的 (x,y) 坐标并输出 -1 或 +1,具体取决于它可能属于哪条曲线。

现在我已经准备好数据了-

#generate data_set - sin wave 1 and sin wave 2

def wave_Lower_training_data(n = 300):
  #generate random input points for wave 1
  X1 = random.uniform(0,2*pi,n) #generates 'n' radian values b/w 0 to 2pi
  #wave output
  X2 = sin(X1) #lower curve
  X1 = X1.reshape(n, 1)
  X2 = X2.reshape(n,1)
  X = hstack((X1,X2))
  # y = -ones((n,1))
  y = -ones((n,1))

  return X,y

def wave_Higher_training_data(n = 300):
  #generate random input points for wave 1
  X1 = random.uniform(0,2*pi,n) #generates 'n' radian values b/w 0 to 2pi
  #wave output
  X2 = 2*sin(X1) #higher curve
  X1 = X1.reshape(n, 1)
  X2 = X2.reshape(n,1)
  X = hstack((X1,X2))
  y = ones((n,1))

  return X,y

X1, y1 = wave_Lower_training_data()
X2, y2 = wave_Higher_training_data()

# print(X1)

# Combine the training data
X_combined = vstack((X1, X2))
y_combined = vstack((y1, y2))




# print("Combined X shape:", X_combined)
# print("Combined y shape:", y_combined)

这就是我尝试建模的方式-

import torch
import torch.nn as nn
import torch.optim as optim
from sklearn.model_selection import train_test_split

class Model(nn.Module):
    def __init__(self):
        super(Model, self).__init__()
        # Define model
        self.fc1 = nn.Linear(2, 64)
        self.relu = nn.ReLU()
        self.fc2 = nn.Linear(64, 32)
        self.fc3 = nn.Linear(32, 16)
        self.fc4 = nn.Linear(16,1)
        self.tanh = nn.Tanh()

    def forward(self, x):
        x = self.relu(self.fc1(x))
        x = self.relu(self.fc2(x))
        x = self.relu(self.fc3(x))
        x = self.tanh(self.fc4(x))
        return x

# Convert training data into tensors usable by PyTorch
X_tensor = torch.tensor(X_combined, dtype=torch.float32)
y_tensor = torch.tensor(y_combined, dtype=torch.int64)
print(y_tensor)

# Splitting of training data into 80-20
X_train, X_val, y_train, y_val = train_test_split(X_tensor, y_tensor, test_size=0.2, random_state=786)

model = Model()
criterion = nn.HingeEmbeddingLoss()
optimizer = optim.Adam(model.parameters(), lr=0.0001)

# Training loop
n_epochs = 10000
for epoch in range(0, n_epochs):
    optimizer.zero_grad()
    output = model(X_train)
    loss = criterion(output.squeeze(), y_train.long())
    loss.backward()
    optimizer.step()

    if epoch % 100 == 0:
        print(f"Epoch {epoch+1}/{n_epochs}, Loss: {loss.item()}")

with torch.no_grad():
    y_pred = model(X_val)
    y_pred_class = torch.sign(y_pred)
    accuracy = (y_pred_class.squeeze().long() == y_val.long()).sum().item() / len(y_val)
    print(f"Validation Accuracy: {accuracy}")

当我检查每 100 个时期的损失百分比时,很明显,在一个点之后,它就停滞了?

然后当我进入预测部分时-

#predictions
def get_user_input():
    them to a list:
    feature1 = float(input("Enter the first feature value: "))
    feature2 = float(input("Enter the second feature value: "))
    return [feature1, feature2]

# Get user input
X_new = get_user_input()
X_ip = torch.tensor(X_new, dtype=torch.float32)
y_pred = model(X_ip)

print(y_pred)


pyplot.figure(figsize=(10, 6))
pyplot.scatter(X1[:, 0], X1[:, 1], label='Wave 1', color='blue', s=10)
pyplot.scatter(X2[:, 0], X2[:, 1], label='Wave 2', color='red', s=10)
user_x = X_new[0]  # Example x-coordinate for user input
user_y = X_new[1]  # Example y-coordinate for user input
pyplot.scatter(user_x, user_y, color='green', label='User Input Point')

pyplot.xlabel('Angle (radians)')
pyplot.ylabel('Amplitude')
pyplot.title('Sine Waves with Amplitudes 1 and 2')
pyplot.legend()
pyplot.show()

这是我得到的输出-

Enter the first feature value: 1.9
Enter the second feature value: 2
tensor([-1.], grad_fn=<TanhBackward0>)

从图中可以很清楚地看出,输出应该是[+1],因为它类似于上面的曲线。但我仍然得到[-1]?

无论我给出什么输入,我总是得到 [-1]。

有什么帮助吗?

编辑我已经尝试使用 BCELoss() 进行相同的操作,它似乎有效。但我需要将其映射到 {-1,1} 而不是 {0,1}。

python machine-learning deep-learning pytorch logistic-regression
1个回答
0
投票

您阅读过 HingeEmbeddingLoss 的文档吗?

Measures the loss given an input tensor 𝑥 and a labels tensor 𝑦 (containing 1 or -1). This is usually used for measuring whether two inputs are similar or dissimilar, e.g. using the L1 pairwise distance as 𝑥, and is typically used for learning nonlinear embeddings or semi-supervised learning.

x
中的
HingeEmbeddingLoss
应该是成对嵌入之间的距离。它根本不适用于您的预测问题。

如果您查看损失的计算方式,则模型仅预测 -1 是完全有意义的。

给定

loss(x,y)
,损失计算为
x
,其中
y=1
max(0, margin-x)
,其中
y=-1

如果

y=1
,则训练模型以产生尽可能小的值(对于 tanh 约束为 -1)。

解决这个问题的正确方法是使用二元分类(正如您提到的,它是有效的)。如果您需要输出位于

[-1, 1]
,您只需在预测后将 sigmoid logits 从
[0, 1]
重新调整为
[-1, 1]

© www.soinside.com 2019 - 2024. All rights reserved.