In this lab you will develop a tool using the Decorator Pattern to display feed-forward neural networks. A neural network takes data from some source such as pixels from an image or samples from an audio stream and generates a number specifying a classification of that input. A feed-forward neural network is one in which the signals enters at one end, flows through the network, and exits without looping backwards on itself. For example, the network
You will be given a starting point for this lab; your instructor will give directions on this. You will extend this into a program that draws the structure of a specified neural network. Note that you are not computing the output of the network, just drawing the network on the screen. You will use the Decorator Pattern as part of your solution.
This is an individual lab.
A starting point for drawing a feed-forward neural network is to draw the first layer. In this case, just a series of five circles:
Using decorations allows different types of network layers. For this lab, we have just two types, but the model clearly extends to others:
Fully-connected layers: each node in the layer is connected to every node in the previous layer (the layer to the immediate left). The number of nodes in the layer is specified by the rest of the system. For example, the image
1x1 convolutional layers: each node is connected to just one other node, a node to its immediate left. There is no need to specify the number of nodes in this layer since it is determined by the previous layer. For example, the following image shows a 1 by 1 convolutional network:
Good OO means that a decorated network can draw itself, including any networks it contains. Drawing a network should be recursive. You should not need a for loop drawing each layer. If you have an arraylist or other list of all layers anywhere in your solution, you are probably applying the pattern incorrectly.
You are to complete a JavaFX program drawing these type of neural networks using the Decorator Pattern. Note the domain of this assignment is drawing neural networks: code to place the nodes (circles) and draw edges between them must be in the domain classes, not the JavaFX controller class. (Putting everything in a JavaFX controller is a great example of writing a “doit” or “system” class!) The following is an ordered list for developing a solution:
Start by spending about 15 minutes drawing a class diagram capturing the domain (as described in the previous section). Be sure to include key classes, behaviors, and relationships. Do not worry at this point about marking some classes as abstract or how to apply the pattern.
Next, create a “minimal solution diagram” - one that adds classes for the pattern and removes unneeded domain classes. Although you will eventually include JavaFX components, do not include them in this diagram so that you can focus your efforts on the domain. Likewise, do not include driver code that draws a particular type of network.
As you write your minimal solution diagram, recall that a decorator both IS-A and HAS-A decorated object, so the decorator pattern classes are not domain objects in the classical sense. The decorator’s responsibilities are to extend the core object while ensuring the decorated object has the same (external) behavior as that core object. In this problem, the decorator is responsible for adding a layer of nodes with appropriate connectors. But it is also responsible for representing the entire network that is decorated.
Once you have a minimal solution diagram sketch, you are probably ready to start your JavaFX implementation. Some notes on this implementation:
In addition to the classes used to draw the network, implement the createInception()
and createAlexNet()
methods within the controller and add your own create…() method to the controller.
The createInception()
and createAlexNet()
methods should remain in the provided Controller class. These three methods construct three different networks as client code and should not be placed within any of the classes shown in your minimal solution diagram. You will likely want to start by drawing just a simple, one-layer network, extend this to a two-layer network, and continue extending this as you implement the rest of the system. The required types of networks are
AlexNet: a network, implemented in createAlexNet()
, with the following layers:
Inception: a network, implemented in createInception()
, with the following layers:
An additional network of your own design. It must be a non-trivial network that illustrates your solution can generate other, interesting networks. Explore some of the boundaries - include a number of nodes in various layers, mix convolutional layers with fully-connected layers, show what happens if you create layers with a single node, etc. Be sure to also show what happens if you create layers with more than 5 node in them, both with an even number and with an odd number of nodes in any particular layer.
Note that the provided code gives examples of how to draw edges and nodes on a JavaFX canvas. During your design stage, please decide where you will move the helper methods and any associated constants. They should not be a responsibility of the controller.
Replace this same example code with your decorator client code. Reduce the burden on this code as much as possible. It should simply nest decorators as discussed in class and should not pass information to the decorators beyond what the client absolutely must provide. Details about the layout should be determined by the decorator pattern classes instead.
For full credit, you must show arrows at the right ends of the neural network connectors (as shown in the first sample neural network at the top of this writeup). However, the penalty for not adding these arrows will be very small.
Your instructor will give submission directions. For the sections for Dr. Hasker and Dr. Thomas, start with the code se2811-decorator-lab.zip. For these sections, you will submit
See Canvas for additional directions.
If you are interested, you might consider implementing additional layers: