Skip to content

Commit 8a188d1

Browse files
committed
Added convnet support, modified files in code/ folder
1 parent bebbb4a commit 8a188d1

File tree

9 files changed

+165
-62
lines changed

9 files changed

+165
-62
lines changed
1.66 KB
Binary file not shown.
0 Bytes
Binary file not shown.

code/convnet.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# reference: https://github.com/ksengin/active-target-localization/blob/master/target_localization/models/convnet.py
2+
import os
3+
4+
import torch
5+
import torch.nn as nn
6+
import torch.nn.init as init
7+
import torch.nn.functional as F
8+
import torchvision
9+
10+
11+
def _init_weights(module: nn.Module):
12+
if type(module) == nn.Linear:
13+
torch.nn.init.xavier_uniform(module.weight)
14+
module.bias.data.fill_(0.01)
15+
16+
17+
class ConvNet(nn.Module):
18+
"""
19+
The ConvNet class defines a convolutional neural net with a desired output dimension.
20+
"""
21+
22+
def __init__(self, out_dim: int = 128, pretrained=True):
23+
"""
24+
Create a convolutional network.
25+
"""
26+
super(ConvNet, self).__init__()
27+
28+
self.act_fn = F.relu
29+
self.model_ft = torchvision.models.resnet34(pretrained=pretrained)
30+
self.model_ft.conv1 = nn.Conv2d(1, 64, kernel_size=7, stride=2, padding=3, bias=False)
31+
num_ftrs = self.model_ft.fc.out_features
32+
33+
self.model_ft.apply(_init_weights)
34+
self.fc1 = nn.Linear(num_ftrs, num_ftrs)
35+
self.fc2 = nn.Linear(num_ftrs, num_ftrs)
36+
self.fc3 = nn.Linear(num_ftrs, out_dim)
37+
38+
39+
def forward(self, x: torch.tensor):
40+
x = self.act_fn(self.model_ft(x))
41+
x = self.act_fn(self.fc1(x))
42+
x = self.act_fn(self.fc2(x))
43+
fc_out = self.fc3(x)
44+
return fc_out
Binary file not shown.

code/envs/convnet.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# reference: https://github.com/ksengin/active-target-localization/blob/master/target_localization/models/convnet.py
2+
import os
3+
4+
import torch
5+
import torch.nn as nn
6+
import torch.nn.init as init
7+
import torch.nn.functional as F
8+
import torchvision
9+
10+
11+
def _init_weights(module: nn.Module):
12+
if type(module) == nn.Linear:
13+
torch.nn.init.xavier_uniform(module.weight)
14+
module.bias.data.fill_(0.01)
15+
16+
17+
class ConvNet(nn.Module):
18+
"""
19+
The ConvNet class defines a convolutional neural net with a desired output dimension.
20+
"""
21+
22+
def __init__(self, out_dim: int = 128, pretrained=False):
23+
"""
24+
Create a convolutional network.
25+
"""
26+
super(ConvNet, self).__init__()
27+
28+
self.act_fn = F.relu
29+
self.model_ft = torchvision.models.resnet34(pretrained=pretrained)
30+
self.model_ft.conv1 = nn.Conv2d(1, 64, kernel_size=7, stride=2, padding=3, bias=False)
31+
num_ftrs = self.model_ft.fc.out_features
32+
33+
self.model_ft.apply(_init_weights)
34+
self.fc1 = nn.Linear(num_ftrs, num_ftrs)
35+
self.fc2 = nn.Linear(num_ftrs, num_ftrs)
36+
self.fc3 = nn.Linear(num_ftrs, out_dim)
37+
38+
39+
def forward(self, x: torch.tensor):
40+
x = self.act_fn(self.model_ft(x))
41+
x = self.act_fn(self.fc1(x))
42+
x = self.act_fn(self.fc2(x))
43+
fc_out = self.fc3(x)
44+
return fc_out

code/envs/robot_target_tracking_env.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import matplotlib.transforms as transforms
2525
from math import pi, cos, sin
2626
from scipy.stats import multivariate_normal
27+
from convnet import *
2728

