-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor MLP #3257
Refactor MLP #3257
Changes from 12 commits
fba9e38
964ef4e
8ab2bf3
4fff5c8
2eb100c
a7e495e
168f7fc
87c8c8c
0530a76
2d0a71b
28c1f0e
0efe533
8126ce5
65ec220
d10752f
a320178
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,68 +25,69 @@ class MultilayerPerceptron(nn.Module): | |
|
||
Examples | ||
-------- | ||
>>> model = MultilayerPerceptron(d_input=10, d_hidden=3, n_layers=2, d_output=2, dropout=0.0, activation_fn='relu') | ||
>>> model = MultilayerPerceptron(d_input=10, d_hidden=(2,3), d_output=2, dropout=0.0, activation_fn='relu') | ||
>>> x = torch.ones(2, 10) | ||
>>> out = model(x) | ||
>>> print(out.shape) | ||
torch.Size([2, 2]) | ||
|
||
""" | ||
|
||
def __init__(self, | ||
d_input: int, | ||
d_hidden: int, | ||
n_layers: int, | ||
d_output: int, | ||
d_hidden: Optional[tuple] = None, | ||
dropout: float = 0.0, | ||
activation_fn: ActivationFn = 'relu'): | ||
activation_fn: ActivationFn = 'relu', | ||
skip_connection: bool = False): | ||
"""Initialize the model. | ||
|
||
Parameters | ||
---------- | ||
d_input: int | ||
the dimension of the input layer | ||
d_hidden: int | ||
the dimension of the hidden layers | ||
n_layers: int | ||
the number of hidden layers | ||
d_output: int | ||
the dimension of the output layer | ||
d_hidden: tuple | ||
the dimensions of the hidden layers | ||
dropout: float | ||
the dropout probability | ||
activation_fn: str | ||
the activation function to use in the hidden layers | ||
skip_connection: bool | ||
whether to add a skip connection from the input to the output | ||
""" | ||
super(MultilayerPerceptron, self).__init__() | ||
self.input_layer = nn.Linear(d_input, d_hidden) | ||
self.hidden_layer = nn.Linear(d_hidden, d_hidden) | ||
self.output_layer = nn.Linear(d_hidden, d_output) | ||
self.dropout = nn.Dropout(dropout) | ||
self.n_layers = n_layers | ||
self.d_input = d_input | ||
self.d_hidden = d_hidden | ||
self.d_output = d_output | ||
self.dropout = nn.Dropout(dropout) | ||
self.activation_fn = get_activation(activation_fn) | ||
self.model = nn.Sequential(*self.build_layers()) | ||
self.skip = nn.Linear(d_input, d_output) if skip_connection else None | ||
|
||
def build_layers(self): | ||
layer_list = [] | ||
layer_dim = self.d_input | ||
if self.d_hidden is not None: | ||
for d in self.d_hidden: | ||
layer_list.append(nn.Linear(layer_dim, d)) | ||
layer_list.append(self.dropout) | ||
layer_dim = d | ||
layer_list.append(nn.Linear(layer_dim, self.d_output)) | ||
return layer_list | ||
|
||
def forward(self, x: Tensor) -> Tensor: | ||
"""Forward pass of the model.""" | ||
|
||
if not self.n_layers: | ||
return x | ||
|
||
if self.n_layers == 1: | ||
x = self.input_layer(x) | ||
x = self.activation_fn(x) | ||
input = x | ||
for layer in self.model: | ||
x = layer(x) | ||
if isinstance(layer, nn.Linear): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe better to add the activations into the sequential model directly? Is this style off adding activations via a loop standard elsewhere? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we do that, we will have to use the torch activations instead of the deepchem activations, since you cannot make a sequential model with anything but nn.modules. |
||
x = self.activation_fn(x) | ||
if self.skip is not None: | ||
return x + self.skip(input) | ||
else: | ||
return x | ||
|
||
x = self.input_layer(x) | ||
x = self.activation_fn(x) | ||
for i in range(self.n_layers - 1): | ||
x = self.hidden_layer(x) | ||
x = self.dropout(x) | ||
x = self.activation_fn(x) | ||
x = self.output_layer(x) | ||
return x | ||
|
||
|
||
class CNNModule(nn.Module): | ||
"""A 1, 2, or 3 dimensional convolutional network for either regression or classification. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a docstring here?