Update readme and setup code to be pushed to pip repository.

This commit is contained in:
Alec Helbling
2022-12-31 12:36:15 -05:00
parent 313d1aa650
commit 334662e8c8
11 changed files with 341 additions and 154 deletions

View File

@ -60,6 +60,12 @@ class VariationalAutoencoderScene(Scene):
self.play(neural_network.make_forward_pass_animation(run_time=15))
```
### Convolutional Neural Network
This is a visualization of a Convolutional Neural Network.
<img src="examples/media/CNNScene.gif">
### Generative Adversarial Network
This is a visualization of a Generative Adversarial Network made using ManimML.

View File

@ -3,40 +3,26 @@ from pathlib import Path
from manim import *
from PIL import Image
<<<<<<< HEAD
from manim_ml.neural_network.layers.convolutional3d import Convolutional3DLayer
=======
from manim_ml.neural_network.layers import Convolutional3DLayer
>>>>>>> 0bc3ad561ba224f3d33e9f843665c1d50d64a68b
from manim_ml.neural_network.layers.feed_forward import FeedForwardLayer
from manim_ml.neural_network.layers.image import ImageLayer
from manim_ml.neural_network.neural_network import NeuralNetwork
<<<<<<< HEAD
# Make the specific scene
config.pixel_height = 1200
config.pixel_width = 1900
config.frame_height = 7.0
config.frame_width = 7.0
=======
ROOT_DIR = Path(__file__).parents[2]
>>>>>>> 0bc3ad561ba224f3d33e9f843665c1d50d64a68b
def make_code_snippet():
code_str = """
# Make nn
nn = NeuralNetwork([
<<<<<<< HEAD
ImageLayer(numpy_image, height=1.5),
Convolutional3DLayer(1, 7, 7, 3, 3),
Convolutional3DLayer(3, 5, 5, 3, 3),
Convolutional3DLayer(5, 3, 3, 1, 1),
=======
ImageLayer(numpy_image),
Convolutional3DLayer(3, 3, 3),
Convolutional3DLayer(5, 2, 2),
Convolutional3DLayer(10, 2, 1),
>>>>>>> 0bc3ad561ba224f3d33e9f843665c1d50d64a68b
FeedForwardLayer(3),
FeedForwardLayer(3),
])
@ -64,7 +50,6 @@ class CombinedScene(ThreeDScene):
numpy_image = np.asarray(image)
# Make nn
nn = NeuralNetwork([
<<<<<<< HEAD
ImageLayer(numpy_image, height=1.5),
Convolutional3DLayer(1, 7, 7, 3, 3, filter_spacing=0.32),
Convolutional3DLayer(3, 5, 5, 3, 3, filter_spacing=0.32),
@ -75,16 +60,6 @@ class CombinedScene(ThreeDScene):
layer_spacing=0.25,
)
# Center the nn
=======
ImageLayer(numpy_image, height=3.5),
Convolutional3DLayer(3, 3, 3, filter_spacing=0.2),
Convolutional3DLayer(5, 2, 2, filter_spacing=0.2),
Convolutional3DLayer(10, 2, 1, filter_spacing=0.2),
FeedForwardLayer(3, rectangle_stroke_width=4, node_stroke_width=4).scale(2),
FeedForwardLayer(1, rectangle_stroke_width=4, node_stroke_width=4).scale(2)
], layer_spacing=0.2)
nn.scale(0.9)
>>>>>>> 0bc3ad561ba224f3d33e9f843665c1d50d64a68b
nn.move_to(ORIGIN)
self.add(nn)
# Make code snippet

View File

@ -0,0 +1,85 @@
from manim import *
from manim_ml.neural_network.layers import FeedForwardLayer, ImageLayer
from manim_ml.neural_network.neural_network import NeuralNetwork
from PIL import Image
import numpy as np
config.pixel_height = 720
config.pixel_width = 1280
config.frame_height = 6.0
config.frame_width = 6.0
class ImageNeuralNetworkScene(Scene):
def make_code_snippet(self):
code_str = """
# Make image object
image = Image.open('images/image.jpeg')
numpy_image = np.asarray(image)
# Make Neural Network
layers = [
ImageLayer(numpy_image, height=1.4),
FeedForwardLayer(3),
FeedForwardLayer(5),
FeedForwardLayer(3)
]
nn = NeuralNetwork(layers)
self.add(nn)
# Play animation
self.play(
nn.make_forward_pass_animation()
)
"""
code = Code(
code = code_str,
tab_width=4,
background_stroke_width=1,
background_stroke_color=WHITE,
insert_line_no=False,
style='monokai',
#background="window",
language="py",
)
code.scale(0.2)
return code
def construct(self):
image = Image.open('../../tests/images/image.jpeg')
numpy_image = np.asarray(image)
# Make nn
layers = [
ImageLayer(numpy_image, height=1.4),
FeedForwardLayer(3),
FeedForwardLayer(5),
FeedForwardLayer(3),
FeedForwardLayer(6)
]
nn = NeuralNetwork(layers)
nn.scale(0.9)
# Center the nn
nn.move_to(ORIGIN)
nn.rotate(-PI/2)
nn.layers[0].image_mobject.rotate(PI/2)
nn.layers[0].image_mobject.shift([0, -0.4, 0])
nn.shift([1.5, 0.3, 0])
self.add(nn)
# Make code snippet
code_snippet = self.make_code_snippet()
code_snippet.scale(1.9)
code_snippet.shift([-1.25, 0, 0])
self.add(code_snippet)
# Play animation
self.play(
nn.make_forward_pass_animation(run_time=10)
)
if __name__ == "__main__":
"""Render all scenes"""
# Feed Forward Neural Network
ffnn_scene = FeedForwardNeuralNetworkScene()
ffnn_scene.render()
# Neural Network
nn_scene = NeuralNetworkScene()
nn_scene.render()

View File

@ -0,0 +1,85 @@
from manim import *
from manim_ml.neural_network.layers import FeedForwardLayer, ImageLayer, EmbeddingLayer
from manim_ml.neural_network.neural_network import NeuralNetwork
from PIL import Image
import numpy as np
config.pixel_height = 720
config.pixel_width = 720
config.frame_height = 6.0
config.frame_width = 6.0
class VAECodeSnippetScene(Scene):
def make_code_snippet(self):
code_str = """
# Make Neural Network
nn = NeuralNetwork([
ImageLayer(numpy_image, height=1.2),
FeedForwardLayer(5),
FeedForwardLayer(3),
EmbeddingLayer(),
FeedForwardLayer(3),
FeedForwardLayer(5),
ImageLayer(numpy_image, height=1.2),
], layer_spacing=0.1)
# Play animation
self.play(nn.make_forward_pass_animation())
"""
code = Code(
code = code_str,
tab_width=4,
background_stroke_width=1,
# background_stroke_color=WHITE,
insert_line_no=False,
background="window",
# font="Monospace",
style='one-dark',
language="py",
)
return code
def construct(self):
image = Image.open('../../tests/images/image.jpeg')
numpy_image = np.asarray(image)
embedding_layer = EmbeddingLayer(dist_theme="ellipse", point_radius=0.04).scale(1.0)
# Make nn
nn = NeuralNetwork([
ImageLayer(numpy_image, height=1.2),
FeedForwardLayer(5),
FeedForwardLayer(3),
embedding_layer,
FeedForwardLayer(3),
FeedForwardLayer(5),
ImageLayer(numpy_image, height=1.2),
], layer_spacing=0.1)
nn.scale(1.1)
# Center the nn
nn.move_to(ORIGIN)
# nn.rotate(-PI/2)
# nn.all_layers[0].image_mobject.rotate(PI/2)
# nn.all_layers[0].image_mobject.shift([0, -0.4, 0])
# nn.all_layers[-1].image_mobject.rotate(PI/2)
# nn.all_layers[-1].image_mobject.shift([0, -0.4, 0])
nn.shift([0, -1.4, 0])
self.add(nn)
# Make code snippet
code_snippet = self.make_code_snippet()
code_snippet.scale(0.52)
code_snippet.shift([0, 1.25, 0])
# code_snippet.shift([-1.25, 0, 0])
self.add(code_snippet)
# Play animation
self.play(
nn.make_forward_pass_animation(),
run_time=10
)
if __name__ == "__main__":
"""Render all scenes"""
# Neural Network
nn_scene = VAECodeSnippetScene()
nn_scene.render()

View File

@ -0,0 +1,92 @@
from manim import *
from manim_ml.neural_network.layers import FeedForwardLayer, ImageLayer, EmbeddingLayer
from manim_ml.neural_network.neural_network import NeuralNetwork
from PIL import Image
import numpy as np
config.pixel_height = 720
config.pixel_width = 1280
config.frame_height = 6.0
config.frame_width = 6.0
class VAECodeSnippetScene(Scene):
def make_code_snippet(self):
code_str = """
# Make image object
image = Image.open('images/image.jpeg')
numpy_image = np.asarray(image)
# Make Neural Network
nn = NeuralNetwork([
ImageLayer(numpy_image, height=1.2),
FeedForwardLayer(5),
FeedForwardLayer(3),
EmbeddingLayer(),
FeedForwardLayer(3),
FeedForwardLayer(5),
ImageLayer(numpy_image, height=1.2),
], layer_spacing=0.1)
self.add(nn)
# Play animation
self.play(
nn.make_forward_pass_animation()
)
"""
code = Code(
code = code_str,
tab_width=4,
background_stroke_width=1,
# background_stroke_color=WHITE,
insert_line_no=False,
background="window",
# font="Monospace",
style='one-dark',
language="py",
)
code.scale(0.2)
return code
def construct(self):
image = Image.open('../../tests/images/image.jpeg')
numpy_image = np.asarray(image)
embedding_layer = EmbeddingLayer(dist_theme="ellipse", point_radius=0.04).scale(1.0)
# Make nn
nn = NeuralNetwork([
ImageLayer(numpy_image, height=1.0),
FeedForwardLayer(5),
FeedForwardLayer(3),
embedding_layer,
FeedForwardLayer(3),
FeedForwardLayer(5),
ImageLayer(numpy_image, height=1.0),
], layer_spacing=0.1)
nn.scale(0.65)
# Center the nn
nn.move_to(ORIGIN)
nn.rotate(-PI/2)
nn.all_layers[0].image_mobject.rotate(PI/2)
# nn.all_layers[0].image_mobject.shift([0, -0.4, 0])
nn.all_layers[-1].image_mobject.rotate(PI/2)
# nn.all_layers[-1].image_mobject.shift([0, -0.4, 0])
nn.shift([1.5, 0.0, 0])
self.add(nn)
# Make code snippet
code_snippet = self.make_code_snippet()
code_snippet.scale(1.9)
code_snippet.shift([-1.25, 0, 0])
self.add(code_snippet)
# Play animation
self.play(
nn.make_forward_pass_animation(),
run_time=10
)
if __name__ == "__main__":
"""Render all scenes"""
# Neural Network
nn_scene = VAECodeSnippetScene()
nn_scene.render()

41
examples/logo/logo.py Normal file
View File

@ -0,0 +1,41 @@
"""
Logo for Manim Machine Learning
"""
from manim import *
from manim_ml.neural_network.neural_network import FeedForwardNeuralNetwork
config.pixel_height = 500
config.pixel_width = 500
config.frame_height = 4.0
config.frame_width = 4.0
class ManimMLLogo(Scene):
def construct(self):
self.text = Text("ManimML")
self.text.scale(1.0)
self.neural_network = FeedForwardNeuralNetwork([3, 5, 3, 6, 3], layer_spacing=0.3, node_color=BLUE)
self.neural_network.scale(1.0)
self.neural_network.move_to(self.text.get_bottom())
self.neural_network.shift(1.25 * DOWN)
self.logo_group = Group(self.text, self.neural_network)
self.logo_group.scale(1.0)
self.logo_group.move_to(ORIGIN)
self.play(Write(self.text))
self.play(Create(self.neural_network))
# self.surrounding_rectangle = SurroundingRectangle(self.logo_group, buff=0.3, color=BLUE)
underline = Underline(self.text, color=BLUE)
animation_group = AnimationGroup(
self.neural_network.make_forward_pass_animation(run_time=5),
Create(underline),
# Create(self.surrounding_rectangle)
)
# self.surrounding_rectangle = SurroundingRectangle(self.logo_group, buff=0.3, color=BLUE)
underline = Underline(self.text, color=BLUE)
animation_group = AnimationGroup(
self.neural_network.make_forward_pass_animation(run_time=5),
Create(underline),
# Create(self.surrounding_rectangle)
)
self.play(animation_group)
self.wait(5)

View File

@ -0,0 +1,25 @@
"""
Logo for Manim Machine Learning
"""
from manim import *
from manim_ml.neural_network.neural_network import FeedForwardNeuralNetwork
config.pixel_height = 400
config.pixel_width = 600
config.frame_height = 8.0
config.frame_width = 10.0
class ManimMLLogo(Scene):
def construct(self):
self.neural_network = FeedForwardNeuralNetwork([3, 5, 3, 5], layer_spacing=0.6, node_color=BLUE,
edge_width=6)
self.neural_network.scale(3)
self.neural_network.move_to(ORIGIN)
self.play(Create(self.neural_network))
# self.surrounding_rectangle = SurroundingRectangle(self.logo_group, buff=0.3, color=BLUE)
animation_group = AnimationGroup(
self.neural_network.make_forward_pass_animation(run_time=5),
)
self.play(animation_group)
self.wait(5)

BIN
examples/media/CNNScene.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 MiB

BIN
examples/media/CNNScene.mp4 Normal file

Binary file not shown.

View File

@ -16,134 +16,13 @@ from manim_ml.neural_network.neural_network import NeuralNetwork
ROOT_DIR = Path(__file__).parents[2]
config.pixel_height = 1200
config.pixel_width = 1900
config.frame_height = 7.0
config.frame_width = 7.0
<<<<<<< HEAD
return animation_group
def make_dot_divergence_animation(self, location, run_time=3.0):
"""Makes dots diverge from the given location and move the decoder"""
animations = []
for node in self.decoder.layers[0].node_group:
new_dot = Dot(location, radius=self.dot_radius, color=RED)
per_node_succession = Succession(
Create(new_dot),
new_dot.animate.move_to(node.get_center()),
)
animations.append(per_node_succession)
animation_group = AnimationGroup(*animations)
return animation_group
def make_reset_vae_animation(self):
"""Resets the VAE to just the neural network"""
animation_group = AnimationGroup(
FadeOut(self.input_image),
FadeOut(self.output_image),
FadeOut(self.distribution_objects),
run_time=1.0
)
return animation_group
def make_forward_pass_animation(self, image_pair, run_time=1.5, **kwargs):
"""Overriden forward pass animation specific to a VAE"""
per_unit_runtime = run_time
# Setup images
self.input_image, self.output_image = self._construct_input_output_images(image_pair)
self.input_image.move_to(self.encoder.get_left())
self.input_image.shift(LEFT)
self.output_image.move_to(self.decoder.get_right())
self.output_image.shift(RIGHT*1.3)
# Make encoder forward pass
encoder_forward_pass = self.encoder.make_forward_propagation_animation(run_time=per_unit_runtime)
# Make red dot in embedding
mean = [1.0, 1.5]
mean_point = self.embedding.axes.coords_to_point(*mean)
std = [0.8, 1.2]
# Make the dot convergence animation
dot_convergence_animation = self.make_dot_convergence_animation(mean, run_time=per_unit_runtime)
encoding_succesion = Succession(
encoder_forward_pass,
dot_convergence_animation
)
# Make an ellipse centered at mean_point witAnimationGraph std outline
center_dot = Dot(mean_point, radius=self.dot_radius, color=RED)
ellipse = Ellipse(width=std[0], height=std[1], color=RED, fill_opacity=0.3, stroke_width=self.ellipse_stroke_width)
ellipse.move_to(mean_point)
self.distribution_objects = VGroup(
center_dot,
ellipse
)
# Make ellipse animation
ellipse_animation = AnimationGroup(
GrowFromCenter(center_dot),
GrowFromCenter(ellipse),
)
# Make the dot divergence animation
sampled_point = [0.51, 1.0]
divergence_point = self.embedding.axes.coords_to_point(*sampled_point)
dot_divergence_animation = self.make_dot_divergence_animation(divergence_point, run_time=per_unit_runtime)
# Make decoder foward pass
decoder_forward_pass = self.decoder.make_forward_propagation_animation(run_time=per_unit_runtime)
# Add the animations to the group
animation_group = AnimationGroup(
FadeIn(self.input_image),
encoding_succesion,
ellipse_animation,
dot_divergence_animation,
decoder_forward_pass,
FadeIn(self.output_image),
lag_ratio=1,
)
return animation_group
def make_interpolation_animation(self, interpolation_images, frame_rate=5):
"""Makes an animation interpolation"""
num_images = len(interpolation_images)
# Make madeup path
interpolation_latent_path = np.linspace([-0.7, -1.2], [1.2, 1.5], num=num_images)
# Make the path animation
first_dot_location = self.embedding.axes.coords_to_point(*interpolation_latent_path[0])
last_dot_location = self.embedding.axes.coords_to_point(*interpolation_latent_path[-1])
moving_dot = Dot(first_dot_location, radius=self.dot_radius, color=RED)
self.add(moving_dot)
animation_list = [Create(Line(first_dot_location, last_dot_location, color=RED), run_time=0.1*num_images)]
for image_index in range(num_images - 1):
next_index = image_index + 1
# Get path
next_point = interpolation_latent_path[next_index]
next_position = self.embedding.axes.coords_to_point(*next_point)
# Draw path from current point to next point
move_animation = moving_dot.animate(run_time=0.1*num_images).move_to(next_position)
animation_list.append(move_animation)
interpolation_animation = AnimationGroup(*animation_list)
# Make the images animation
animation_list = [Wait(0.5)]
for numpy_image in interpolation_images:
numpy_image = numpy_image[None, :, :]
manim_image = self._construct_image_mobject(numpy_image)
# Move the image to the correct location
manim_image.move_to(self.output_image)
# Add the image
animation_list.append(FadeIn(manim_image, run_time=0.1))
# Wait
# animation_list.append(Wait(1 / frame_rate))
# Remove the image
# animation_list.append(FadeOut(manim_image, run_time=0.1))
images_animation = AnimationGroup(*animation_list, lag_ratio=1.0)
# Combine the two into an AnimationGroup
animation_group = AnimationGroup(
interpolation_animation,
images_animation
)
return animation_group
=======
class VAEScene(Scene):
"""Scene object for a Variational Autoencoder and Autoencoder"""
>>>>>>> 0bc3ad561ba224f3d33e9f843665c1d50d64a68b
def construct(self):
@ -152,13 +31,12 @@ class VAEScene(Scene):
ImageLayer(numpy_image, height=1.4),
FeedForwardLayer(5),
FeedForwardLayer(3),
EmbeddingLayer(dist_theme="ellipse").scale(2),
EmbeddingLayer(dist_theme="ellipse"),
FeedForwardLayer(3),
FeedForwardLayer(5),
ImageLayer(numpy_image, height=1.4),
])
vae.scale(1.3)
self.play(Create(vae))
self.play(vae.make_forward_pass_animation(run_time=15))
self.play(vae.make_forward_pass_animation(run_time=15))

View File

@ -2,7 +2,7 @@ from setuptools import setup, find_packages
setup(
name = "manim_ml",
version = "0.0.11",
version = "0.0.12",
description = (" Machine Learning Animations in python using Manim."),
packages=find_packages(),
)