reinforcement learning improvement suggestions equating float numbers with open ai gym - deep-learning

I'm working on a reinforcement model at university. The aim is to equate three decimal numbers (X,Y,Z) to other decimal numbers (X2,Y2,Z2).
I already have a working model and would like to ask you for suggestions for improvement. I use the open ai gym library
with each reset the agent gets new numbers
X=(random.uniform(-1, 1))
Y=(random.uniform(-1, 1))
Z=(random.uniform(-1, 1))
X = round(X, 5)
Y = round(Y, 5)
Z = round(Z, 5)
choice = random.choices([True,False])
if choice[0]:
X2=X + random.uniform(0,0.5)
Y2=Y + random.uniform(0,0.5)
Z2=Z + random.uniform(0,0.5)
else:
X2=X - random.uniform(0,0.5)
Y2=Y - random.uniform(0,0.5)
Z2=Z - random.uniform(0,0.5)
X2 = round(X2, 5)
Y2 = round(Y2, 5)
Z2 = round(Z2, 5)
Here are my 7 discrete actions:
if action == 0:
self.state[0] -= 0.00001
elif action == 1:
self.state[1] -= 0.00001
elif action == 2:
self.state[2] -= 0.00001
elif action == 3:
self.state[0] += 0.00001
elif action == 4:
self.state[1] += 0.00001
elif action == 5:
self.state[2] += 0.00001
elif action == 6:
self.state[0] += 0
self.state[1] += 0
self.state[2] += 0
My rewardsystem:
direction = np.array(self.state[3:6] - self.state[0:3])
length = np.sqrt(direction.dot(direction))
reward = length *-100
my model:
def build_model(states, actions):
model = Sequential()
model.add(Flatten(input_shape=(1,states)))
model.add(Dense(256, activation='relu'))
model.add(Dense(128, activation='relu'))
model.add(Dense(actions, activation="sigmoid"))
and my agent:
def build_agent(model, actions):
policy = BoltzmannQPolicy()
memory = SequentialMemory(limit=50000, window_length=1)
dqn = DQNAgent(model=model, memory=memory, policy=policy,
nb_actions=actions, nb_steps_warmup=10, target_model_update=1e-2)
i've tried a lot with the step length but i don't really get a feeling for it.
is there perhaps a better agent, a better policy or better actions?
I am thankful for every hint :)

Related

My neural network does not appear to learn DQN

Good morning,
I'm trying to implement a DQN with Bellman's Equations, however I don't know why but every prediction seems random. Just below here is my code.
The neural network :
class simpleAgent(nn.Module) :
def __init__(self,taille_entree, taille_sortie):
super(simpleAgent, self).__init__()
self.fc1 = nn.Linear(taille_entree, 32)
self.fc2 = nn.Linear(32, taille_sortie)
self.beta = 0.999
self.epsilon = 0.99
def forward(self, x):
x = F.relu(self.fc1(x))
x = self.fc2(x)
return x
def selectAction(self, pos):
if random.uniform(0,1) < self.epsilon:
self.epsilon = self.epsilon * self.beta
action = random.randint(0,1)
return action
else:
return torch.argmax(self(pos)).item()
The training code :
def optimize_model():
global model, targetNetwork
criterion = nn.MSELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=LEARNING_RATE)
if len(buffer_circ) < BATCH_SIZE:
return
transitions = buffer_circ.sample(BATCH_SIZE)
batch = Transition(*zip(*transitions))
state = torch.stack(batch.state)
action = torch.stack(batch.action)
reward = torch.stack(batch.reward)
continu = torch.stack(batch.terminated)
next_state = torch.stack(batch.next_state)
q_value = torch.flatten(model(state).gather(1, action))
q_value_next = torch.max(targetNetwork(next_state), 1).values
cible = reward + torch.mul(discount_factor,torch.mul(continu, q_value_next))
loss = criterion(q_value, cible)
optimizer.zero_grad()
loss.backward(retain_graph=True)
optimizer.step()
def train():
global model, targetNetwork
env = gym.make('CartPole-v1', render_mode="rgb_array", disable_env_checker=True)
env.action_space.seed(42)
tab = []
for i in range(5000):
observation, info = env.reset()
rewards=[]
cumule = 0
update_target = 1
terminated = False
truncated = False
while not terminated :
old_observation = observation
action = model.selectAction(torch.from_numpy(observation))
observation, reward, terminated, truncated, info= env.step(action)
cumule += reward
reward = torch.tensor(reward)
terminated = terminated or truncated
state = torch.from_numpy(old_observation)
next_state = torch.from_numpy(observation)
if terminated:
print(i,cumule)
tab.append(cumule)
rewards.append(cumule)
break
buffer_circ.push(state, torch.tensor([action]), next_state, reward, torch.tensor(not terminated))
optimize_model()
if update_target % TARGET_UPDATE == 0:
targetNetwork.load_state_dict(model.state_dict())
update_target = 0
update_target += 1
print('Complete')
env.render()
env.close()
I'm using a target network that is updated every TARGET_UPDATE, and model is the neural network that I train and Target network a copy of it. Yet, I have the loss decreasing and I also implemented the greedy-exploration with selectAction. If you could tell what's wrong in my code, it would be nice.
Thank you in advance

