My bad, Sorry for the back and forth. I tried using the .clone() function to sort the issue with inplace operation. However it still gave the same error. I am not sure of another way to get this done. is there another route different from .clone()?
Here is the edited NN code below:
import os
os.environ['TF_CPP_MIN_LOG_LEVEL']="2"
import numpy as np # linear algebra
import random
from numpy import newaxis
from numpy import array
import torch
from torch import nn
torch.pi = torch.acos(torch.zeros(1)).item() * 2 # which is 3.1415927410125732
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)
from sklearn.preprocessing import MinMaxScaler
import matplotlib.pyplot as plt
import math
import array
from sklearn.metrics import confusion_matrix
plt.style.use('fivethirtyeight')
print ('import completed')
#initializing the power time and distance
global N
global t
global Time_res
N=5
t=np.zeros((N,201), dtype=float)
t=torch.Tensor(t)
Tx_powers=np.ones((N,1), dtype=int)
AttExp = 2 # Attenuation Exponent (2 = free space)
AttConst = 1000**2 # Attenuation coefficient (e.g., Aeff)
X_max= 20
Y_max=20
Time_res=torch.tensor(1/200)
location_X=X_max*np.random.rand(N,1)
location_Y=Y_max*np.random.rand(N,1)
Distance_matrix=np.zeros((N,N), dtype=float)
P0= 0.01
#Allocating the different nodes randomly
for i in range(N):
for j in range(i+1, N):
Distance_matrix[i,j]=1000*np.sqrt(np.square(location_X[j]-location_X[i])+np.square(location_Y[j]-location_Y[i]))
Distance_matrix[j,i]=Distance_matrix[i,j]
#Generating RSSI matrix, i.e. Pr
#Row index = receiver, Column index = transmitter
RSSI_Matrix = np.zeros((N,N),dtype=float)
for i in range(N):
for j in range(N):
if i != j : # If ii=jj the RSSI is infinite
RSSI_Matrix[i,j] = Tx_powers[j]*AttConst/Distance_matrix[i,j]**AttExp
elif i == j:
RSSI_Matrix[i,j] = 0
# Initializing nodes to random clocks.
# t_i(0) is the initial offset of user % i. It is uniform over 1/200 sec
# Time resolution is 1/200 of a sec. We count timing in unit of T_res = 1/200 sec
for i in range (N):
t[i,0]= torch.rand(1,1)*Time_res
plt.scatter(location_X, location_Y, label='WSN Layout', marker='o')
Data_pow=pd.DataFrame(data=RSSI_Matrix, index=None, columns=None, dtype=None, copy=None)
print(Data_pow.to_string())
Data_time=pd.DataFrame(data=t, index=None, columns=None, dtype=None, copy=None)
print(Data_time.loc[0:N,0].to_string())
print(t[:,0])
# Get cpu or gpu device for training.
device = "cuda" if torch.cuda.is_available() else "cpu"
print("Using {} device".format(device))
# Defining the Network model
class NeuralNetwork(nn.Module):
def __init__(self):
super(NeuralNetwork, self).__init__()
"""this is the neural network
it can take a shape of 9 columns by any column
the output layer is 2
"""
self.model = nn.Sequential(
nn.Linear(3*N,N-1),
nn.Sigmoid(),
nn.Linear(N-1,N-1),
nn.Sigmoid(),
nn.Linear(N-1,N-1),
nn.Softmax(dim=1),
)
def forward(self, x, time_idx):
#x is input data that you want to pass into the neural network
# self.network_output is network output
#t[:,time_idx+1] is the new clock time for the next time index (Eqn. 16) gotten from the weights (i.e., softmax o/p)
self.network_output = self.model(x)
for i in range(N):
diff=t[:,time_idx].clone()-t[i,time_idx].clone()
diff=diff[diff!=0].clone()
t[i,time_idx+1]=t[i,time_idx].clone()+Time_res.clone() + torch.sum(torch.dot(self.network_output[i,:].clone(), diff.clone()))
self.newtime=t[:,time_idx+1].clone()
sumerror=torch.zeros((N,1), dtype=float)
mse_loss = nn.MSELoss()
for i in range(N):
for j in [a for a in range(N) if a != i]:
sumerror[i]=sumerror[i].clone()+mse_loss(self.newtime[i].clone(),self.newtime[j].clone())
self.loss=torch.sum(sumerror.clone())
return self.network_output, self.newtime, self.loss
modelmy=NeuralNetwork().to(device)
# Setting the input Matrix to the NN
Nodein=torch.zeros(N,3*N)
for b in range(N):
Node=torch.cat([t[:,0].clone(), torch.Tensor(Distance_matrix[b,:]).clone(),torch.Tensor(RSSI_Matrix[b,:]).clone()])
Nodein[b,:]=Node.clone()
print(Nodein)
#RUNNING THE CODE
torch.autograd.set_detect_anomaly(True)
optimizer = torch.optim.SGD(modelmy.parameters(), lr=0.01)
steps = 20
for i in range(steps):
output = modelmy.forward(Nodein,i)
#loss=modelmy.custom_loss(output[1],i)
loss=modelmy.loss
print(loss)
optimizer.zero_grad()
loss.backward(retain_graph=True)
optimizer.step()
Not sure, but, I am guessing the optimizer.step is modifying the parameters inplace.