[recommend] I think you can use nn.ModuleList instead of exec.
example:
# function __init__
self.hidden_list = nn.ModuleList()
for h in range(len(hidden_size) - 1):
    self.hidden_list.append(nn.Linear(self.hidden_size[h], self.hidden_size[h + 1]))

# function forward
for module in self.hidden_list:
    x = module(x)
    x = self.relu(x)


m = list(your_module) then nn.Sequential(*m) is also a good choice.
example:
# function __init__
module_list = list()
for h in range(len(hidden_size) - 1):
    module_list.append(nn.Linear(self.hidden_size[h], self.hidden_size[h + 1]))
    module_list.append(nn.ReLU())
self.hidden_list = nn.Sequential(*module_list)

# function forward
x = self.hidden_list(x)


self.add_module will also work.
example:
# function __init__
for h in range(len(hidden_size) - 1):
    self.add_module("hidden{h}".format(h), nn.Linear(hidden_size[h], hidden_size[h + 1])

# functin forward
for h in range(len(self.hidden_size) - 1):
    x = eval("self.hidden{h}(x)".format(h))