Skip to content
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

[SYSTEMDS-3426] Python NN Builtin components #1848

Closed
wants to merge 7 commits into from

Conversation

thaivd1309
Copy link
Contributor

I added the class Affine which represents a layer in a neural network.
Also, the class Source couldn't parse the file ''affine.dml'' because it it contains the comment block " /* */ " so I fixed it

@thaivd1309 thaivd1309 changed the title SYSTEMDS-3426 Student project [SYSTEMDS-3426] Python NN Builtin components Jun 23, 2023
Copy link
Contributor

@Baunsgaard Baunsgaard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, most of the things are on the right track.

I would like to change the API a bit, to enable static calling:

This means you need to change the API in 2 ways
as an example Relu should be able to be called:

from systemds.operator.nn_nodes.relu as Relu

Relu.forward(X)
Relu.backward(X)

But we should also still be able to call the other way:

Relu().forward(X)
Relu().backward(X)

For the Affine since it have internal state i like how it is, but i still want the forward and backward static call. and internally in the class for Affine i still want the option to have the state.

Second lets change the liberary name to:

systemds.operator.nn.??

As a follow up task look at the complied plans, and figure out if the NN builtin are sourced multiple times. If they are fix this. Also add a test that verifies the compiled plans does not contain multiple sources of the same file. aka if you use affine twice or more.
To look at the compiled plans simply set the verbose flag when calling compute()

# specific language governing permissions and limitations
# under the License.
#
# -------------------------------------------------------------
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add line in end of file

_X: Matrix

def __init__(self):
self._sds_context = SystemDSContext()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not allowed since it starts up a new JVM.
just remove it and the variable for SDS.

we can on first call extract the context from the variable X on a forward or on a Backward pass.

def tearDownClass(cls):
cls.sds.close()

def test_affine(self):
Copy link
Contributor

@Baunsgaard Baunsgaard Jun 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add dedicated tests for forward for backward.
Ideally you add multiple such tests.
Then write in what you expect to get out from the operation based on a explicit input.

src/main/python/tests/nn_nodes/test_affine.py Outdated Show resolved Hide resolved
@thaivd1309
Copy link
Contributor Author

I added static methods call for Affine and ReLU. Since static call of forward and backward does not have internal states, the user needs to provide extra parameter, e.g. affine.forward(X) and Affine.forward(X, W, b).
I also made the _source object static, which means it is created only once. I believe this will make the system only import once. But for the time being I will write a test to verify this.

Copy link
Contributor

@Baunsgaard Baunsgaard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall i like it, there are 3 missing pieces for me to say that it is a pass:

  1. Test if it does not source multiple times when called multiple times in a single script, you verify this via calling compute with verbose.
  2. Verify it works across two different instance of SystemDSContext, to do this you need to start two SystemDSContext() and call into these with two different affine transforms. Note here you need to materialize an X for each of them and remember to call close on each.
  3. Make a test that verify combined behavior of multiple instructions. i suggest a simple test for a network of affine(128) relu affine(64) relu affine (32) relu affine(2). here verify again, that we do not souce multiple times, even if we call multiple different layers.

These things should be enough for both of you to pass the coding, but i would like to have seen more instructions introduced.

@rahuljo
Copy link
Contributor

rahuljo commented Jul 24, 2023

@Baunsgaard Added the new tests that we discussed. Could you please review it?

Copy link
Contributor

@Baunsgaard Baunsgaard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, this concludes your Programming assignment.

There are some minor things to improve in tests, where you move the variables to individual test cases, and please add at least one more test case with other inputs.

And I am still missing an experiment to verify behavior with multiple SDS contexts.

Before merging we need to Ensure that this API is what we want in general (more people have to indicate their opinion), i can imagine one comment that could be brought up is that the standard functions should be non static and the instance based should be renamed or moved slightly, for instance outside the class definition inside the same file.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add license (i know it is stupid, but these do need it as well.)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not like that this is part of the nn package. This should be moved to the tests.


class ReLU:
_source: Source = None
_X: Matrix
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not like that X (the input) is stored inside

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought that the input X would be used in the backward pass anyways so I stored it. But I can remove it if you wish

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you know what. You are right, lets keep it, since it is needed in backward passes