Why does loss history go to zero for momentum

I am trying to implement momentum for a linear regression model, I will like to save my plus at each point and plot against the iterations, but the loss decreases in the first few epochs and goes to zero, how do I solve this
''' def compute_cost(self, X, y):
loss = float((np.sum((X.dot(self.theta) - y) ** 2) ))/ 2
return loss
def fitmomentum(self, X, y,momentum = 0.9 ):
X = self.add_ones(X.values)
self.theta = np.zeros(X.shape[1])
self.cost_history = np.zeros(self.epoch)
self.momentum = momentum
self.velocity = np.zeros(self.epoch)
self.theta = self.momentum(g, self.velocity)
for i in range(len((X.T # (X # self.theta - y)))):
self.velocity[i] = self.momentum * self.velocity[i] + self.lr * ((X.T # (X # self.theta - y)))[i]
self.theta[i] += self.velocity[i]
self.cost_history[i] = self.compute_cost(X, y)
return self.theta, self.cost_history '''
This is what I see after printing the loss
'''array([4.20078101e+13, 6.06945342e+13, 7.01728125e+17, ...,
0.00000000e+00, 0.00000000e+00, 0.00000000e+00])'''
This is what the graph looks like..
plot of epochs against loss history

PyTorch: Dropout (?) causes different model convergence for training+validation V. training-only

