mirror of
https://github.com/helblazer811/ManimML.git
synced 2025-05-20 03:57:40 +08:00
Removed Conv2D because it can be done using just Conv3D and renamed Conv3D to Conv2D to correspond to the spatial conv dimenson not the scene dimension, which is more inline with convention.
This commit is contained in:
@ -3,7 +3,7 @@ from pathlib import Path
|
||||
from manim import *
|
||||
from PIL import Image
|
||||
|
||||
from manim_ml.neural_network.layers.convolutional3d import Convolutional3DLayer
|
||||
from manim_ml.neural_network.layers.convolutional_2d import Convolutional2DLayer
|
||||
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
|
||||
@ -21,9 +21,9 @@ def make_code_snippet():
|
||||
# Make nn
|
||||
nn = NeuralNetwork([
|
||||
ImageLayer(numpy_image, height=1.5),
|
||||
Convolutional3DLayer(1, 7, 7, 3, 3),
|
||||
Convolutional3DLayer(3, 5, 5, 3, 3),
|
||||
Convolutional3DLayer(5, 3, 3, 1, 1),
|
||||
Convolutional2DLayer(1, 7, 7, 3, 3),
|
||||
Convolutional2DLayer(3, 5, 5, 3, 3),
|
||||
Convolutional2DLayer(5, 3, 3, 1, 1),
|
||||
FeedForwardLayer(3),
|
||||
FeedForwardLayer(3),
|
||||
])
|
||||
@ -54,9 +54,9 @@ class CombinedScene(ThreeDScene):
|
||||
nn = NeuralNetwork(
|
||||
[
|
||||
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),
|
||||
Convolutional3DLayer(5, 3, 3, 1, 1, filter_spacing=0.18),
|
||||
Convolutional2DLayer(1, 7, 7, 3, 3, filter_spacing=0.32),
|
||||
Convolutional2DLayer(3, 5, 5, 3, 3, filter_spacing=0.32),
|
||||
Convolutional2DLayer(5, 3, 3, 1, 1, filter_spacing=0.18),
|
||||
FeedForwardLayer(3),
|
||||
FeedForwardLayer(3),
|
||||
],
|
||||
|
77
examples/cnn/one_by_one_convolution.py
Normal file
77
examples/cnn/one_by_one_convolution.py
Normal file
@ -0,0 +1,77 @@
|
||||
from pathlib import Path
|
||||
|
||||
from manim import *
|
||||
from PIL import Image
|
||||
|
||||
from manim_ml.neural_network.layers.convolutional_2d import Convolutional2DLayer
|
||||
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
|
||||
|
||||
# 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]
|
||||
|
||||
|
||||
def make_code_snippet():
|
||||
code_str = """
|
||||
# Make nn
|
||||
nn = NeuralNetwork([
|
||||
ImageLayer(numpy_image, height=1.5),
|
||||
Convolutional2DLayer(1, 5, 5, 1, 1),
|
||||
Convolutional2DLayer(4, 5, 5, 1, 1),
|
||||
Convolutional2DLayer(2, 5, 5),
|
||||
])
|
||||
# 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.50)
|
||||
|
||||
return code
|
||||
|
||||
|
||||
class CombinedScene(ThreeDScene):
|
||||
def construct(self):
|
||||
image = Image.open(ROOT_DIR / "assets/mnist/digit.jpeg")
|
||||
numpy_image = np.asarray(image)
|
||||
# Make nn
|
||||
nn = NeuralNetwork(
|
||||
[
|
||||
ImageLayer(numpy_image, height=1.5),
|
||||
Convolutional2DLayer(1, 5, 5, 1, 1, filter_spacing=0.32),
|
||||
Convolutional2DLayer(4, 5, 5, 1, 1, filter_spacing=0.32),
|
||||
Convolutional2DLayer(2, 5, 5, filter_spacing=0.32),
|
||||
],
|
||||
layer_spacing=0.4,
|
||||
)
|
||||
# Center the nn
|
||||
nn.move_to(ORIGIN)
|
||||
self.add(nn)
|
||||
# Make code snippet
|
||||
code = make_code_snippet()
|
||||
code.next_to(nn, DOWN)
|
||||
self.add(code)
|
||||
# Group it all
|
||||
group = Group(nn, code)
|
||||
group.move_to(ORIGIN)
|
||||
# Play animation
|
||||
forward_pass = nn.make_forward_pass_animation(
|
||||
corner_pulses=False,
|
||||
all_filters_at_once=False,
|
||||
)
|
||||
self.wait(1)
|
||||
self.play(forward_pass)
|
@ -1,7 +1,7 @@
|
||||
from manim import *
|
||||
from PIL import Image
|
||||
|
||||
from manim_ml.neural_network.layers.convolutional3d import Convolutional3DLayer
|
||||
from manim_ml.neural_network.layers.convolutional_2d import Convolutional2DLayer
|
||||
from manim_ml.neural_network.layers.feed_forward import FeedForwardLayer
|
||||
from manim_ml.neural_network.layers.image import ImageLayer
|
||||
from manim_ml.neural_network.layers.parent_layers import ThreeDLayer
|
||||
@ -25,8 +25,8 @@ class CombinedScene(ThreeDScene):
|
||||
nn = NeuralNetwork(
|
||||
[
|
||||
ImageLayer(numpy_image, height=1.5),
|
||||
Convolutional3DLayer(1, 7, 7, 3, 3, filter_spacing=0.32),
|
||||
Convolutional3DLayer(3, 5, 5, 1, 1, filter_spacing=0.18),
|
||||
Convolutional2DLayer(1, 7, 7, 3, 3, filter_spacing=0.32),
|
||||
Convolutional2DLayer(3, 5, 5, 1, 1, filter_spacing=0.18),
|
||||
],
|
||||
layer_spacing=0.25,
|
||||
layout_direction="top_to_bottom",
|
||||
|
@ -1,13 +1,11 @@
|
||||
from manim_ml.neural_network.layers.convolutional_3d_to_feed_forward import (
|
||||
Convolutional3DToFeedForward,
|
||||
from manim_ml.neural_network.layers.convolutional_2d_to_feed_forward import (
|
||||
Convolutional2DToFeedForward,
|
||||
)
|
||||
from manim_ml.neural_network.layers.image_to_convolutional3d import (
|
||||
ImageToConvolutional3DLayer,
|
||||
from manim_ml.neural_network.layers.image_to_convolutional_2d import (
|
||||
ImageToConvolutional2DLayer,
|
||||
)
|
||||
from .convolutional3d_to_convolutional3d import Convolutional3DToConvolutional3D
|
||||
from .convolutional2d_to_convolutional2d import Convolutional2DToConvolutional2D
|
||||
from .convolutional3d import Convolutional3DLayer
|
||||
from .convolutional2d import Convolutional2DLayer
|
||||
from .convolutional_2d_to_convolutional_2d import Convolutional2DToConvolutional2D
|
||||
from .convolutional_2d import Convolutional2DLayer
|
||||
from .feed_forward_to_vector import FeedForwardToVector
|
||||
from .paired_query_to_feed_forward import PairedQueryToFeedForward
|
||||
from .embedding_to_feed_forward import EmbeddingToFeedForward
|
||||
@ -23,6 +21,7 @@ from .triplet import TripletLayer
|
||||
from .triplet_to_feed_forward import TripletToFeedForward
|
||||
from .paired_query import PairedQueryLayer
|
||||
from .paired_query_to_feed_forward import PairedQueryToFeedForward
|
||||
from .max_pooling_2d import MaxPooling2DLayer
|
||||
|
||||
connective_layers_list = (
|
||||
EmbeddingToFeedForward,
|
||||
@ -34,8 +33,8 @@ connective_layers_list = (
|
||||
TripletToFeedForward,
|
||||
PairedQueryToFeedForward,
|
||||
FeedForwardToVector,
|
||||
Convolutional3DToConvolutional3D,
|
||||
Convolutional2DToConvolutional2D,
|
||||
ImageToConvolutional3DLayer,
|
||||
Convolutional3DToFeedForward,
|
||||
Convolutional2DToConvolutional2D,
|
||||
ImageToConvolutional2DLayer,
|
||||
Convolutional2DToFeedForward,
|
||||
)
|
||||
|
@ -1,50 +0,0 @@
|
||||
from manim import *
|
||||
from matplotlib import animation
|
||||
from manim_ml.neural_network.layers.parent_layers import VGroupNeuralNetworkLayer
|
||||
|
||||
|
||||
class Convolutional2DLayer(VGroupNeuralNetworkLayer):
|
||||
def __init__(
|
||||
self,
|
||||
feature_map_height,
|
||||
feature_map_width,
|
||||
filter_width,
|
||||
filter_height,
|
||||
stride=1,
|
||||
cell_width=0.5,
|
||||
feature_map_color=BLUE,
|
||||
filter_color=ORANGE,
|
||||
**kwargs
|
||||
):
|
||||
super(VGroupNeuralNetworkLayer, self).__init__(**kwargs)
|
||||
self.feature_map_height = feature_map_height
|
||||
self.feature_map_width = feature_map_width
|
||||
self.filter_width = filter_width
|
||||
self.filter_height = filter_height
|
||||
self.feature_map_color = feature_map_color
|
||||
self.filter_color = filter_color
|
||||
self.stride = stride
|
||||
self.cell_width = cell_width
|
||||
# Construct the input
|
||||
self.construct_feature_map()
|
||||
|
||||
def construct_feature_map(self):
|
||||
"""Makes feature map"""
|
||||
# Make feature map rectangle
|
||||
self.feature_map = Rectangle(
|
||||
width=self.feature_map_width * self.cell_width,
|
||||
height=self.feature_map_height * self.cell_width,
|
||||
color=self.feature_map_color,
|
||||
grid_xstep=self.cell_width,
|
||||
grid_ystep=self.cell_width,
|
||||
)
|
||||
|
||||
self.add(self.feature_map)
|
||||
|
||||
@override_animation(Create)
|
||||
def _create_override(self, **kwargs):
|
||||
return FadeIn(self.feature_map)
|
||||
|
||||
def make_forward_pass_animation(self, **kwargs):
|
||||
"""Make feed forward animation"""
|
||||
return AnimationGroup()
|
@ -1,242 +0,0 @@
|
||||
from cv2 import line
|
||||
from manim import *
|
||||
from manim_ml.neural_network.layers.convolutional2d import Convolutional2DLayer
|
||||
from manim_ml.neural_network.layers.parent_layers import ConnectiveLayer
|
||||
|
||||
|
||||
class Convolutional2DToConvolutional2D(ConnectiveLayer):
|
||||
"""2D Conv to 2d Conv"""
|
||||
|
||||
input_class = Convolutional2DLayer
|
||||
output_class = Convolutional2DLayer
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
input_layer,
|
||||
output_layer,
|
||||
color=WHITE,
|
||||
filter_opacity=0.3,
|
||||
line_color=WHITE,
|
||||
pulse_color=ORANGE,
|
||||
**kwargs
|
||||
):
|
||||
super().__init__(
|
||||
input_layer,
|
||||
output_layer,
|
||||
input_class=Convolutional2DLayer,
|
||||
output_class=Convolutional2DLayer,
|
||||
**kwargs
|
||||
)
|
||||
self.color = color
|
||||
self.filter_color = self.input_layer.filter_color
|
||||
self.filter_width = self.input_layer.filter_width
|
||||
self.filter_height = self.input_layer.filter_height
|
||||
self.feature_map_width = self.input_layer.feature_map_width
|
||||
self.feature_map_height = self.input_layer.feature_map_height
|
||||
self.cell_width = self.input_layer.cell_width
|
||||
self.stride = self.input_layer.stride
|
||||
self.filter_opacity = filter_opacity
|
||||
self.line_color = line_color
|
||||
self.pulse_color = pulse_color
|
||||
|
||||
@override_animation(Create)
|
||||
def _create_override(self, **kwargs):
|
||||
return AnimationGroup()
|
||||
|
||||
def make_filter(self):
|
||||
"""Make filter object"""
|
||||
# Make opaque rectangle
|
||||
filter = Rectangle(
|
||||
color=self.filter_color,
|
||||
fill_color=self.filter_color,
|
||||
width=self.cell_width * self.filter_width,
|
||||
height=self.cell_width * self.filter_height,
|
||||
grid_xstep=self.cell_width,
|
||||
grid_ystep=self.cell_width,
|
||||
fill_opacity=self.filter_opacity,
|
||||
)
|
||||
# Move filter to top left of feature map
|
||||
filter.move_to(
|
||||
self.input_layer.feature_map.get_corner(LEFT + UP), aligned_edge=LEFT + UP
|
||||
)
|
||||
|
||||
return filter
|
||||
|
||||
def make_output_node(self):
|
||||
"""Put output node in top left corner of output feature map"""
|
||||
# Make opaque rectangle
|
||||
filter = Rectangle(
|
||||
color=self.filter_color,
|
||||
fill_color=self.filter_color,
|
||||
width=self.cell_width,
|
||||
height=self.cell_width,
|
||||
fill_opacity=self.filter_opacity,
|
||||
)
|
||||
# Move filter to top left of feature map
|
||||
filter.move_to(
|
||||
self.output_layer.feature_map.get_corner(LEFT + UP), aligned_edge=LEFT + UP
|
||||
)
|
||||
|
||||
return filter
|
||||
|
||||
def make_filter_propagation_animation(self):
|
||||
"""Make filter propagation animation"""
|
||||
lines_copy = self.filter_lines.copy().set_color(ORANGE)
|
||||
animation_group = AnimationGroup(
|
||||
Create(lines_copy, lag_ratio=0.0),
|
||||
# FadeOut(self.filter_lines),
|
||||
FadeOut(lines_copy),
|
||||
lag_ratio=1.0,
|
||||
)
|
||||
|
||||
return animation_group
|
||||
|
||||
def make_filter_lines(self):
|
||||
"""Lines connecting input filter with output node"""
|
||||
filter_lines = []
|
||||
corner_directions = [LEFT + UP, RIGHT + UP, RIGHT + DOWN, LEFT + DOWN]
|
||||
for corner_direction in corner_directions:
|
||||
filter_corner = self.filter.get_corner(corner_direction)
|
||||
output_corner = self.output_node.get_corner(corner_direction)
|
||||
line = Line(filter_corner, output_corner, stroke_color=self.line_color)
|
||||
filter_lines.append(line)
|
||||
|
||||
filter_lines = VGroup(*filter_lines)
|
||||
filter_lines.set_z_index(5)
|
||||
# Make updater that links the lines to the filter and output node
|
||||
def filter_updater(filter_lines):
|
||||
for corner_index, corner_direction in enumerate(corner_directions):
|
||||
line = filter_lines[corner_index]
|
||||
filter_corner = self.filter.get_corner(corner_direction)
|
||||
output_corner = self.output_node.get_corner(corner_direction)
|
||||
# line._set_start_and_end_attrs(filter_corner, output_corner)
|
||||
# line.put_start_and_end_on(filter_corner, output_corner)
|
||||
line.set_points_by_ends(filter_corner, output_corner)
|
||||
# line._set_start_and_end_attrs(filter_corner, output_corner)
|
||||
# line.set_points([filter_corner, output_corner])
|
||||
|
||||
filter_lines.add_updater(filter_updater)
|
||||
|
||||
return filter_lines
|
||||
|
||||
def make_assets(self):
|
||||
"""Make all of the assets"""
|
||||
# Make the filter
|
||||
self.filter = self.make_filter()
|
||||
self.add(self.filter)
|
||||
# Make output node
|
||||
self.output_node = self.make_output_node()
|
||||
self.add(self.output_node)
|
||||
# Make filter lines
|
||||
self.filter_lines = self.make_filter_lines()
|
||||
self.add(self.filter_lines)
|
||||
|
||||
super().set_z_index(5)
|
||||
|
||||
def make_forward_pass_animation(self, layer_args={}, run_time=1.5, **kwargs):
|
||||
"""Forward pass animation from conv2d to conv2d"""
|
||||
# Make assets
|
||||
self.make_assets()
|
||||
self.lines_copies = VGroup()
|
||||
self.add(self.lines_copies)
|
||||
# Make the animations
|
||||
animations = []
|
||||
# Create filter animation
|
||||
animations.append(
|
||||
AnimationGroup(
|
||||
Create(self.filter),
|
||||
Create(self.output_node),
|
||||
# Create(self.filter_lines)
|
||||
)
|
||||
)
|
||||
# Make scan filter animation
|
||||
num_y_moves = (
|
||||
int((self.feature_map_height - self.filter_height) / self.stride) + 1
|
||||
)
|
||||
num_x_moves = int((self.feature_map_width - self.filter_width) / self.stride)
|
||||
for y_location in range(num_y_moves):
|
||||
if y_location > 0:
|
||||
# Shift filter back to start and down
|
||||
shift_animation = ApplyMethod(
|
||||
self.filter.shift,
|
||||
np.array(
|
||||
[
|
||||
-self.cell_width
|
||||
* (self.feature_map_width - self.filter_width),
|
||||
-self.stride * self.cell_width,
|
||||
0,
|
||||
]
|
||||
),
|
||||
)
|
||||
# Shift output node
|
||||
shift_output_node = ApplyMethod(
|
||||
self.output_node.shift,
|
||||
np.array(
|
||||
[
|
||||
-(self.output_layer.feature_map_width - 1)
|
||||
* self.cell_width,
|
||||
-self.cell_width,
|
||||
0,
|
||||
]
|
||||
),
|
||||
)
|
||||
# Make animation group
|
||||
animation_group = AnimationGroup(
|
||||
shift_animation,
|
||||
shift_output_node,
|
||||
)
|
||||
animations.append(animation_group)
|
||||
# Make filter passing flash
|
||||
# animation = self.make_filter_propagation_animation()
|
||||
animations.append(Create(self.filter_lines, lag_ratio=0.0))
|
||||
# animations.append(animation)
|
||||
|
||||
for x_location in range(num_x_moves):
|
||||
# Shift filter right
|
||||
shift_animation = ApplyMethod(
|
||||
self.filter.shift, np.array([self.stride * self.cell_width, 0, 0])
|
||||
)
|
||||
# Shift output node
|
||||
shift_output_node = ApplyMethod(
|
||||
self.output_node.shift, np.array([self.cell_width, 0, 0])
|
||||
)
|
||||
# Make animation group
|
||||
animation_group = AnimationGroup(
|
||||
shift_animation,
|
||||
shift_output_node,
|
||||
)
|
||||
animations.append(animation_group)
|
||||
# Make filter passing flash
|
||||
old_z_index = self.filter_lines.z_index
|
||||
lines_copy = (
|
||||
self.filter_lines.copy()
|
||||
.set_color(ORANGE)
|
||||
.set_z_index(old_z_index + 1)
|
||||
)
|
||||
# self.add(lines_copy)
|
||||
# self.lines_copies.add(lines_copy)
|
||||
animations.append(Create(self.filter_lines, lag_ratio=0.0))
|
||||
# animations.append(FadeOut(self.filter_lines))
|
||||
# animation = self.make_filter_propagation_animation()
|
||||
# animations.append(animation)
|
||||
# animations.append(Create(self.filter_lines, lag_ratio=1.0))
|
||||
# animations.append(FadeOut(self.filter_lines))
|
||||
# Fade out
|
||||
animations.append(
|
||||
AnimationGroup(
|
||||
FadeOut(self.filter),
|
||||
FadeOut(self.output_node),
|
||||
FadeOut(self.filter_lines),
|
||||
)
|
||||
)
|
||||
# Make animation group
|
||||
animation_group = Succession(*animations, lag_ratio=1.0)
|
||||
return animation_group
|
||||
|
||||
def set_z_index(self, z_index, family=False):
|
||||
"""Override set_z_index"""
|
||||
super().set_z_index(4)
|
||||
|
||||
def scale(self, scale_factor, **kwargs):
|
||||
self.cell_width *= scale_factor
|
||||
super().scale(scale_factor, **kwargs)
|
@ -7,7 +7,7 @@ from manim_ml.gridded_rectangle import GriddedRectangle
|
||||
import numpy as np
|
||||
|
||||
|
||||
class Convolutional3DLayer(VGroupNeuralNetworkLayer, ThreeDLayer):
|
||||
class Convolutional2DLayer(VGroupNeuralNetworkLayer, ThreeDLayer):
|
||||
"""Handles rendering a convolutional layer for a nn"""
|
||||
|
||||
def __init__(
|
||||
@ -41,6 +41,8 @@ class Convolutional3DLayer(VGroupNeuralNetworkLayer, ThreeDLayer):
|
||||
self.stride = stride
|
||||
self.stroke_width = stroke_width
|
||||
self.show_grid_lines = show_grid_lines
|
||||
|
||||
def construct_layer(self, input_layer: 'NeuralNetworkLayer', output_layer: 'NeuralNetworkLayer', **kwargs):
|
||||
# Make the feature maps
|
||||
self.feature_maps = self.construct_feature_maps()
|
||||
self.add(self.feature_maps)
|
@ -1,11 +1,10 @@
|
||||
from manim import *
|
||||
from manim_ml.neural_network.layers.convolutional3d import Convolutional3DLayer
|
||||
from manim_ml.neural_network.layers.convolutional_2d import Convolutional2DLayer
|
||||
from manim_ml.neural_network.layers.parent_layers import ConnectiveLayer, ThreeDLayer
|
||||
from manim_ml.gridded_rectangle import GriddedRectangle
|
||||
|
||||
from manim.utils.space_ops import rotation_matrix
|
||||
|
||||
|
||||
class Filters(VGroup):
|
||||
"""Group for showing a collection of filters connecting two layers"""
|
||||
|
||||
@ -244,16 +243,16 @@ class Filters(VGroup):
|
||||
return passing_flash
|
||||
|
||||
|
||||
class Convolutional3DToConvolutional3D(ConnectiveLayer, ThreeDLayer):
|
||||
class Convolutional2DToConvolutional2D(ConnectiveLayer, ThreeDLayer):
|
||||
"""Feed Forward to Embedding Layer"""
|
||||
|
||||
input_class = Convolutional3DLayer
|
||||
output_class = Convolutional3DLayer
|
||||
input_class = Convolutional2DLayer
|
||||
output_class = Convolutional2DLayer
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
input_layer: Convolutional3DLayer,
|
||||
output_layer: Convolutional3DLayer,
|
||||
input_layer: Convolutional2DLayer,
|
||||
output_layer: Convolutional2DLayer,
|
||||
color=ORANGE,
|
||||
filter_opacity=0.3,
|
||||
line_color=ORANGE,
|
||||
@ -266,8 +265,8 @@ class Convolutional3DToConvolutional3D(ConnectiveLayer, ThreeDLayer):
|
||||
super().__init__(
|
||||
input_layer,
|
||||
output_layer,
|
||||
input_class=Convolutional3DLayer,
|
||||
output_class=Convolutional3DLayer,
|
||||
input_class=Convolutional2DLayer,
|
||||
output_class=Convolutional2DLayer,
|
||||
**kwargs,
|
||||
)
|
||||
self.color = color
|
@ -1,18 +1,18 @@
|
||||
from manim import *
|
||||
from manim_ml.neural_network.layers.parent_layers import ConnectiveLayer, ThreeDLayer
|
||||
from manim_ml.neural_network.layers.feed_forward import FeedForwardLayer
|
||||
from manim_ml.neural_network.layers.convolutional3d import Convolutional3DLayer
|
||||
from manim_ml.neural_network.layers.convolutional_2d import Convolutional2DLayer
|
||||
|
||||
|
||||
class Convolutional3DToFeedForward(ConnectiveLayer, ThreeDLayer):
|
||||
class Convolutional2DToFeedForward(ConnectiveLayer, ThreeDLayer):
|
||||
"""Feed Forward to Embedding Layer"""
|
||||
|
||||
input_class = Convolutional3DLayer
|
||||
input_class = Convolutional2DLayer
|
||||
output_class = FeedForwardLayer
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
input_layer: Convolutional3DLayer,
|
||||
input_layer: Convolutional2DLayer,
|
||||
output_layer: FeedForwardLayer,
|
||||
passing_flash_color=ORANGE,
|
||||
**kwargs
|
||||
@ -20,8 +20,8 @@ class Convolutional3DToFeedForward(ConnectiveLayer, ThreeDLayer):
|
||||
super().__init__(
|
||||
input_layer,
|
||||
output_layer,
|
||||
input_class=Convolutional3DLayer,
|
||||
output_class=Convolutional3DLayer,
|
||||
input_class=Convolutional2DLayer,
|
||||
output_class=Convolutional2DLayer,
|
||||
**kwargs
|
||||
)
|
||||
self.passing_flash_color = passing_flash_color
|
@ -35,9 +35,7 @@ class FeedForwardLayer(VGroupNeuralNetworkLayer):
|
||||
|
||||
self.node_group = VGroup()
|
||||
|
||||
self._construct_neural_network_layer()
|
||||
|
||||
def _construct_neural_network_layer(self):
|
||||
def construct_layer(self, input_layer: 'NeuralNetworkLayer', output_layer: 'NeuralNetworkLayer', **kwargs):
|
||||
"""Creates the neural network layer"""
|
||||
# Add Nodes
|
||||
for node_number in range(self.num_nodes):
|
||||
|
@ -1,10 +1,10 @@
|
||||
from manim import *
|
||||
import numpy as np
|
||||
from manim_ml.image import GrayscaleImageMobject
|
||||
from manim_ml.neural_network.layers.parent_layers import NeuralNetworkLayer
|
||||
|
||||
from PIL import Image
|
||||
|
||||
|
||||
class ImageLayer(NeuralNetworkLayer):
|
||||
"""Single Image Layer for Neural Network"""
|
||||
|
||||
@ -12,6 +12,17 @@ class ImageLayer(NeuralNetworkLayer):
|
||||
super().__init__(**kwargs)
|
||||
self.numpy_image = numpy_image
|
||||
self.show_image_on_create = show_image_on_create
|
||||
|
||||
def construct_layer(self, input_layer, output_layer):
|
||||
"""Construct layer method
|
||||
|
||||
Parameters
|
||||
----------
|
||||
input_layer :
|
||||
Input layer
|
||||
output_layer :
|
||||
Output layer
|
||||
"""
|
||||
if len(np.shape(self.numpy_image)) == 2:
|
||||
# Assumed Grayscale
|
||||
self.num_channels = 1
|
||||
|
@ -1,7 +1,7 @@
|
||||
import numpy as np
|
||||
|
||||
from manim import *
|
||||
from manim_ml.neural_network.layers.convolutional3d import Convolutional3DLayer
|
||||
from manim_ml.neural_network.layers.convolutional_2d import Convolutional2DLayer
|
||||
from manim_ml.neural_network.layers.image import ImageLayer
|
||||
from manim_ml.neural_network.layers.parent_layers import (
|
||||
ThreeDLayer,
|
||||
@ -10,14 +10,14 @@ from manim_ml.neural_network.layers.parent_layers import (
|
||||
from manim_ml.gridded_rectangle import GriddedRectangle
|
||||
|
||||
|
||||
class ImageToConvolutional3DLayer(VGroupNeuralNetworkLayer, ThreeDLayer):
|
||||
class ImageToConvolutional2DLayer(VGroupNeuralNetworkLayer, ThreeDLayer):
|
||||
"""Handles rendering a convolutional layer for a nn"""
|
||||
|
||||
input_class = ImageLayer
|
||||
output_class = Convolutional3DLayer
|
||||
output_class = Convolutional2DLayer
|
||||
|
||||
def __init__(
|
||||
self, input_layer: ImageLayer, output_layer: Convolutional3DLayer, **kwargs
|
||||
self, input_layer: ImageLayer, output_layer: Convolutional2DLayer, **kwargs
|
||||
):
|
||||
super().__init__(input_layer, output_layer, **kwargs)
|
||||
self.input_layer = input_layer
|
61
manim_ml/neural_network/layers/max_pooling_2d.py
Normal file
61
manim_ml/neural_network/layers/max_pooling_2d.py
Normal file
@ -0,0 +1,61 @@
|
||||
from manim import *
|
||||
|
||||
from manim_ml.neural_network.layers.parent_layers import ThreeDLayer, VGroupNeuralNetworkLayer
|
||||
|
||||
class MaxPooling2DLayer(VGroupNeuralNetworkLayer, ThreeDLayer):
|
||||
"""Max pooling layer for Convolutional2DLayer
|
||||
|
||||
Note: This is for a Convolutional2DLayer even though
|
||||
it is called MaxPooling2DLayer because the 2D corresponds
|
||||
to the 2 spatial dimensions of the convolution.
|
||||
"""
|
||||
|
||||
def __init__(self, output_feature_map_size=(4, 4), kernel_size=2, stride=1,
|
||||
cell_highlight_color=ORANGE, **kwargs):
|
||||
"""Layer object for animating 2D Convolution Max Pooling
|
||||
|
||||
Parameters
|
||||
----------
|
||||
kernel_size : int or tuple, optional
|
||||
Width/Height of max pooling kernel, by default 2
|
||||
stride : int, optional
|
||||
Stride of the max pooling operation, by default 1
|
||||
"""
|
||||
super().__init__(**kwargs)
|
||||
self.output_feature_map_size = output_feature_map_size
|
||||
self.kernel_size = kernel_size
|
||||
self.stride = stride
|
||||
self.cell_highlight_color = cell_highlight_color
|
||||
# Make the output feature maps
|
||||
feature_maps = self._make_output_feature_maps()
|
||||
self.add(feature_maps)
|
||||
|
||||
def construct_layer(self, input_layer, output_layer):
|
||||
"""Constructs the layer in the context of adjacent layers"""
|
||||
pass
|
||||
|
||||
def _make_output_feature_maps(self):
|
||||
"""Makes a set of output feature maps"""
|
||||
# Compute the size of the feature maps
|
||||
pass
|
||||
|
||||
def make_forward_pass_animation(self, layer_args={}, **kwargs):
|
||||
"""Makes forward pass of Max Pooling Layer.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
layer_args : dict, optional
|
||||
_description_, by default {}
|
||||
"""
|
||||
# 1. Draw gridded rectangle with kernel_size x kernel_size
|
||||
# box regions over the input feature map.
|
||||
# 2. Randomly highlight one of the cells in the kernel.
|
||||
# 3. Move and resize the gridded rectangle to the output
|
||||
# feature maps.
|
||||
# 4. Make the gridded feature map(s) disappear.
|
||||
pass
|
||||
|
||||
@override_animation(Create)
|
||||
def _create_override(self, **kwargs):
|
||||
"""Create animation for the MaxPooling operation"""
|
||||
pass
|
@ -1,7 +1,6 @@
|
||||
from manim import *
|
||||
from abc import ABC, abstractmethod
|
||||
|
||||
|
||||
class NeuralNetworkLayer(ABC, Group):
|
||||
"""Abstract Neural Network Layer class"""
|
||||
|
||||
@ -12,6 +11,20 @@ class NeuralNetworkLayer(ABC, Group):
|
||||
self.title.next_to(self, UP, 1.2)
|
||||
# self.add(self.title)
|
||||
|
||||
@abstractmethod
|
||||
def construct_layer(self, input_layer: 'NeuralNetworkLayer',
|
||||
output_layer: 'NeuralNetworkLayer', **kwargs):
|
||||
"""Constructs the layer at network construction time
|
||||
|
||||
Parameters
|
||||
----------
|
||||
input_layer : NeuralNetworkLayer
|
||||
preceding layer
|
||||
output_layer : NeuralNetworkLayer
|
||||
following layer
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def make_forward_pass_animation(self, layer_args={}, **kwargs):
|
||||
pass
|
||||
@ -23,7 +36,6 @@ class NeuralNetworkLayer(ABC, Group):
|
||||
def __repr__(self):
|
||||
return f"{type(self).__name__}"
|
||||
|
||||
|
||||
class VGroupNeuralNetworkLayer(NeuralNetworkLayer):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
@ -37,7 +49,6 @@ class VGroupNeuralNetworkLayer(NeuralNetworkLayer):
|
||||
def _create_override(self):
|
||||
return super()._create_override()
|
||||
|
||||
|
||||
class ThreeDLayer(ABC):
|
||||
"""Abstract class for 3D layers"""
|
||||
|
||||
@ -47,7 +58,6 @@ class ThreeDLayer(ABC):
|
||||
rotation_angle = 60 * DEGREES
|
||||
rotation_axis = [0.0, 0.9, 0.0]
|
||||
|
||||
|
||||
class ConnectiveLayer(VGroupNeuralNetworkLayer):
|
||||
"""Forward pass animation for a given pair of layers"""
|
||||
|
||||
@ -76,7 +86,6 @@ class ConnectiveLayer(VGroupNeuralNetworkLayer):
|
||||
+ ")"
|
||||
)
|
||||
|
||||
|
||||
class BlankConnective(ConnectiveLayer):
|
||||
"""Connective layer to be used when the given pair of layers is undefined"""
|
||||
|
||||
|
@ -51,11 +51,20 @@ class NeuralNetwork(Group):
|
||||
self.layout_direction = layout_direction
|
||||
# TODO take layer_node_count [0, (1, 2), 0]
|
||||
# and make it have explicit distinct subspaces
|
||||
# Construct all of the layers
|
||||
self._construct_input_layers()
|
||||
# Place the layers
|
||||
self._place_layers(layout=layout, layout_direction=layout_direction)
|
||||
self._place_layers(
|
||||
layout=layout,
|
||||
layout_direction=layout_direction
|
||||
)
|
||||
# Make the connective layers
|
||||
self.connective_layers, self.all_layers = self._construct_connective_layers()
|
||||
# Make overhead title
|
||||
self.title = Text(self.title_text, font_size=DEFAULT_FONT_SIZE / 2)
|
||||
self.title = Text(
|
||||
self.title_text,
|
||||
font_size=DEFAULT_FONT_SIZE / 2
|
||||
)
|
||||
self.title.next_to(self, UP, 1.0)
|
||||
self.add(self.title)
|
||||
# Place layers at correct z index
|
||||
@ -67,6 +76,21 @@ class NeuralNetwork(Group):
|
||||
# Print neural network
|
||||
print(repr(self))
|
||||
|
||||
def _construct_input_layers(self):
|
||||
"""Constructs each of the input layers in context
|
||||
of their adjacent layers"""
|
||||
prev_layer = None
|
||||
next_layer = None
|
||||
# Go through all the input layers and run their construct method
|
||||
for layer_index in range(len(self.input_layers)):
|
||||
current_layer = self.input_layers[layer_index]
|
||||
if layer_index < len(self.input_layers) - 1:
|
||||
next_layer = self.input_layers[layer_index + 1]
|
||||
if layer_index > 0:
|
||||
prev_layer = self.input_layers[layer_index - 1]
|
||||
# Run the construct layer method for each
|
||||
current_layer.construct_layer(prev_layer, next_layer)
|
||||
|
||||
def _place_layers(self, layout="linear", layout_direction="top_to_bottom"):
|
||||
"""Creates the neural network"""
|
||||
# TODO implement more sophisticated custom layouts
|
||||
@ -300,7 +324,6 @@ class NeuralNetwork(Group):
|
||||
string_repr = "NeuralNetwork([\n" + inner_string + "])"
|
||||
return string_repr
|
||||
|
||||
|
||||
class FeedForwardNeuralNetwork(NeuralNetwork):
|
||||
"""NeuralNetwork with just feed forward layers"""
|
||||
|
||||
|
@ -1,30 +1,83 @@
|
||||
from manim import *
|
||||
from manim_ml.neural_network.layers import Convolutional2DLayer
|
||||
from PIL import Image
|
||||
|
||||
from manim_ml.neural_network.layers.convolutional_2d import Convolutional2DLayer
|
||||
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
|
||||
|
||||
|
||||
class SingleConvolutionalLayerScene(ThreeDScene):
|
||||
def construct(self):
|
||||
# Make nn
|
||||
layers = [Convolutional2DLayer(3, 4)]
|
||||
nn = NeuralNetwork(layers)
|
||||
nn.scale(1.3)
|
||||
# Center the nn
|
||||
nn.move_to(ORIGIN)
|
||||
self.add(nn)
|
||||
# Play animation
|
||||
self.set_camera_orientation(
|
||||
phi=280 * DEGREES, theta=-10 * DEGREES, gamma=90 * DEGREES
|
||||
)
|
||||
# self.play(nn.make_forward_pass_animation(run_time=5))
|
||||
|
||||
|
||||
class Simple3DConvScene(ThreeDScene):
|
||||
def construct(self):
|
||||
"""
|
||||
TODO
|
||||
- [X] Make grid lines for the CNN filters
|
||||
- [ ] Make Scanning filter effect
|
||||
- [ ] Have filter box go accross each input feature map
|
||||
- [ ] Make filter lines effect
|
||||
- [ ] Make flowing animation down filter lines
|
||||
"""
|
||||
# Make nn
|
||||
layers = [
|
||||
Convolutional2DLayer(
|
||||
1, 5, 5, 5, 5, feature_map_height=3, filter_width=3, filter_height=3
|
||||
),
|
||||
Convolutional2DLayer(
|
||||
1, 3, 3, 1, 1, feature_map_width=3, filter_width=3, filter_height=3
|
||||
),
|
||||
]
|
||||
nn = NeuralNetwork(layers)
|
||||
# Center the nn
|
||||
nn.move_to(ORIGIN)
|
||||
self.add(nn)
|
||||
# Play animation
|
||||
# self.set_camera_orientation(phi=280*DEGREES, theta=-10*DEGREES, gamma=90*DEGREES)
|
||||
self.play(nn.make_forward_pass_animation(run_time=30))
|
||||
|
||||
# Make the specific scene
|
||||
config.pixel_height = 1200
|
||||
config.pixel_width = 1900
|
||||
config.frame_height = 12.0
|
||||
config.frame_width = 12.0
|
||||
config.frame_height = 6.0
|
||||
config.frame_width = 6.0
|
||||
|
||||
|
||||
class TestConv2d(Scene):
|
||||
class CombinedScene(ThreeDScene):
|
||||
def construct(self):
|
||||
image = Image.open("../assets/mnist/digit.jpeg")
|
||||
numpy_image = np.asarray(image)
|
||||
# Make nn
|
||||
nn = NeuralNetwork(
|
||||
[
|
||||
Convolutional2DLayer(5, 5, 3, 3, cell_width=0.5, stride=1),
|
||||
Convolutional2DLayer(3, 3, 2, 2, cell_width=0.5, stride=1),
|
||||
ImageLayer(numpy_image, height=1.5),
|
||||
Convolutional2DLayer(1, 7, 7, 3, 3, filter_spacing=0.32),
|
||||
Convolutional2DLayer(3, 5, 5, 3, 3, filter_spacing=0.32),
|
||||
Convolutional2DLayer(5, 3, 3, 1, 1, filter_spacing=0.18),
|
||||
FeedForwardLayer(3),
|
||||
FeedForwardLayer(3),
|
||||
],
|
||||
layer_spacing=1.5,
|
||||
camera=self.camera,
|
||||
layer_spacing=0.25,
|
||||
)
|
||||
# Center the nn
|
||||
nn.scale(1.3)
|
||||
nn.move_to(ORIGIN)
|
||||
self.play(Create(nn), run_time=2)
|
||||
self.add(nn)
|
||||
# Play animation
|
||||
forward_pass = nn.make_forward_pass_animation(run_time=19)
|
||||
self.play(
|
||||
forward_pass,
|
||||
forward_pass = nn.make_forward_pass_animation(
|
||||
corner_pulses=False, all_filters_at_once=False
|
||||
)
|
||||
self.wait(1)
|
||||
self.play(forward_pass)
|
@ -1,87 +0,0 @@
|
||||
from manim import *
|
||||
from PIL import Image
|
||||
|
||||
from manim_ml.neural_network.layers.convolutional3d import Convolutional3DLayer
|
||||
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
|
||||
|
||||
|
||||
class SingleConvolutionalLayerScene(ThreeDScene):
|
||||
def construct(self):
|
||||
# Make nn
|
||||
layers = [Convolutional3DLayer(3, 4)]
|
||||
nn = NeuralNetwork(layers)
|
||||
nn.scale(1.3)
|
||||
# Center the nn
|
||||
nn.move_to(ORIGIN)
|
||||
self.add(nn)
|
||||
# Play animation
|
||||
self.set_camera_orientation(
|
||||
phi=280 * DEGREES, theta=-10 * DEGREES, gamma=90 * DEGREES
|
||||
)
|
||||
# self.play(nn.make_forward_pass_animation(run_time=5))
|
||||
|
||||
|
||||
class Simple3DConvScene(ThreeDScene):
|
||||
def construct(self):
|
||||
"""
|
||||
TODO
|
||||
- [X] Make grid lines for the CNN filters
|
||||
- [ ] Make Scanning filter effect
|
||||
- [ ] Have filter box go accross each input feature map
|
||||
- [ ] Make filter lines effect
|
||||
- [ ] Make flowing animation down filter lines
|
||||
"""
|
||||
# Make nn
|
||||
layers = [
|
||||
Convolutional3DLayer(
|
||||
1, 5, 5, 5, 5, feature_map_height=3, filter_width=3, filter_height=3
|
||||
),
|
||||
Convolutional3DLayer(
|
||||
1, 3, 3, 1, 1, feature_map_width=3, filter_width=3, filter_height=3
|
||||
),
|
||||
]
|
||||
nn = NeuralNetwork(layers)
|
||||
# Center the nn
|
||||
nn.move_to(ORIGIN)
|
||||
self.add(nn)
|
||||
# Play animation
|
||||
# self.set_camera_orientation(phi=280*DEGREES, theta=-10*DEGREES, gamma=90*DEGREES)
|
||||
self.play(nn.make_forward_pass_animation(run_time=30))
|
||||
|
||||
|
||||
# Make the specific scene
|
||||
config.pixel_height = 1200
|
||||
config.pixel_width = 1900
|
||||
config.frame_height = 6.0
|
||||
config.frame_width = 6.0
|
||||
|
||||
|
||||
class CombinedScene(ThreeDScene):
|
||||
def construct(self):
|
||||
image = Image.open("../assets/mnist/digit.jpeg")
|
||||
numpy_image = np.asarray(image)
|
||||
# Make nn
|
||||
nn = NeuralNetwork(
|
||||
[
|
||||
ImageLayer(numpy_image, height=1.4),
|
||||
Convolutional3DLayer(1, 5, 5, 3, 3, filter_spacing=0.2),
|
||||
Convolutional3DLayer(2, 3, 3, 1, 1, filter_spacing=0.2),
|
||||
FeedForwardLayer(3, rectangle_stroke_width=4, node_stroke_width=4),
|
||||
FeedForwardLayer(1, rectangle_stroke_width=4, node_stroke_width=4),
|
||||
],
|
||||
layer_spacing=0.5,
|
||||
camera=self.camera,
|
||||
)
|
||||
|
||||
nn.scale(1.3)
|
||||
# Center the nn
|
||||
nn.move_to(ORIGIN)
|
||||
self.add(nn)
|
||||
# Play animation
|
||||
# self.set_camera_orientation(phi=280* DEGREES, theta=-20*DEGREES, gamma=90 * DEGREES)
|
||||
# self.begin_ambient_camera_rotation()
|
||||
forward_pass = nn.make_forward_pass_animation(run_time=10, corner_pulses=False)
|
||||
print(forward_pass)
|
||||
self.play(forward_pass)
|
@ -9,7 +9,6 @@ from sklearn import datasets
|
||||
import sklearn
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
|
||||
def learn_iris_decision_tree(iris):
|
||||
decision_tree = DecisionTreeClassifier(
|
||||
random_state=1, max_depth=3, max_leaf_nodes=6
|
||||
@ -18,13 +17,11 @@ def learn_iris_decision_tree(iris):
|
||||
# output the decisioin tree in some format
|
||||
return decision_tree
|
||||
|
||||
|
||||
def make_sklearn_tree(dataset, max_tree_depth=3):
|
||||
tree = learn_iris_decision_tree(dataset)
|
||||
feature_names = dataset.feature_names[0:2]
|
||||
return tree, tree.tree_
|
||||
|
||||
|
||||
class DecisionTreeScene(Scene):
|
||||
def construct(self):
|
||||
"""Makes a decision tree object"""
|
||||
@ -32,7 +29,6 @@ class DecisionTreeScene(Scene):
|
||||
clf, sklearn_tree = make_sklearn_tree(iris_dataset)
|
||||
# sklearn.tree.plot_tree(clf, node_ids=True)
|
||||
# plt.show()
|
||||
|
||||
decision_tree = DecisionTreeDiagram(
|
||||
sklearn_tree,
|
||||
class_images_paths=[
|
||||
@ -48,7 +44,6 @@ class DecisionTreeScene(Scene):
|
||||
self.play(create_decision_tree)
|
||||
# self.play(create_decision_tree)
|
||||
|
||||
|
||||
class SurfacePlot(Scene):
|
||||
def construct(self):
|
||||
iris_dataset = datasets.load_iris()
|
||||
|
@ -1,9 +1,11 @@
|
||||
from manim import *
|
||||
from PIL import Image
|
||||
import numpy as np
|
||||
|
||||
from manim_ml.neural_network.layers.convolutional3d import Convolutional3DLayer
|
||||
from manim_ml.neural_network.layers.convolutional_2d import Convolutional2DLayer
|
||||
from manim_ml.neural_network.layers.feed_forward import FeedForwardLayer
|
||||
from manim_ml.neural_network.layers.image import ImageLayer
|
||||
from manim_ml.neural_network.layers.max_pooling_2d import MaxPooling2DLayer
|
||||
from manim_ml.neural_network.neural_network import NeuralNetwork
|
||||
|
||||
# Make the specific scene
|
||||
@ -12,7 +14,6 @@ config.pixel_width = 1900
|
||||
config.frame_height = 6.0
|
||||
config.frame_width = 6.0
|
||||
|
||||
|
||||
class CombinedScene(ThreeDScene):
|
||||
def construct(self):
|
||||
image = Image.open("../assets/mnist/digit.jpeg")
|
||||
@ -21,22 +22,15 @@ class CombinedScene(ThreeDScene):
|
||||
nn = NeuralNetwork(
|
||||
[
|
||||
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),
|
||||
Convolutional3DLayer(5, 3, 3, 1, 1, filter_spacing=0.18),
|
||||
FeedForwardLayer(3),
|
||||
FeedForwardLayer(3),
|
||||
Convolutional2DLayer(1, 8, 8, 3, 3, filter_spacing=0.32),
|
||||
MaxPooling2DLayer(kernel_size=2),
|
||||
Convolutional2DLayer(3, 5, 5, 3, 3, filter_spacing=0.32),
|
||||
],
|
||||
layer_spacing=0.25,
|
||||
)
|
||||
# Center the nn
|
||||
nn.move_to(ORIGIN)
|
||||
self.add(nn)
|
||||
"""
|
||||
self.play(
|
||||
FadeIn(nn)
|
||||
)
|
||||
"""
|
||||
# Play animation
|
||||
forward_pass = nn.make_forward_pass_animation(
|
||||
corner_pulses=False, all_filters_at_once=False
|
31
tests/test_mcmc.py
Normal file
31
tests/test_mcmc.py
Normal file
@ -0,0 +1,31 @@
|
||||
from manim import *
|
||||
from manim_ml.diffusion.mcmc import MCMCAxes, MultidimensionalGaussianPosterior, metropolis_hastings_sampler
|
||||
# Make the specific scene
|
||||
config.pixel_height = 1200
|
||||
config.pixel_width = 1200
|
||||
config.frame_height = 12.0
|
||||
config.frame_width = 12.0
|
||||
|
||||
def test_metropolis_hastings_sampler(iterations=100):
|
||||
samples, _, candidates = metropolis_hastings_sampler(iterations=iterations)
|
||||
assert samples.shape == (iterations, 2)
|
||||
|
||||
class MCMCTest(Scene):
|
||||
|
||||
def construct(self):
|
||||
axes = MCMCAxes()
|
||||
self.play(Create(axes))
|
||||
gaussian_posterior = MultidimensionalGaussianPosterior(
|
||||
mu=np.array([0.0, 0.0]),
|
||||
var=np.array([4.0, 2.0])
|
||||
)
|
||||
show_gaussian_animation = axes.show_ground_truth_gaussian(
|
||||
gaussian_posterior
|
||||
)
|
||||
self.play(show_gaussian_animation)
|
||||
chain_sampling_animation = axes.visualize_metropolis_hastings_chain_sampling(
|
||||
log_prob_fn=gaussian_posterior,
|
||||
sampling_kwargs={"iterations": 1000}
|
||||
)
|
||||
|
||||
self.play(chain_sampling_animation)
|
4
tests/test_nested_neural_networks.py
Normal file
4
tests/test_nested_neural_networks.py
Normal file
@ -0,0 +1,4 @@
|
||||
"""
|
||||
The purpose of this test is to ensure that it is possible
|
||||
to have nested neural network layers.
|
||||
"""
|
@ -1,7 +1,7 @@
|
||||
from manim import *
|
||||
from PIL import Image
|
||||
|
||||
from manim_ml.neural_network.layers.convolutional3d import Convolutional3DLayer
|
||||
from manim_ml.neural_network.layers.convolutional_2d import Convolutional2DLayer
|
||||
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
|
||||
@ -21,8 +21,8 @@ class CombinedScene(ThreeDScene):
|
||||
nn = NeuralNetwork(
|
||||
[
|
||||
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),
|
||||
Convolutional2DLayer(1, 7, 7, 3, 3, filter_spacing=0.32),
|
||||
Convolutional2DLayer(3, 5, 5, 3, 3, filter_spacing=0.32),
|
||||
FeedForwardLayer(3),
|
||||
],
|
||||
layer_spacing=0.25,
|
||||
|
14
tests/test_show_gaussian.py
Normal file
14
tests/test_show_gaussian.py
Normal file
@ -0,0 +1,14 @@
|
||||
from manim import *
|
||||
from manim_ml.probability import GaussianDistribution
|
||||
|
||||
class TestShowGaussian(Scene):
|
||||
|
||||
def construct(self):
|
||||
axes = Axes()
|
||||
self.add(axes)
|
||||
gaussian = GaussianDistribution(
|
||||
axes,
|
||||
mean=np.array([0.0, 0.0]),
|
||||
cov=np.array([[2.0, 0.0], [0.0, 1.0]])
|
||||
)
|
||||
self.add(gaussian)
|
Reference in New Issue
Block a user