Spaces:
Sleeping
Sleeping
Niharmahesh
commited on
Upload 4 files
Browse files- Animation - 1707640885996.json +0 -0
- README.md +1 -13
- app.py +159 -0
- requirements.txt +8 -0
Animation - 1707640885996.json
ADDED
The diff for this file is too large to render.
See raw diff
|
|
README.md
CHANGED
@@ -1,13 +1 @@
|
|
1 |
-
|
2 |
-
title: Decoding CNN
|
3 |
-
emoji: 🏃
|
4 |
-
colorFrom: blue
|
5 |
-
colorTo: purple
|
6 |
-
sdk: streamlit
|
7 |
-
sdk_version: 1.40.1
|
8 |
-
app_file: app.py
|
9 |
-
pinned: false
|
10 |
-
short_description: 'Image representation of how a CNN works '
|
11 |
-
---
|
12 |
-
|
13 |
-
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
1 |
+
# CNN-arch
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app.py
ADDED
@@ -0,0 +1,159 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import numpy as np
|
3 |
+
from PIL import Image, ImageDraw, ImageFont
|
4 |
+
from tensorflow.keras.models import Sequential
|
5 |
+
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Dropout, Layer
|
6 |
+
from tensorflow.keras.layers import LeakyReLU, ELU
|
7 |
+
import imageio
|
8 |
+
import json
|
9 |
+
from streamlit_lottie import st_lottie
|
10 |
+
import tensorflow.keras.activations as activations
|
11 |
+
from tensorflow.keras.layers import Activation
|
12 |
+
|
13 |
+
# Function to load a Lottie animation from a local file
|
14 |
+
def load_lottiefile(filepath: str):
|
15 |
+
with open(filepath, "r") as file:
|
16 |
+
return json.load(file)
|
17 |
+
|
18 |
+
# Function to display a Lottie animation in the sidebar
|
19 |
+
def display_lottiefile_sidebar(lottie_json, unique_key):
|
20 |
+
st_lottie(lottie_json, speed=1, width=250, height=250, key=unique_key)
|
21 |
+
|
22 |
+
# Function to parse and preprocess the uploaded image
|
23 |
+
def parse_image(uploaded_file):
|
24 |
+
img = Image.open(uploaded_file)
|
25 |
+
img = img.resize((64, 64)).convert('L') # Convert to grayscale
|
26 |
+
img = np.array(img)
|
27 |
+
img = np.expand_dims(img, axis=0) # Shape (1, 64, 64)
|
28 |
+
img = np.expand_dims(img, axis=-1) # Shape (1, 64, 64, 1)
|
29 |
+
img = img / 255.0 # Normalize
|
30 |
+
return img
|
31 |
+
|
32 |
+
# Function to dynamically add an activation layer based on user selection
|
33 |
+
def add_activation_layer(model, activation_name):
|
34 |
+
if activation_name == 'leakyrelu':
|
35 |
+
model.add(LeakyReLU())
|
36 |
+
elif activation_name == 'elu':
|
37 |
+
model.add(ELU())
|
38 |
+
else:
|
39 |
+
# For 'relu', 'sigmoid', 'tanh', 'softmax', 'selu'
|
40 |
+
if hasattr(activations, activation_name):
|
41 |
+
activation_function = getattr(activations, activation_name)
|
42 |
+
model.add(Activation(activation_function))
|
43 |
+
else:
|
44 |
+
raise ValueError(f"Unsupported activation function: {activation_name}")
|
45 |
+
|
46 |
+
# Function to create a model and return the feature map
|
47 |
+
def display_feature_map(img, num_filters, kernel_size, activation, dropout_rate):
|
48 |
+
model = Sequential()
|
49 |
+
model.add(Conv2D(num_filters, (kernel_size, kernel_size), input_shape=(64, 64, 1)))
|
50 |
+
add_activation_layer(model, activation)
|
51 |
+
model.add(MaxPooling2D(pool_size=(2, 2)))
|
52 |
+
model.add(Dropout(dropout_rate))
|
53 |
+
conv2d_output = model.predict(img)
|
54 |
+
return conv2d_output
|
55 |
+
|
56 |
+
def main():
|
57 |
+
st.title("Convolutional Neural Network Visualizer")
|
58 |
+
with st.sidebar:
|
59 |
+
lottie_animation = load_lottiefile("Animation - 1707640885996.json")
|
60 |
+
display_lottiefile_sidebar(lottie_animation, "lottie_animation_key")
|
61 |
+
st.sidebar.markdown("""
|
62 |
+
# Interactive CNN Visualizer Explanation
|
63 |
+
This interactive tool allows you to visualize how different parameters of a Convolutional Neural Network (CNN) affect the features detected in an input image. Here's a brief overview of the parameters you can adjust:
|
64 |
+
|
65 |
+
## Filters/Kernels
|
66 |
+
- **What they are**: Small matrices of weights that slide over the input image to produce a feature map. Each filter is trained to detect a specific feature in the image, such as edges, corners, or textures.
|
67 |
+
|
68 |
+
## Kernel Size
|
69 |
+
- **What it is**: Determines the size of the filter. For example, a kernel size of 3 means the filter is a 3x3 matrix. The kernel size affects the level of detail the filter can capture. Smaller kernels can capture fine-grained details, while larger kernels capture more abstract features.
|
70 |
+
|
71 |
+
## Number of Filters
|
72 |
+
- **What it is**: Determines the number of feature maps that will be produced by a Conv2D layer. Each filter is trained to detect a different feature, so having more filters allows the model to recognize a wider variety of features.
|
73 |
+
|
74 |
+
## Activation Function
|
75 |
+
- **What it is**: Applied to the feature maps after the convolution operation. It introduces non-linearity into the model, which allows the model to learn more complex patterns. Common choices include ReLU (Rectified Linear Unit), sigmoid, and tanh.
|
76 |
+
|
77 |
+
## MaxPooling
|
78 |
+
- **What it is**: This operation reduces the spatial dimensions (i.e., width and height) of the input by taking the maximum value in each window of a certain size. This helps to make the model invariant to small translations and reduces the computational complexity of the model.
|
79 |
+
|
80 |
+
In the interactive visualization you've created, you can adjust the number of filters, the kernel size, and the activation function to see how these parameters affect the features that the model detects in the input image.
|
81 |
+
""", unsafe_allow_html=True)
|
82 |
+
|
83 |
+
|
84 |
+
# Architecture parameters input
|
85 |
+
num_filters = st.slider('Number of Filters:', 16, 256, 32)
|
86 |
+
kernel_size = st.slider('Kernel Size:', 2, 7, 3)
|
87 |
+
activation = st.selectbox('Activation Function:', ['relu', 'sigmoid', 'tanh', 'leakyrelu', 'elu'])
|
88 |
+
dropout_rate = st.slider('Dropout Rate:', 0.0, 0.5, 0.25)
|
89 |
+
|
90 |
+
# Image upload section
|
91 |
+
st.subheader("Upload Image")
|
92 |
+
uploaded_file = st.file_uploader("", type=["png", "jpg", "jpeg"], help="Choose an image to upload")
|
93 |
+
if uploaded_file is not None:
|
94 |
+
img = parse_image(uploaded_file)
|
95 |
+
st.session_state['uploaded_image'] = img
|
96 |
+
st.success("Image uploaded successfully!")
|
97 |
+
|
98 |
+
# Process button to visualize the model
|
99 |
+
if st.button("Process"):
|
100 |
+
if 'uploaded_image' in st.session_state:
|
101 |
+
visualize_activation_overlays(st.session_state['uploaded_image'], num_filters, kernel_size, activation, dropout_rate)
|
102 |
+
else:
|
103 |
+
st.error("Please upload an image first.")
|
104 |
+
|
105 |
+
# Reset button to clear session state and start over
|
106 |
+
if st.button("Reset"):
|
107 |
+
st.session_state.clear()
|
108 |
+
st.experimental_rerun()
|
109 |
+
|
110 |
+
def visualize_activation_overlays(img, num_filters, kernel_size, activation, dropout_rate):
|
111 |
+
conv2d_output = display_feature_map(img, num_filters, kernel_size, activation, dropout_rate)
|
112 |
+
|
113 |
+
# Define the new size for the output images
|
114 |
+
new_size = (800, 800) # Example new size, adjust as needed
|
115 |
+
|
116 |
+
# Assuming img was normalized to [0, 1], convert back to [0, 255], RGB, and resize
|
117 |
+
original_img = np.squeeze(img) * 255.0
|
118 |
+
original_img = Image.fromarray(np.uint8(original_img)).convert('RGB').resize(new_size)
|
119 |
+
|
120 |
+
frames = [] # To hold each frame for the GIF
|
121 |
+
|
122 |
+
for i in range(conv2d_output.shape[-1]): # Iterate through each feature map
|
123 |
+
feature_map = conv2d_output[0, :, :, i]
|
124 |
+
|
125 |
+
# Normalize the feature map to enhance visualization
|
126 |
+
normalized_feature_map = (feature_map - np.min(feature_map)) / (np.max(feature_map) - np.min(feature_map))
|
127 |
+
|
128 |
+
# Resize to new output size
|
129 |
+
resized_feature_map = Image.fromarray(np.uint8(normalized_feature_map * 255)).resize(new_size, Image.NEAREST)
|
130 |
+
|
131 |
+
# Create a mask where high activations are marked
|
132 |
+
mask = np.array(resized_feature_map) > 128 # Threshold to identify high activations
|
133 |
+
|
134 |
+
# Create an overlay image with red color in the high activation areas
|
135 |
+
overlay = np.array(original_img).copy()
|
136 |
+
overlay[mask] = [255, 0, 0] # Red color for high activation areas
|
137 |
+
|
138 |
+
# Convert numpy array back to PIL Image for display
|
139 |
+
overlay_img = Image.fromarray(overlay)
|
140 |
+
|
141 |
+
# Draw filter number or text on the image
|
142 |
+
draw = ImageDraw.Draw(overlay_img)
|
143 |
+
# Specify font size and type (default font here, you can specify a path to a .ttf file for custom fonts)
|
144 |
+
font = ImageFont.load_default()
|
145 |
+
# Position for the text (bottom left corner in this case)
|
146 |
+
text_position = (100, new_size[1] - 30)
|
147 |
+
# Drawing text
|
148 |
+
draw.text(text_position, f"Filter {i+1}", fill=(255,255,255), font=font)
|
149 |
+
|
150 |
+
frames.append(overlay_img)
|
151 |
+
|
152 |
+
# Create a GIF from the frames
|
153 |
+
gif_path = 'activation_overlay_large.gif'
|
154 |
+
imageio.mimsave(gif_path, frames, fps=1) # Adjust fps as needed
|
155 |
+
|
156 |
+
# Display the GIF in Streamlit
|
157 |
+
st.image(gif_path)
|
158 |
+
if __name__ == "__main__":
|
159 |
+
main()
|
requirements.txt
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
streamlit==1.10.0
|
2 |
+
numpy==1.21.4 # Or allow a newer version if compatible
|
3 |
+
Pillow==8.4.0
|
4 |
+
tensorflow>=2.6.1 # Upgrade to a newer version that's compatible with your NumPy version
|
5 |
+
matplotlib==3.4.3
|
6 |
+
imageio==2.9.0
|
7 |
+
json5==0.9.5
|
8 |
+
streamlit-lottie==0.0.2
|