mirror of
https://github.com/helblazer811/ManimML.git
synced 2025-07-02 04:46:52 +08:00
Created neural network visualization and feed forward animation
This commit is contained in:
6
Makefile
Normal file
6
Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
video:
|
||||
manim -pqh src/autoencoder.py Autoencoder
|
||||
checkstyle:
|
||||
pycodestyle src
|
||||
pydocstyle src
|
||||
#docs:
|
131
src/neural_network.py
Normal file
131
src/neural_network.py
Normal file
@ -0,0 +1,131 @@
|
||||
"""Neural Network Manim Visualization
|
||||
|
||||
This module is responsible for generating a neural network visualization with
|
||||
manim, specifically a fully connected neural network diagram.
|
||||
|
||||
Example:
|
||||
# Specify how many nodes are in each node layer
|
||||
layer_node_count = [5, 3, 5]
|
||||
# Create the object with default style settings
|
||||
NeuralNetwork(layer_node_count)
|
||||
"""
|
||||
from manim import *
|
||||
|
||||
class NeuralNetworkLayer(VGroup):
|
||||
"""Handles rendering a layer for a neural network"""
|
||||
|
||||
def __init__(
|
||||
self, num_nodes, layer_width=0.3, node_radius=0.2,
|
||||
node_color=BLUE, node_outline_color=WHITE, rectangle_color=WHITE,
|
||||
node_spacing=0.6, rectangle_fill_color=BLACK):
|
||||
super(VGroup, self).__init__()
|
||||
self.num_nodes = num_nodes
|
||||
self.layer_width = layer_width
|
||||
self.node_radius = node_radius
|
||||
self.node_color = node_color
|
||||
self.node_outline_color = node_outline_color
|
||||
self.rectangle_color = rectangle_color
|
||||
self.node_spacing = node_spacing
|
||||
self.rectangle_fill_color = rectangle_fill_color
|
||||
|
||||
self.node_group = VGroup()
|
||||
|
||||
self._construct_neural_network_layer()
|
||||
|
||||
def _construct_neural_network_layer(self):
|
||||
"""Creates the neural network layer"""
|
||||
# Add Nodes
|
||||
for node_number in range(self.num_nodes):
|
||||
node_object = Circle(radius=self.node_radius, color=self.node_color)
|
||||
self.node_group.add(node_object)
|
||||
# Space the nodes
|
||||
# Assumes Vertical orientation
|
||||
for node_index, node_object in enumerate(self.node_group):
|
||||
location = node_index * self.node_spacing
|
||||
node_object.move_to([0, location, 0])
|
||||
# Create Surrounding Rectangle
|
||||
surrounding_rectangle = SurroundingRectangle(
|
||||
self.node_group, color=self.rectangle_color, fill_color=self.rectangle_fill_color, fill_opacity=1.0)
|
||||
# Add the objects to the class
|
||||
self.add(surrounding_rectangle, self.node_group)
|
||||
|
||||
class NeuralNetwork(VGroup):
|
||||
|
||||
def __init__(
|
||||
self, layer_node_count, layer_width=1.0, node_radius=1.0,
|
||||
node_color=BLUE, edge_color=WHITE, layer_spacing=1.5,
|
||||
animation_dot_color=ORANGE):
|
||||
super(VGroup, self).__init__()
|
||||
self.layer_node_count = layer_node_count
|
||||
self.layer_width = layer_width
|
||||
self.node_radius = node_radius
|
||||
self.node_color = node_color
|
||||
self.edge_color = edge_color
|
||||
self.layer_spacing = layer_spacing
|
||||
self.animation_dot_color = animation_dot_color
|
||||
|
||||
self.layers = self._construct_layers()
|
||||
self.edge_layers = self._construct_edges()
|
||||
|
||||
self.add(self.edge_layers)
|
||||
self.add(self.layers)
|
||||
|
||||
def _construct_layers(self):
|
||||
"""Creates the neural network"""
|
||||
layers = VGroup()
|
||||
# Create each layer
|
||||
for layer_index, node_count in enumerate(self.layer_node_count):
|
||||
layer = NeuralNetworkLayer(node_count)
|
||||
# Manage spacing
|
||||
layer.move_to([self.layer_spacing * layer_index, 0, 0])
|
||||
# Add layer to VGroup
|
||||
layers.add(layer)
|
||||
# Create the connecting edges
|
||||
layers.z_index = 1
|
||||
return layers
|
||||
|
||||
def _construct_edges(self):
|
||||
"""Draws connecting lines between layers"""
|
||||
edge_layers = VGroup()
|
||||
for layer_index in range(len(self.layer_node_count) - 1):
|
||||
current_layer = self.layers[layer_index]
|
||||
next_layer = self.layers[layer_index + 1]
|
||||
edge_layer = VGroup()
|
||||
# Go through each node in the two layers and make a connecting line
|
||||
for node_i in current_layer.node_group:
|
||||
for node_j in next_layer.node_group:
|
||||
line = Line(node_i.get_center(), node_j.get_center(), color=self.edge_color)
|
||||
edge_layer.add(line)
|
||||
edge_layers.add(edge_layer)
|
||||
edge_layers.z_index = 1
|
||||
return edge_layers
|
||||
|
||||
def make_forward_propagation_animation(self, run_time=4):
|
||||
"""Generates an animation for feed forward propogation"""
|
||||
all_animations = []
|
||||
per_layer_run_time = run_time / len(self.edge_layers)
|
||||
for edge_layer in self.edge_layers:
|
||||
path_animations = []
|
||||
for edge in edge_layer:
|
||||
dot = Dot(color=self.animation_dot_color)
|
||||
dot.z_index = 0
|
||||
anim = MoveAlongPath(dot, edge, run_time=per_layer_run_time, rate_function=linear)
|
||||
path_animations.append(anim)
|
||||
path_animation_group = AnimationGroup(*path_animations)
|
||||
all_animations.append(path_animation_group)
|
||||
|
||||
animation_group = AnimationGroup(*all_animations, lag_ratio=1)
|
||||
|
||||
return animation_group
|
||||
|
||||
class TestNeuralNetworkScene(Scene):
|
||||
"""Test Scene for the Neural Network"""
|
||||
def construct(self):
|
||||
# Make the Layer object
|
||||
num_nodes = [5, 3, 5]
|
||||
nn = NeuralNetwork(num_nodes)
|
||||
nn.move_to(ORIGIN)
|
||||
# Make Animation
|
||||
self.add(nn)
|
||||
forward_propagation_animation = nn.make_forward_propagation_animation()
|
||||
self.play(forward_propagation_animation)
|
Reference in New Issue
Block a user