SE 2811 Lab 5:
Decorated Networks
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
assumes the input is on the left and the output on the right. If this is a
classification network, the rightmost, top circle could indicate the
probability a picture is an image is of a cat and the rightmost,
bottom circle could indicate the probability a picture is an image of a dog.
This particular network can be divided into four distinct layers:
The middle two layers are known as "hidden layers". A deep neural network
contains many hidden layers.
We are giving you a starting point for this
lab: msoe-se2811-2021-lab5.zip
. 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.
Approach
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:
The second layer is drawn by
decorating the first layer by adding
three circles and the associated connectors. This is illustrated in the following
pair of images. These show extending three layers into four:
In the image on the left, the program has drawn the initial layer
(five circles) and applied the decorator twice to construct the sub-network
shown in black. The purple shows extending the network by adding another
decoration (that is, another layer). The result will be the network shown
on the right. (Note that your solution will not show the dotted boxes or
the notes; these are just to help see how the network is structured.)
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
shows two cases for adding a fully-connected layer, one with five nodes
and one with just three.
- 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.
Drawing the network
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" 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 providing information about
the added nodes so that later layers can determine where to
draw their connectors.
- Once you have a minimal solution diagram sketch, you are probably
ready to start your JavaFX implementation. Some notes on this
implementation:
- A reasonably sized network (say, one less than 10 layers with no
more than 10 nodes in a layer) should fit on a 700 by 900 pixel
screen. This may seem like a small area, but remember that when we are
grading we must have room to view your output and write comments.
- Ensure you use named constants to determine the relative placement
of network nodes and connectors! You should be able to adjust all of
the sizes with just a few changes.
- Each layer must be vertically symmetrical about the center of the
window. That is, you should be able to draw a horizontal line and have
the lower half mirror the upper half.
- The distance of each layer from the left-hand side of the window
will be determined by the number of other layers to that layer's left.
- In addition to the classes used to draw the network,
implement a driver class (called from the controller) that
draws the following, three different types
of networks. You will likely want to start by drawing just a simple,
two-layer network and extending this as you implement the rest of the system.
The required types of networks are
- AlexNet: a network with the following layers:
- An identity layer with four nodes
- A 1x1 convolutional layer
- A 1x1 convolutional layer
- A fully-connected layer with four nodes
- A fully-connected layer with three nodes
The last layer with the three nodes is the output layer.
Implement this in the method createAlexNet()
.
- Inception: a network with the following layers:
- An identity layer with three nodes
- A 1x1 convolutional layer
- A 1x1 convolutional layer
- A 1x1 convolutional layer (forming the output layer)
Implement this in the method createInception()
.
- 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. The
quality of your testing (as implemented in this network) will affect your
grade.
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 these methods and any associated constants. They should NOT be a
responsibility of the controller.
Note that these examples represent client code using your
decorator classes to construct desired networks.
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.
Submission
You will submit two items:
- A contract-level diagram (drawn using Enterprise Architect)
illustrating your system in full detail. See
the UML Standards document for the
description of this diagram. Note that it is not a
reverse-engineered diagram.
- Source code of your implementation. Ensure you meet the appropriate
coding standards.
Directions on submitting these materials will be available in Canvas.
Just for fun
If you are interested, you might consider implementing additional
layers:
- nx1 convolutional layers: nodes are connected to a fixed number
of nodes in the previous layer (rather than all nodes). Client code must
specify the number of nodes to connect to and the number of nodes in thelayer.
- dropout layers: similar to a 1x1
convolutional layer but with each input node directly connected to an
output node. The key difference is that instead of each connection
having its own weight, all the connections have a weight of 1, and
others are removed from the network. So some of the edges are randomly
not drawn. (Which edges are dropped out changes over time, so you could
pick a random set and draw some of the edges in a lighter color to indicate
they have been dropped out.