2829

2930
# OpenAI gym environment class
@@ -41,11 +42,7 @@ def __init__(self):
4142
self.time_step = 1
4243

4344
self.action_space = spaces.Box(-np.pi, np.pi, shape=(1,), dtype='float32')
44-
45-
#self.model = torchvision.models.resnet50(pretrained=True)
46-
#self.model.conv1 = nn.Conv2d(1, 64, kernel_size=7, stride=2, padding=3, bias=False)
47-
#self.model.fc = torch.nn.Linear(2048, 128)
48-
#self.model.to(self.device)
45+
self.convnet = ConvNet()
4946

5047

5148
def env_parametrization(self, num_targets=4, num_sensors=1, target_motion_omegas=None, meas_model='range'):
@@ -80,7 +77,9 @@ def env_parametrization(self, num_targets=4, num_sensors=1, target_motion_omegas
8077
pos[:, :, 0] = X; pos[:, :, 1] = Y
8178
rv = multivariate_normal(self.estimated_targets_mean[index], self.estimated_targets_var[index])
8279
self.heatmap += rv.pdf(pos)
83-
true_obs = self.heatmap.flatten()
80+
image = F.interpolate(self.heatmap, (256, 256), mode='bilinear')
81+
true_obs = self.convnet(image).squeeze()
82+
#true_obs = self.heatmap.flatten()
8483

8584
self.robot_movement_x = []
8685
self.robot_movement_y = []

code/envs/robot_target_tracking_env_sensors.py

Lines changed: 69 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import matplotlib.transforms as transforms
2525
from math import pi, cos, sin
2626
from scipy.stats import multivariate_normal
27+
from convnet import *
2728

2829

2930
# OpenAI gym environment class
@@ -41,14 +42,10 @@ def __init__(self):
4142
self.time_step = 1
4243

4344
self.action_space = spaces.Box(-np.pi, np.pi, shape=(1,), dtype='float32')
45+
self.convnet = ConvNet()
4446

45-
#self.model = torchvision.models.resnet50(pretrained=True)
46-
#self.model.conv1 = nn.Conv2d(1, 64, kernel_size=7, stride=2, padding=3, bias=False)
47-
#self.model.fc = torch.nn.Linear(2048, 128)
48-
#self.model.to(self.device)
4947

50-
51-
def env_parametrization(self, num_targets=1, num_sensors=2, target_motion_omegas=None, meas_model='range'):
48+
def env_parametrization(self, num_targets=4, num_sensors=2, target_motion_omegas=None, meas_model='range'):
5249
"""
5350
Function for parametrizing the environment
5451
"""
@@ -64,11 +61,15 @@ def env_parametrization(self, num_targets=1, num_sensors=2, target_motion_omegas
6461
self.num_targets = num_targets
6562
self.true_targets_radii = torch.rand(self.num_targets)*5.0+2.0
6663
self.true_targets_pos = (torch.rand(self.num_targets, 2)*self.len_workspace)
67-
self.true_targets_pos[0, 0] = 14
68-
self.true_targets_pos[0, 1] = 8
69-
self.true_const = np.random.uniform(low=9, high=19, size=(1,))[0]
64+
#self.true_targets_pos[0, 0] = 14
65+
#self.true_targets_pos[0, 1] = 8
66+
#self.true_targets_pos[1, 0] = 6
67+
#self.true_targets_pos[1, 1] = 6
68+
#self.true_const_1 = np.random.uniform(low=9, high=19, size=(1,))[0]
7069
#self.true_const = 14
71-
self.true_slope = (self.true_targets_pos[0, 1]-self.true_const)/self.true_targets_pos[0, 0]
70+
#self.true_slope_1 = (self.true_targets_pos[0, 1]-self.true_const_1)/self.true_targets_pos[0, 0]
71+
#self.true_const_2 = np.random.uniform(low=2, high=5, size=(1,))[0]
72+
#self.true_slope_2 = (self.true_targets_pos[1, 1]-self.true_const_2)/self.true_targets_pos[1, 0]
7273
self.initial_true_targets_pos = self.true_targets_pos.clone()
7374
self.estimated_targets_mean = self.true_targets_pos.clone()
7475
self.estimated_targets_var = torch.zeros(self.num_targets, 2, 2)
@@ -85,7 +86,10 @@ def env_parametrization(self, num_targets=1, num_sensors=2, target_motion_omegas
8586
pos[:, :, 0] = X; pos[:, :, 1] = Y
8687
rv = multivariate_normal(self.estimated_targets_mean[index], self.estimated_targets_var[index])
8788
self.heatmap += rv.pdf(pos)
88-
true_obs = self.heatmap.flatten()
89+
image = F.interpolate(self.heatmap.unsqueeze(0).unsqueeze(0), (256, 256), mode='bilinear', align_corners=True)
90+
image = image.float()
91+
true_obs = self.convnet(image).squeeze()
92+
#true_obs = self.heatmap.flatten()
8993

9094
self.robot_movement_x_1 = []
9195
self.robot_movement_y_1 = []
@@ -108,10 +112,10 @@ def env_parametrization(self, num_targets=1, num_sensors=2, target_motion_omegas
108112
self.sensors_pos[index, 1] -= (self.sensors_pos[index, 1]-self.len_workspace+1)
109113
if(self.sensors_pos[index, 1]<=0):
110114
self.sensors_pos[index, 1] = (-self.sensors_pos[index, 1]+1)
111-
self.sensors_pos[0, 0] = 18
112-
self.sensors_pos[0, 1] = 14
113-
self.sensors_pos[1, 0] = 18
114-
self.sensors_pos[1, 1] = 12
115+
#self.sensors_pos[0, 0] = 18
116+
#self.sensors_pos[0, 1] = 14
117+
#self.sensors_pos[1, 0] = 18
118+
#self.sensors_pos[1, 1] = 12
115119

116120
self.robot_movement_x_1.append(float(self.sensors_pos[0, 0]))
117121
self.robot_movement_y_1.append(float(self.sensors_pos[0, 1]))
@@ -123,12 +127,12 @@ def env_parametrization(self, num_targets=1, num_sensors=2, target_motion_omegas
123127
#self.robot_movement_y_4.append(float(self.sensors_pos[3, 1]))
124128
self.x1_list.append(float(self.true_targets_pos[0, 0]))
125129
self.y1_list.append(float(self.true_targets_pos[0, 1]))
126-
#self.x2_list.append(float(self.true_targets_pos[1, 0]))
127-
#self.y2_list.append(float(self.true_targets_pos[1, 1]))
128-
#self.x3_list.append(float(self.true_targets_pos[2, 0]))
129-
#self.y3_list.append(float(self.true_targets_pos[2, 1]))
130-
#self.x4_list.append(float(self.true_targets_pos[3, 0]))
131-
#self.y4_list.append(float(self.true_targets_pos[3, 1]))
130+
self.x2_list.append(float(self.true_targets_pos[1, 0]))
131+
self.y2_list.append(float(self.true_targets_pos[1, 1]))
132+
self.x3_list.append(float(self.true_targets_pos[2, 0]))
133+
self.y3_list.append(float(self.true_targets_pos[2, 1]))
134+
self.x4_list.append(float(self.true_targets_pos[3, 0]))
135+
self.y4_list.append(float(self.true_targets_pos[3, 1]))
132136

133137
self.meas_model = meas_model
134138
if self.meas_model == 'bearing':
@@ -137,7 +141,6 @@ def env_parametrization(self, num_targets=1, num_sensors=2, target_motion_omegas
137141
else:
138142
self.sigma_meas = 1.0
139143
self.normal_dist_1d_torch = lambda x, mu, sgm: 1.0/(np.sqrt(2*np.pi*sgm**2))*np.exp(-0.5/sgm**2*(np.abs(x-mu)**2))
140-
141144
self.state = torch.cat((self.sensors_pos[0], self.sensors_pos[1], torch.tensor(true_obs).float()))
142145
self.observation_space = spaces.Box(-np.inf, np.inf, shape=self.state.shape, dtype='float32')
143146

@@ -162,12 +165,12 @@ def step(self, action, step_size):
162165
#self.robot_movement_y_4.append(float(self.sensors_pos[3, 1]))
163166
self.x1_list.append(float(self.true_targets_pos[0, 0]))
164167
self.y1_list.append(float(self.true_targets_pos[0, 1]))
165-
#self.x2_list.append(float(self.true_targets_pos[1, 0]))
166-
#self.y2_list.append(float(self.true_targets_pos[1, 1]))
167-
#self.x3_list.append(float(self.true_targets_pos[2, 0]))
168-
#self.y3_list.append(float(self.true_targets_pos[2, 1]))
169-
#self.x4_list.append(float(self.true_targets_pos[3, 0]))
170-
#self.y4_list.append(float(self.true_targets_pos[3, 1]))
168+
self.x2_list.append(float(self.true_targets_pos[1, 0]))
169+
self.y2_list.append(float(self.true_targets_pos[1, 1]))
170+
self.x3_list.append(float(self.true_targets_pos[2, 0]))
171+
self.y3_list.append(float(self.true_targets_pos[2, 1]))
172+
self.x4_list.append(float(self.true_targets_pos[3, 0]))
173+
self.y4_list.append(float(self.true_targets_pos[3, 1]))
171174

172175
self.heatmap = torch.zeros(self.len_workspace, self.len_workspace)
173176
for index in range(0, self.num_targets):
@@ -178,7 +181,10 @@ def step(self, action, step_size):
178181
pos[:, :, 0] = X; pos[:, :, 1] = Y
179182
rv = multivariate_normal(self.estimated_targets_mean[index], self.estimated_targets_var[index])
180183
self.heatmap += rv.pdf(pos)
181-
true_obs = self.heatmap.flatten()
184+
image = F.interpolate(self.heatmap.unsqueeze(0).unsqueeze(0), (256, 256), mode='bilinear', align_corners=True)
185+
image = image.float()
186+
true_obs = self.convnet(image).squeeze()
187+
#true_obs = self.heatmap.flatten()
182188

183189
done = False
184190
reward = None
@@ -206,11 +212,15 @@ def reset(self, **kwargs):
206212
self.time_step = 1
207213
self.true_targets_radii = torch.rand(self.num_targets)*5.0+2.0
208214
self.true_targets_pos = (torch.rand(self.num_targets, 2)*self.len_workspace)
209-
self.true_targets_pos[0, 0] = 14
210-
self.true_targets_pos[0, 1] = 8
211-
self.true_const = np.random.uniform(low=9, high=19, size=(1,))[0]
215+
#self.true_targets_pos[0, 0] = 14
216+
#self.true_targets_pos[0, 1] = 8
217+
#self.true_targets_pos[1, 0] = 6
218+
#self.true_targets_pos[1, 1] = 6
219+
#self.true_const_1 = np.random.uniform(low=9, high=19, size=(1,))[0]
212220
#self.true_const = 14
213-
self.true_slope = (self.true_targets_pos[0, 1]-self.true_const)/self.true_targets_pos[0, 0]
221+
#self.true_slope_1 = (self.true_targets_pos[0, 1]-self.true_const_1)/self.true_targets_pos[0, 0]
222+
#self.true_const_2 = np.random.uniform(low=2, high=5, size=(1,))[0]
223+
#self.true_slope_2 = (self.true_targets_pos[1, 1]-self.true_const_2)/self.true_targets_pos[1, 0]
214224
self.initial_true_targets_pos = self.true_targets_pos.clone()
215225
self.estimated_targets_mean = self.true_targets_pos.clone()
216226
self.estimated_targets_var = torch.zeros(self.num_targets, 2, 2)
@@ -238,10 +248,10 @@ def reset(self, **kwargs):
238248
self.sensors_pos[index, 1] -= (self.sensors_pos[index, 1]-self.len_workspace+1)
239249
if(self.sensors_pos[index, 1]<=0):
240250
self.sensors_pos[index, 1] = (-self.sensors_pos[index, 1]+1)
241-
self.sensors_pos[0, 0] = 18
242-
self.sensors_pos[0, 1] = 14
243-
self.sensors_pos[1, 0] = 18
244-
self.sensors_pos[1, 1] = 12
251+
#self.sensors_pos[0, 0] = 18
252+
#self.sensors_pos[0, 1] = 14
253+
#self.sensors_pos[1, 0] = 18
254+
#self.sensors_pos[1, 1] = 12
245255

246256
self.robot_movement_x_1.append(float(self.sensors_pos[0, 0]))
247257
self.robot_movement_y_1.append(float(self.sensors_pos[0, 1]))
@@ -253,12 +263,12 @@ def reset(self, **kwargs):
253263
#self.robot_movement_y_4.append(float(self.sensors_pos[3, 1]))
254264
self.x1_list.append(float(self.true_targets_pos[0, 0]))
255265
self.y1_list.append(float(self.true_targets_pos[0, 1]))
256-
#self.x2_list.append(float(self.true_targets_pos[1, 0]))
257-
#self.y2_list.append(float(self.true_targets_pos[1, 1]))
258-
#self.x3_list.append(float(self.true_targets_pos[2, 0]))
259-
#self.y3_list.append(float(self.true_targets_pos[2, 1]))
260-
#self.x4_list.append(float(self.true_targets_pos[3, 0]))
261-
#self.y4_list.append(float(self.true_targets_pos[3, 1]))
266+
self.x2_list.append(float(self.true_targets_pos[1, 0]))
267+
self.y2_list.append(float(self.true_targets_pos[1, 1]))
268+
self.x3_list.append(float(self.true_targets_pos[2, 0]))
269+
self.y3_list.append(float(self.true_targets_pos[2, 1]))
270+
self.x4_list.append(float(self.true_targets_pos[3, 0]))
271+
self.y4_list.append(float(self.true_targets_pos[3, 1]))
262272

263273
self.heatmap = torch.zeros(self.len_workspace, self.len_workspace)
264274
for index in range(0, self.num_targets):
@@ -269,7 +279,10 @@ def reset(self, **kwargs):
269279
pos[:, :, 0] = X; pos[:, :, 1] = Y
270280
rv = multivariate_normal(self.estimated_targets_mean[index], self.estimated_targets_var[index])
271281
self.heatmap += rv.pdf(pos)
272-
true_obs = self.heatmap.flatten()
282+
image = F.interpolate(self.heatmap.unsqueeze(0).unsqueeze(0), (256, 256), mode='bilinear', align_corners=True)
283+
image = image.float()
284+
true_obs = self.convnet(image).squeeze()
285+
#true_obs = self.heatmap.flatten()
273286

274287
self.state = torch.cat((self.sensors_pos[0], self.sensors_pos[1], torch.tensor(true_obs).float()))
275288
self.observation_space = spaces.Box(-np.inf, np.inf, shape=self.state.shape, dtype='float32')
@@ -308,12 +321,12 @@ def render(self):
308321
plt.contourf(X, Y, heatmap, cmap=cm.inferno)
309322
plt.plot(self.x1_list, self.y1_list, 'b--')
310323
plt.plot(self.x1_list[len(self.x1_list)-1], self.y1_list[len(self.y1_list)-1], 'o', c='b', marker='*')
311-
#plt.plot(self.x2_list, self.y2_list, 'b--')
312-
#plt.plot(self.x2_list[len(self.x2_list)-1], self.y2_list[len(self.y2_list)-1], 'o', c='b', marker='*')
313-
#plt.plot(self.x3_list, self.y3_list, 'b--')
314-
#plt.plot(self.x3_list[len(self.x3_list)-1], self.y3_list[len(self.y3_list)-1], 'o', c='b', marker='*')
315-
#plt.plot(self.x4_list, self.y4_list, 'b--')
316-
#plt.plot(self.x4_list[len(self.x4_list)-1], self.y4_list[len(self.y4_list)-1], 'o', c='b', marker='*')
324+
plt.plot(self.x2_list, self.y2_list, 'b--')
325+
plt.plot(self.x2_list[len(self.x2_list)-1], self.y2_list[len(self.y2_list)-1], 'o', c='b', marker='*')
326+
plt.plot(self.x3_list, self.y3_list, 'b--')
327+
plt.plot(self.x3_list[len(self.x3_list)-1], self.y3_list[len(self.y3_list)-1], 'o', c='b', marker='*')
328+
plt.plot(self.x4_list, self.y4_list, 'b--')
329+
plt.plot(self.x4_list[len(self.x4_list)-1], self.y4_list[len(self.y4_list)-1], 'o', c='b', marker='*')
317330
if(len(self.robot_movement_x_1)<8):
318331
plt.plot(self.robot_movement_x_1, self.robot_movement_y_1, 'r--')
319332
else:
@@ -404,12 +417,15 @@ def update_true_targets_pos(self):
404417
"""
405418
Function to update the true target positions when time step increases (assuming circular target motions)
406419
"""
407-
'''
408420
for index in range(0, self.num_targets):
409-
self.true_targets_pos[index] = torch.tensor([self.true_targets_radii[index]*np.cos((self.time_step-1)/float(self.target_motion_omegas[index]))+float(self.initial_true_targets_pos[index, 0])-self.true_targets_radii[index], self.true_targets_radii[index]*np.sin((self.time_step-1)/float(self.target_motion_omegas[index]))+float(self.initial_true_targets_pos[index, 1])])
421+
self.true_targets_pos[index] = torch.tensor([self.true_targets_radii[index]*np.cos((self.time_step-1)/float(self.target_motion_omegas[index]))+float(self.initial_true_targets_pos[index, 0])-self.true_targets_radii[index], self.true_targets_radii[index]*np.sin((self.time_step-1)/float(self.target_motion_omegas[index]))+float(self.initial_true_targets_pos[index, 1])])
410422
'''
411423
for index in range(0, self.num_targets):
412-
self.true_targets_pos[index] = torch.tensor([self.true_targets_pos[index, 0]-0.1, (self.true_slope*(self.true_targets_pos[index, 0]-0.1))+self.true_const])
424+
if index == 0:
425+
self.true_targets_pos[index] = torch.tensor([self.true_targets_pos[index, 0]-0.1, (self.true_slope_1*(self.true_targets_pos[index, 0]-0.1))+self.true_const_1])
426+
if index == 1:
427+
self.true_targets_pos[index] = torch.tensor([self.true_targets_pos[index, 0]-0.1, (self.true_slope_2*(self.true_targets_pos[index, 0]-0.1))+self.true_const_2])
428+
'''
413429

414430

415431
def update_estimated_targets_pos(self):

code/eval.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
action_dim = env.action_space.shape[0]
3939
max_action = float(env.action_space.high[0])
4040
policy = TD3(0.0005, state_dim, 4, max_action)
41-
policy.load_actor("/home/arpitdec5/Desktop/robot_target_tracking/", "sample_model_sensors_2_targets_1_3")
41+
policy.load_actor("/home/arpitdec5/Desktop/robot_target_tracking/", "sample_model_sensors_2_targets_2_1")
4242

4343
# eval loop
4444
greedy_cov = []

code/train.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@
7474

7575
# save actor-critic models
7676
if(epoch>100 and epoch%10==0):
77-
policy.save("/home/arpitdec5/Desktop/robot_target_tracking/", "sample_model_sensors_2_targets_1_1")
77+
policy.save("/home/arpitdec5/Desktop/robot_target_tracking/", "sample_model_sensors_2_targets_4")
7878

7979
# print reward
8080
print()
@@ -100,4 +100,4 @@
100100
plt.plot(m_e, m_r, c='orange', label='Mean Reward')
101101
#plt.plot(g_e, g_r, c='red', label='Greedy Algorithm')
102102
plt.legend()
103-
plt.savefig("/home/arpitdec5/Desktop/robot_target_tracking/sample_reward_sensors_2_targets_1_1.png")
103+
plt.savefig("/home/arpitdec5/Desktop/robot_target_tracking/sample_reward_sensors_2_targets_4.png")

0 commit comments

Comments
 (0)