We are facing a very strange issue. We tested the exact same model into two different “execution” settings. In the first case, given a certain amount of epochs, we train using mini-batches for one epoch, and thereafter we test on the validation set following the same criteria. Then, we go for the next epoch. Clearly, before each training epoch, we use model.train(), and before validation we turn on model.eval().
Then we take the exact same model (same init, same dataset, same epochs, etc.) and we just train it without validation after each epoch.
Just looking at performance on training set, we observed that, even if we fixed all seeds, the two training procedures evolve differently and produce quite different metrics results (losses, accuracy, and so on). Specifically, the training-only procedure is less performing.
We also observe the following things:
It is not a reproducibility issue, because multiple executions of the
same procedure produce exactly the same results (and this is
intended);
Removing the dropout, it appears that the problem vanishes;
Batchnorm1d layer, that still has different behaviours between
training and evaluation, seems to work properly;
The issue still happens if we move from training onto TPUs to CPUs.
We are working and tried Pythorch 1.6, Pythorch nightly, XLA 1.6.
We quite lost one full day in trying to tackle this issue (and no, we cannot avoid using dropout). Does anyone have any idea about how to solve this fact?
Thank you very much!
p.s. Here the code employed for the training (on CPU).
def sigmoid(x):
return 1 / (1 + torch.exp(-x))
def _run(model, EPOCHS, training_data_in, validation_data_in=None):
def train_fn(train_dataloader, model, optimizer, criterion):
running_loss = 0.
running_accuracy = 0.
running_tp = 0.
running_tn = 0.
running_fp = 0.
running_fn = 0.
model.train()
for batch_idx, (ecg, spo2, labels) in enumerate(train_dataloader, 1):
optimizer.zero_grad()
outputs = model(ecg)
loss = criterion(outputs, labels)
loss.backward() # calculate the gradients
torch.nn.utils.clip_grad_norm_(model.parameters(), 0.5)
optimizer.step() # update the network weights
running_loss += loss.item()
predicted = torch.round(sigmoid(outputs.data)) # here determining the sigmoid, not included in the model
running_accuracy += (predicted == labels).sum().item() / labels.size(0)
fp = ((predicted - labels) == 1.).sum().item()
fn = ((predicted - labels) == -1.).sum().item()
tp = ((predicted + labels) == 2.).sum().item()
tn = ((predicted + labels) == 0.).sum().item()
running_tp += tp
running_fp += fp
running_tn += tn
running_fn += fn
retval = {'loss':running_loss / batch_idx,
'accuracy':running_accuracy / batch_idx,
'tp':running_tp,
'tn':running_tn,
'fp':running_fp,
'fn':running_fn
}
return retval
def valid_fn(valid_dataloader, model, criterion):
running_loss = 0.
running_accuracy = 0.
running_tp = 0.
running_tn = 0.
running_fp = 0.
running_fn = 0.
model.eval()
for batch_idx, (ecg, spo2, labels) in enumerate(valid_dataloader, 1):
outputs = model(ecg)
loss = criterion(outputs, labels)
running_loss += loss.item()
predicted = torch.round(sigmoid(outputs.data)) # here determining the sigmoid, not included in the model
running_accuracy += (predicted == labels).sum().item() / labels.size(0)
fp = ((predicted - labels) == 1.).sum().item()
fn = ((predicted - labels) == -1.).sum().item()
tp = ((predicted + labels) == 2.).sum().item()
tn = ((predicted + labels) == 0.).sum().item()
running_tp += tp
running_fp += fp
running_tn += tn
running_fn += fn
retval = {'loss':running_loss / batch_idx,
'accuracy':running_accuracy / batch_idx,
'tp':running_tp,
'tn':running_tn,
'fp':running_fp,
'fn':running_fn
}
return retval
# Defining data loaders
train_dataloader = torch.utils.data.DataLoader(training_data_in, batch_size=BATCH_SIZE, shuffle=True, num_workers=1)
if validation_data_in != None:
validation_dataloader = torch.utils.data.DataLoader(validation_data_in, batch_size=BATCH_SIZE, shuffle=False, num_workers=1)
# Defining the loss function
criterion = nn.BCEWithLogitsLoss()
# Defining the optimizer
import torch.optim as optim
optimizer = optim.AdamW(model.parameters(), lr=3e-4, amsgrad=False, eps=1e-07)
# Training code
metrics_history = {"loss":[], "accuracy":[], "precision":[], "recall":[], "f1":[], "specificity":[], "accuracy_bis":[], "tp":[], "tn":[], "fp":[], "fn":[],
"val_loss":[], "val_accuracy":[], "val_precision":[], "val_recall":[], "val_f1":[], "val_specificity":[], "val_accuracy_bis":[], "val_tp":[], "val_tn":[], "val_fp":[], "val_fn":[],}
train_begin = time.time()
for epoch in range(EPOCHS):
start = time.time()
print("EPOCH:", epoch+1)
train_metrics = train_fn(train_dataloader=train_dataloader,
model=model,
optimizer=optimizer,
criterion=criterion)
metrics_history["loss"].append(train_metrics["loss"])
metrics_history["accuracy"].append(train_metrics["accuracy"])
metrics_history["tp"].append(train_metrics["tp"])
metrics_history["tn"].append(train_metrics["tn"])
metrics_history["fp"].append(train_metrics["fp"])
metrics_history["fn"].append(train_metrics["fn"])
precision = train_metrics["tp"] / (train_metrics["tp"] + train_metrics["fp"]) if train_metrics["tp"] > 0 else 0
recall = train_metrics["tp"] / (train_metrics["tp"] + train_metrics["fn"]) if train_metrics["tp"] > 0 else 0
specificity = train_metrics["tn"] / (train_metrics["tn"] + train_metrics["fp"]) if train_metrics["tn"] > 0 else 0
f1 = 2*precision*recall / (precision + recall) if precision*recall > 0 else 0
metrics_history["precision"].append(precision)
metrics_history["recall"].append(recall)
metrics_history["f1"].append(f1)
metrics_history["specificity"].append(specificity)
if validation_data_in != None:
# Calculate the metrics on the validation data, in the same way as done for training
with torch.no_grad(): # don't keep track of the info necessary to calculate the gradients
val_metrics = valid_fn(valid_dataloader=validation_dataloader,
model=model,
criterion=criterion)
metrics_history["val_loss"].append(val_metrics["loss"])
metrics_history["val_accuracy"].append(val_metrics["accuracy"])
metrics_history["val_tp"].append(val_metrics["tp"])
metrics_history["val_tn"].append(val_metrics["tn"])
metrics_history["val_fp"].append(val_metrics["fp"])
metrics_history["val_fn"].append(val_metrics["fn"])
val_precision = val_metrics["tp"] / (val_metrics["tp"] + val_metrics["fp"]) if val_metrics["tp"] > 0 else 0
val_recall = val_metrics["tp"] / (val_metrics["tp"] + val_metrics["fn"]) if val_metrics["tp"] > 0 else 0
val_specificity = val_metrics["tn"] / (val_metrics["tn"] + val_metrics["fp"]) if val_metrics["tn"] > 0 else 0
val_f1 = 2*val_precision*val_recall / (val_precision + val_recall) if val_precision*val_recall > 0 else 0
metrics_history["val_precision"].append(val_precision)
metrics_history["val_recall"].append(val_recall)
metrics_history["val_f1"].append(val_f1)
metrics_history["val_specificity"].append(val_specificity)
print(" > Training/validation loss:", round(train_metrics['loss'], 4), round(val_metrics['loss'], 4))
print(" > Training/validation accuracy:", round(train_metrics['accuracy'], 4), round(val_metrics['accuracy'], 4))
print(" > Training/validation precision:", round(precision, 4), round(val_precision, 4))
print(" > Training/validation recall:", round(recall, 4), round(val_recall, 4))
print(" > Training/validation f1:", round(f1, 4), round(val_f1, 4))
print(" > Training/validation specificity:", round(specificity, 4), round(val_specificity, 4))
else:
print(" > Training loss:", round(train_metrics['loss'], 4))
print(" > Training accuracy:", round(train_metrics['accuracy'], 4))
print(" > Training precision:", round(precision, 4))
print(" > Training recall:", round(recall, 4))
print(" > Training f1:", round(f1, 4))
print(" > Training specificity:", round(specificity, 4))
print("Completed in:", round(time.time() - start, 1), "seconds \n")
print("Training completed in:", round((time.time()- train_begin)/60, 1), "minutes")
# Save the model weights
torch.save(model.state_dict(), './nnet_model.pt')
# Save the metrics history
torch.save(metrics_history, 'training_history')
And here is the function that initializes the model and set the seeds, called before each execution of the code of "_run":
def reinit_model():
torch.manual_seed(42)
np.random.seed(42)
random.seed(42)
net = Net() # the model
return net
Ok, I found the issue.
The problem is determined by the fact that, apparently, running the evaluation some random seeds are changed, and this affects the training phase.
The solution is thus as follows:
at the beginning of function "_run()", set all seeds states to the desired value, e.g., 42. Then, save those seeds to disk.
at the beginning of function "train_fn()", read the seeds states from disk, and set them
at the end of function "train_fn()", save the seeds states to disk
For instance, running on TPU with XLA, the following instructions have to be used:
at the beginning of function "_run()": xm.set_rng_state(42), xm.save(xm.get_rng_state(), 'xm_seed')
at the beginning of function "train_fn()": xm.set_rng_state(torch.load('xm_seed'), device=device) (you can also print here the seed for verification purposes with xm.master_print(xm.get_rng_state())
at the end of function "train_fn_()": xm.save(xm.get_rng_state(), 'xm_seed')

python pygame (scroll camera with player) [duplicate]

This question already has answers here:
Add scrolling to a platformer in pygame
(4 answers)
Closed last month.
I am using pygame framework to implement my game in Python. Below is my code.
I do not know how to properly ask questions at StackOverflow, so I have included the whole program so that you can see all the details.
I would like to have a camera that would follow my player, but I do not know how to do that.
Could you, please, help me?
import pygame
pygame.init()
class Oyun():
def __init__(self):
self.x = 20
pygame.display.set_caption("Cabbar_Oyunda_Vol01")
self.uzunluk = 1280
self.genişlik = 800
self.pencere = pygame.display.set_mode((self.uzunluk, self.genişlik))
self.area = self.uzunluk * self.genişlik
self.clock = pygame.time.Clock()
self.adam = pygame.image.load("R8E.png")
self.bg = pygame.image.load("mountains.png").convert()
self.bgWidth, self.bgHeight = self.bg.get_rect().size
self.stageWidth = self.bgWidth * 2
self.stagePosX=0
self.startScrollingPosX=self.uzunluk/2
self.circleRadius=25
self.circlePosX=self.circleRadius
self.playerPosX = self.circleRadius
self.playerPosY = 685
self.playerVelocityX = 0
self.right = False
self.left = False
self.walkLeft = [pygame.image.load('L1.png'), pygame.image.load('L2.png'), pygame.image.load("L3.png"), pygame.image.load('L4.png'), pygame.image.load('L5.png'), pygame.image.load('L6.png'), pygame.image.load('L7.png'), pygame.image.load('L8.png'), pygame.image.load('L9.png')]
self.walkRight = [pygame.image.load('R1.png'), pygame.image.load('R2.png'), pygame.image.load('R3.png'), pygame.image.load('R4.png'), pygame.image.load('R5.png'), pygame.image.load('R6.png'), pygame.image.load('R7.png'), pygame.image.load('R8.png'),pygame.image.load('R9.png')]
self.walkCount=0
self.canavar_left=[pygame.image.load("L1E.png"),pygame.image.load("L2E.png"),pygame.image.load("L3E.png"),pygame.image.load("L4E.png"),pygame.image.load("L5E.png"),pygame.image.load("L6E.png"),pygame.image.load("L7E.png"),pygame.image.load("L8E.png"),pygame.image.load("L9E.png")]
self.canavar_right = [pygame.image.load("R1E.png"), pygame.image.load("R2E.png"), pygame.image.load("R3E.png"),pygame.image.load("R4E.png"), pygame.image.load("R5E.png"), pygame.image.load("R6E.png"),pygame.image.load("R7E.png"), pygame.image.load("R8E.png"), pygame.image.load("R9E.png")]
self.c_walkount=0
self.isJump = False
self.jumpCount = 10
self.sayac=0
self.yorgunluk_x=70
self.font=pygame.font.SysFont("Arial",17)
self.mermi=pygame.image.load("bullet.png")
self.mermi_x=0
self.mermi_y=0
self.mermi_stage="ready"
self.deneme=pygame.image.load("bg.jpg")
self.a = self.stagePosX + 1300
self.canavar=False
pygame.mixer.music.load("background.wav")
pygame.mixer.music.play(-1)
self.yon=1
self.scroll=[0,0]
def move(self):
self.clock.tick(40)
if self.walkCount + 1 >= 27:
self.walkCount = 0
if self.right:
self.pencere.blit(self.walkRight[self.walkCount // 3], (self.circlePosX, self.playerPosY))
self.walkCount += 1
elif self.left:
self.pencere.blit(self.walkLeft[self.walkCount // 3], (self.circlePosX, self.playerPosY))
self.walkCount += 1
else:
self.pencere.blit(self.walkRight[0], (self.circlePosX, self.playerPosY))
if self.canavar:
if self.a>1400 or self.a<1200:
self.yon*=-1
self.a += 2 * self.yon
def fire_bullet(self,circlePosX,playerPosY):
self.mermi_stage="fire"
self.pencere.blit(self.mermi,(circlePosX+40,playerPosY+20))
def kontrol(self):
keys=pygame.key.get_pressed()
if keys[pygame.K_SPACE]:
if self.mermi_stage is "ready":
self.mermi_x=self.circlePosX
self.mermi_y=self.playerPosY
self.fire_bullet(self.mermi_x,self.mermi_y)
self.mermi_ses = pygame.mixer.Sound("laser.wav")
self.mermi_ses.play()
if self.mermi_stage is "fire":
self.fire_bullet(self.mermi_x,self.mermi_y)
self.mermi_x+=18
if self.mermi_x>=1280:
self.mermi_x=self.circlePosX
self.mermi_stage="ready"
self.pencere.blit(self.adam, (self.a, 685))
def Game(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
return "son"
self.pencere.blit(self.bg, (0, 0))
keys = pygame.key.get_pressed()
if keys[pygame.K_RIGHT]:
self.left = False
self.right = True
self.circlePosX += 5
elif keys[pygame.K_LEFT]:
self.left = True
self.right = False
self.circlePosX=-5
if not (self.isJump):
if keys[pygame.K_UP]:
self.isJump = True
self.left = False
self.right = True
self.walkCount = 0
self.sayac += 1
else:
if self.jumpCount >= -10:
self.playerPosY -= (self.jumpCount * abs(self.jumpCount)) * 0.5
self.jumpCount -= 1
else:
self.jumpCount = 10
self.isJump = False
self.canavar=True
self.move()
self.kontrol()
pygame.display.update()
Game = Oyun()
while True:
Durum = Game.Game()
if Durum == "son":
break
A simple(but not most efficient) way to do this would be to move the background and all other assets, while keeping the player stationary.
# insert code in each object in background/assets
if right:
OBJECT.right() # code to change location
if left:
OBJECT.left() #code to change location
Also, off-topic, but it is easier to have a single direction variable with -1 for left, 0 for stationary, and 1 for right. You can also easily add speed to this, too, so keep this in mind and implement it if you can.

Pytorch:Apply cross entropy loss with custom weight map

I am solving multi-class segmentation problem using u-net architecture in pytorch.
As specified in U-NET paper, I am trying to implement custom weight maps to counter class imbalances.
Below is the opertion which I want to apply -
Also, I reduced the batch_size=1 so that I can remove that dimension while passing it to precompute_to_masks function.
I tried the below approach-
def precompute_for_image(masks):
masks = masks.cpu()
cls = masks.unique()
res = torch.stack([torch.where(masks==cls_val, torch.tensor(1), torch.tensor(0)) for cls_val in cls])
return res
def train(n_epochs, loaders, model, optimizer, criterion, use_cuda, save_path):
###################
# train the model #
###################
model.train()
for batch_idx, (data, target) in enumerate(final_train_loader):
# move to GPU
if use_cuda:
data, target = data.cuda(), target.cuda()
optimizer.zero_grad()
output = model(data)
temp_target = precompute_for_image(target)
w = weight_map(temp_target)
loss = criterion(output,target)
loss = w*loss
loss.backward()
optimizer.step()
train_loss = train_loss + ((1 / (batch_idx + 1)) * (loss.data - train_loss))
return model
where weight_map is the function to calculate weight mask which I got from here
The issue, I am facing is I am getting memory error when I apply the following method. I am using 61gb RAM and Tesla V100 GPU.
I really think I am applying it in incorrect way.
How to do it?
I am omitting the non-essential details from the training loop.
Below is my weight_map function:
from skimage.segmentation import find_boundaries
w0 = 10
sigma = 5
def make_weight_map(masks):
"""
Generate the weight maps as specified in the UNet paper
for a set of binary masks.
Parameters
----------
masks: array-like
A 3D array of shape (n_masks, image_height, image_width),
where each slice of the matrix along the 0th axis represents one binary mask.
Returns
-------
array-like
A 2D array of shape (image_height, image_width)
"""
nrows, ncols = masks.shape[1:]
masks = (masks > 0).astype(int)
distMap = np.zeros((nrows * ncols, masks.shape[0]))
X1, Y1 = np.meshgrid(np.arange(nrows), np.arange(ncols))
X1, Y1 = np.c_[X1.ravel(), Y1.ravel()].T
for i, mask in enumerate(masks):
# find the boundary of each mask,
# compute the distance of each pixel from this boundary
bounds = find_boundaries(mask, mode='inner')
X2, Y2 = np.nonzero(bounds)
xSum = (X2.reshape(-1, 1) - X1.reshape(1, -1)) ** 2
ySum = (Y2.reshape(-1, 1) - Y1.reshape(1, -1)) ** 2
distMap[:, i] = np.sqrt(xSum + ySum).min(axis=0)
ix = np.arange(distMap.shape[0])
if distMap.shape[1] == 1:
d1 = distMap.ravel()
border_loss_map = w0 * np.exp((-1 * (d1) ** 2) / (2 * (sigma ** 2)))
else:
if distMap.shape[1] == 2:
d1_ix, d2_ix = np.argpartition(distMap, 1, axis=1)[:, :2].T
else:
d1_ix, d2_ix = np.argpartition(distMap, 2, axis=1)[:, :2].T
d1 = distMap[ix, d1_ix]
d2 = distMap[ix, d2_ix]
border_loss_map = w0 * np.exp((-1 * (d1 + d2) ** 2) / (2 * (sigma ** 2)))
xBLoss = np.zeros((nrows, ncols))
xBLoss[X1, Y1] = border_loss_map
# class weight map
loss = np.zeros((nrows, ncols))
w_1 = 1 - masks.sum() / loss.size
w_0 = 1 - w_1
loss[masks.sum(0) == 1] = w_1
loss[masks.sum(0) == 0] = w_0
ZZ = xBLoss + loss
return ZZ
Traceback of the error-
MemoryError Traceback (most recent call last)
<ipython-input-30-f0a595b8de7e> in <module>
1 # train the model
2 model_scratch = train(20, final_train_loader, unet, optimizer,
----> 3 criterion, train_on_gpu, 'model_scratch.pt')
<ipython-input-29-b481b4f3120e> in train(n_epochs, loaders, model, optimizer, criterion, use_cuda, save_path)
24 loss = criterion(output,target)
25 target.requires_grad = False
---> 26 w = make_weight_map(target)
27 loss = W*loss
28 loss.backward()
<ipython-input-5-e75a6281476f> in make_weight_map(masks)
33 X2, Y2 = np.nonzero(bounds)
34 xSum = (X2.reshape(-1, 1) - X1.reshape(1, -1)) ** 2
---> 35 ySum = (Y2.reshape(-1, 1) - Y1.reshape(1, -1)) ** 2
36 distMap[:, i] = np.sqrt(xSum + ySum).min(axis=0)
37 ix = np.arange(distMap.shape[0])
MemoryError:
Your final_train_loader provides you with an input image data and the expected pixel-wise labeling target. I assume (following pytorch's conventions) that data is of shape B-3-H-W and of dtype=torch.float.
More importantly, target is of shape B-H-W and of dtype=torch.long.
On the other hand make_weight_map expects its input to be C-H-W (with C = number of classes, NOT batch size), of type numpy array.
Try providing make_weight_map the input mask as it expects it and see if you get similar errors.
I also recommend that you visualize the resulting weight map - to make sure your function does what you expect it to do.