class Affine:
_source: Source = None
_X: Matrix
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, i do not like the input is stored inside.

Xm = self.sds.from_numpy(X)
Wm = self.sds.from_numpy(W)
bm = self.sds.full((1, 6), 0)
doutm = self.sds.from_numpy(dout)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not like doutm is materialized here, can we not calculate it based on a forward to backward pass.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since an error-evaluating function hasn't been implemented yet, I couldn't calculate the gradient for the backward pass. So I have to materialize the output gradient like this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then we should leave a TODO specifying to use an loss function.
But i think it should be possible to naively use the outputs of the forward call.

scripts = DMLScript(self.sds)
scripts.build_code(network_out)

self.assertEqual(1,self.count_sourcing(scripts.dml_script, layer_name="affine"))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

format, add a space after ","

@classmethod
def setUpClass(cls):
cls.sds = SystemDSContext()
cls.X = np.array([0, -1, -2, 2, 3, -5])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move this to the individual tests.

return dX

# forward = staticmethod(forward)
# backward = staticmethod(backward)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove commented code.

"""
Affine._create_source(X.sds_context)
out = Affine._source.forward(X, W, b)
return out
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

collapse these to lines to not make out on the line above.

X: input matrix
return out: output matrix
"""
self._X = X
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this.

Baunsgaard pushed a commit to Baunsgaard/systemds that referenced this pull request Oct 20, 2023
This commit adds the new interface for easy usage of our neural network
in python. The design take inspiration from other neural network
frameworks.
This specific commit contains the building blocks of Affine and Relu.

Co-authored-by: Duc Thai Vu <[email protected]>
Co-authored-by: Rahul Joshi <[email protected]>

Closes apache#1848
@Baunsgaard
Copy link
Contributor

Thanks for the PR @thaivd1309 and @rahuljo

I will take it from here, and moved the code to another PR #1929 ,
There is some bug that makes the source test work locally, but not in the cloud.

@Baunsgaard Baunsgaard closed this Oct 23, 2023
Baunsgaard pushed a commit to Baunsgaard/systemds that referenced this pull request Oct 24, 2023
This commit adds the new interface for easy usage of our neural network
in python. The design take inspiration from other neural network
frameworks.
This specific commit contains the building blocks of Affine and Relu.

Co-authored-by: Duc Thai Vu <[email protected]>
Co-authored-by: Rahul Joshi <[email protected]>

Closes apache#1848
Baunsgaard pushed a commit to Baunsgaard/systemds that referenced this pull request Apr 12, 2024
This commit adds the new interface for easy usage of our neural network
in python. The design take inspiration from other neural network
frameworks.
This specific commit contains the building blocks of Affine and Relu.

Co-authored-by: Duc Thai Vu <[email protected]>
Co-authored-by: Rahul Joshi <[email protected]>

Closes apache#1848
Baunsgaard pushed a commit to Baunsgaard/systemds that referenced this pull request Apr 15, 2024
This commit adds the new interface for easy usage of our neural network
in python. The design take inspiration from other neural network
frameworks.
This specific commit contains the building blocks of Affine and Relu.

Closes apache#1848

Co-authored-by: Duc Thai Vu <[email protected]>
Co-authored-by: Rahul Joshi <[email protected]>

...
Baunsgaard pushed a commit to Baunsgaard/systemds that referenced this pull request Apr 15, 2024
This commit adds the new interface for easy usage of our neural network
in python. The design take inspiration from other neural network
frameworks.
This specific commit contains the building blocks of Affine and Relu.

Closes apache#1848
Closes apache#1929

Co-authored-by: Duc Thai Vu <[email protected]>
Co-authored-by: Rahul Joshi <[email protected]>
Baunsgaard pushed a commit that referenced this pull request Apr 15, 2024
This commit adds the new interface for easy usage of our neural network
in python. The design take inspiration from other neural network frameworks.
This specific commit contains the building blocks of Affine and Relu.

Closes #1848
Closes #1929

Co-authored-by: Duc Thai Vu <[email protected]>
Co-authored-by: Rahul Joshi <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

3 participants