# Mapping Trignometric Math functions as Neural Networks

Hello All,

I am new to PyTorch and started with a simple project for learning purposes. Here is the data format I currently have current=(x1,y1) target=(x2,y2) and would like to predict the angle between the two points using the cosine formula = (x2-x1) / distance.euclidean(current,target). I have a simple neural network that takes the 2 pairs points in and has 2 outputs (sin, consine). The encoding for the angles is inspired from this post Link. My code with comments is as follows. The results i get are absurd loss values and totally wrong predictions clearly indicate I am going wrong. I am trying hard to figure out where but feeling lost. Any help on this would be appreciated. The activation function and loss function
were inspired form this Post

``````class Net(nn.Module):
def __init__(self):

super(Net, self).__init__()
self.fc1 = nn.Linear(4,2)
self.htanh = nn.Hardtanh(-1,1)

def forward(self, x):
return self.htanh(self.fc1(x))

#Angle Encoding : http://practicalcryptography.com/miscellaneous/machine-learning/encoding-variables-neural-networks/
df['sin_desired'] = df['desired_heading'].apply(lambda x: math.sin(x*0.0174533))
df['cos_desired'] = df['desired_heading'].apply(lambda x: math.cos(x*0.0174533))

X = df[['x_t', 'y_t', 'x_c', 'y_c']]
y = df[['sin_desired','cos_desired']]

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=RANDOM_SEED)

X_train = torch.from_numpy(X_train.to_numpy()).float()
y_train = torch.squeeze(torch.from_numpy(y_train.to_numpy()).float())
X_test = torch.from_numpy(X_test.to_numpy()).float()
y_test = torch.squeeze(torch.from_numpy(y_test.to_numpy()).float())
print(X_train.shape, y_train.shape)
print(X_test.shape, y_test.shape)

net = Net()
optimizer = optim.Adam(net.parameters(), lr=0.001)
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
X_train = X_train.to(device)
y_train = y_train.to(device)

X_test = X_test.to(device)
y_test = y_test.to(device)

net = net.to(device)

criterion = nn.MSELoss()
criterion = criterion.to(device)

for epoch in range(1000):
y_pred = net(X_train)
y_pred = torch.squeeze(y_pred)
train_loss = criterion(y_pred, y_train)
print(f'''epoch {epoch} Train set - loss: {(train_loss)}, ''')
train_loss.backward()
optimizer.step()

def get_desired_angle(x_t, y_t, x_c, y_c):
t = torch.as_tensor([x_t, y_t, x_c, y_c]) \
.float() \
.to(device)
output = net(t)
return output

output = get_desired_angle(6,6,0,0)
print(output)
sin_theta = output
cos_theta = output
tan_theta = sin_theta/cos_theta
print(sin_theta,cos_theta,tan_theta) `````````

Could you check the shape of `y_pred` before using `torch.squeeze` as well as the shape of `y_train`?
Since you are using `nn.MSELoss` both tensors should have the same shape as otherwise a broadcasting would be applied internally and will raise a warning in newer PyTorch versions.