Hello,
@ptrblck Thank you for your answer. I took your advice and created a model that uses the sinus function with a training parameter that matches the frequency of the oscillation function. The objective of learning is then to find the right frequency. In the case of even or odd it is pi / 2. Here is my code below.
According to you is it possible to make it easier?
class AbsSinTensorFucntion(nn.Module):
    def __init__(self,alpha = None):
        super().__init__()
        if alpha == None:
            self.alpha = Parameter(torch.tensor(1.0))
        else:
            self.alpha = Parameter(torch.tensor(alpha)) 
        
        self.alpha.requiresGrad = True
        #alpha is a learnable parameter
        
    def forward(self, input):
        return torch.abs(torch.sin(self.alpha*input)) #Will return 0 on pair number and 1 on impair if alpha is pi/2


##CASE of pair impair
absSinInput = AbsSinTensorFucntion() #to be oscillating COS(X)+1

model = nn.Sequential(OrderedDict([
                      ('absSinInput', absSinInput)
                        ]))
optimizer = optim.Adam(model.parameters(), lr=0.001)
optimizer.zero_grad()
loss = nn.BCELoss() #because it's binary
##

savedalpha = absSinInput.alpha
print("**************************************")
print("Start alpha = " + str(savedalpha.item()))
print("**************************************")
#It should stop when alpha is around a multiple of pi/2
step = 0
bestvalidloss = np.inf
for epoch in range(50):
    for i in range(1,200,1):
        inputz = torch.tensor([[float(i)]], requires_grad=True, dtype=torch.float)
        target = torch.tensor([[float(i%2)]])
        bestloss = np.inf
        print("###############learn with " + str(i) + "###############")
        for improve in range(10): #for each sample try to find best alpha
            result = model(inputz)
            lossoutput = loss(result, target)
            lossoutput.backward()
            optimizer.step()
            step +=1
            print("loss output = " + str(lossoutput.item())+"#alpha = " + str(absSinInput.alpha.item()))
            if(lossoutput.item() < bestloss):
                bestloss = lossoutput.item()
                savedalpha = absSinInput.alpha
            else:
                absSinInput.alpha = savedalpha
                #print("stop and restore the best #alpha = " + str(absSinInput.alpha.item()))
                break
            validpred = model(torch.tensor([[555.0]]))
        validloss = loss(validpred, torch.tensor([[1.0]]))
        print("**************************************") 
        print("valid loss = " + str(validloss.item()))
        print("**************************************") 
        if(validloss.item() < bestvalidloss):
            bestvalidloss = validloss.item()
        else:
            break
print("**************************************")
print("Best alpha = " + str(absSinInput.alpha.item()))
print("pi/2 = " + str(np.pi/2))
print("**************************************")
print("Predict(1) = " + str(model(torch.tensor([[1]])).item()))
print("Predict(2) = " +  str(model(torch.tensor([[2]])).item()))
print("Predict(3) = " +  str(model(torch.tensor([[3]])).item()))
print("Predict(4) = " +  str(model(torch.tensor([[4]])).item()))
print("Predict(5) = " +  str(model(torch.tensor([[5]])).item()))
print("Predict(11111111) = " + str(model(torch.tensor([[11111111]])).item()))
print("Predict(990) = " +  str(model(torch.tensor([[990]])).item()))


I get the output : so it’s 1 when the input is an odd number and 0 for even number.
**************************************
Best alpha = 1.5897823572158813
pi/2 = 1.5707963267948966
**************************************
Predict(1) = 0.9998197555541992
Predict(2) = 0.037962935864925385
Predict(3) = 0.998378336429596
Predict(4) = 0.07587113976478577
Predict(5) = 0.9954975247383118
Predict(11111111) = 0.6603634357452393
Predict(990) = 0.053372591733932495