This is a Convolutional Neural Network (CNN) framework project implemented entirely from scratch using only low-level libraries like NumPy, PIL, SciPy and Cython no deep learning frameworks (e.g., TensorFlow or PyTorch) are used. It can train a CNN model on your local dataset folder or an external Hugging Face dataset, save or load models, support CUDA and the Adam optimizer for better performance, and switch the training backend between CPU and GPU
- PyCNN trained model: pycnn_cifar10
| Version | Latest | Stable |
|---|---|---|
| 2.2 | β | β |
| 2.0 | β | β |
| 0.1.2 | β | β |
| 0.1.1 | β | β |
| 0.1.0 | β | β |
- β Fully functional CNN implementation from scratch
- π§ Manual convolution, max pooling, and ReLU activations
- π Forward and backward propagation with mini-batch gradient descent
- π· Multi-class classification via softmax and cross-entropy loss
- πΎ Model save/load using
pickle - πΌ RGB image preprocessing with customizable filters
- π Predict function to classify new unseen images
- π Real-time training visualization (accuracy & loss per epoch)
- β‘ Optional CUDA acceleration for faster training and inference
- π Adam optimizer support for improved training performance
- π Dynamic user-defined layers for fully customizable architectures
- π Performance optimizations for faster computation and memory efficiency
- π Automatic backend conversion when loading models trained on a different backend
- π ** More CPU based performance optimizations** for faster computation and memory efficiency
- π Automatic backend conversion when loading models trained on a different backend
- π’οΈ Hugging Face CNN datasets support
- ποΈ Dataset augmentation support
- π Pytorch exportation support to export PyCNN trained model to a PyTorch format
Make sure your dataset folder is structured like this:
data/
βββ class1/
β βββ image1.png
β βββ image2.png
βββ class2/
β βββ image1.png
β βββ image2.png
βββ class../
β βββ ..
..
Each subfolder represents a class (e.g., cat, dog), and contains sample images.
To help you get started, weβve included a starter
datafolder with example class directories.
-
Image Preprocessing:
- Each image is resized to a fixed size and normalized.
- Filters (e.g., sharpening, edge detection) are applied using 2D convolution.
- ReLU activation and 2Γ2 max-pooling reduce spatial dimensions.
- GPU acceleration via CUDA allows these operations to run in parallel on the graphics card, significantly speeding up large datasets.
-
Feature Vector:
- Flattened pooled feature maps are fed into fully connected layers.
-
Feedforward + Softmax:
- Dense layers compute activations followed by a softmax for classification.
- All dense computations can be performed on the GPU for faster matrix multiplications.
-
Backpropagation:
- Gradients are computed layer-by-layer.
- Weights and biases are updated using the Adam or SGD optimizer, which adapts learning rates for each parameter for faster and more stable convergence compared to basic gradient descent.
- CUDA can also accelerate gradient computations and weight updates.
from pycnn.pycnn import PyCNN
pycnn= CNN()
pycnn.cuda(True) # Enable CUDA
pycnn.init(
image_size=64, # If unspecified the default is 64
batch_size=32, # If unspecified the default is 32
layers=[256, 128, 64, 32, 16, 8, 4], # Allows you to define any type of dense layer, If unspecified the default is [128, 64]
learning_rate=0.0001, # If unspecified the default is 0.0001
epochs=1000, # If unspecified the default is 50
filters = [
[# Custom filter 1],
[# Custom filter 2],
[# Custom filter 3],
[# Custom filter ...],
] # If unspecified, the framework will use the default filters.
)
pycnn.adam() # If specified, the framework will use the adam optimizer.
pycnn.dataset.local(
path_to_you_dataset_folder,
max_image=1000 # If unspecified, the framework will use all images from each class.
) # Use this method if you want to load your local dataset folder.
pycnn.dataset.hf(
huggingface_dataset_name,
max_image=1000, # If unspecified, the framework will use all images from each class.
cached=True, # Using the cached database helps you bypass downloading the dataset each time it is loaded (the default behavior when cached=True).
split="train", # Specify which split of the dataset to use for training the model (the default is the train split).
aug = [
1, # Left-Right Flip
2, # Top-Bottom Flip
3, # 90 degree rotation
4 # -90 degree rotation
] # Unspecify this setting if you don't want a dataset augmentation
) # Use this method if you want to load a HuggingFace dataset folder.
pycnn.train_model(
visualize=True, # Displays a real-time graph of accuracy and loss per epoch when enabled. Set to False or leave unspecified to disable this feature.
early_stop=2 # Stops training when overfitting begins and the number of epochs exceeds early_stop. Set to 0 or leave unspecified to disable this feature.
) pycnn.save_model(path) # For saving models (if your your_save_path is unspecified the framework will save it in "./model.bin" bu default)
pycnn.load_model(path) # For loading models
pycnn.torch(path) # For saving PyTorch compatible models (to use them in PyTorch later)result = pycnn.predict(your_image_path) # Returns a tuple of (class name, confidense value)
print(result) The framework will automatically convert weights, biases, and datasets to the selected backend. Models trained on GPU can still be loaded on CPU and vice versa.
from pycnn.pycnn import PyCNN
from os import listdir
pycnn = PyCNN()
pycnn.cuda(True)
pycnn.init(
layers=[512, 256],
epochs=500,
)
pycnn.dataset.hf("cifar10", max_image=500, cached=True)
pycnn.adam()
pycnn.train_model(early_stop=15)
pycnn.save_model("pycnn_cifar10.bin")
testdir = "cifar10_test"
_max = 1000
for classname in listdir(testdir):
x = 0
correct = 0
for filename in listdir(f"{testdir}/{classname}"):
if x == _max:
break
if pycnn.predict(f"{testdir}/{classname}/{filename}")[0] == classname:
correct += 1
x += 1
print(classname, correct)Output:
- Total prediction accuracy: 48.1%, which is a strong result for a model trained on only 500 images per class.
Hardware used while training:
- Create a PyTorch CNN model with PyCNN:
from pycnn.pycnn import PyCNN
# Initialize PyCNN model
pycnn = PyCNN()
pycnn.init(
epochs=50,
layers=[64, 32],
learning_rate=0.0001
)
# Load dataset from Hugging Face
pycnn.dataset.hf("cifar10", max_image=50, aug=[])
# Configure Adam optimizer and train
pycnn.adam()
pycnn.train_model()
# Save the model in a PyTorch format
pycnn.torch("model.pth")- Load and use the model.pth in PyTorch:
from pycnn.pycnn import PyCNNTorchModel
from PIL import Image
import numpy as np
import torch
checkpoint = torch.load('model.pth', map_location='cpu')
model = PyCNNTorchModel(
checkpoint['layers'],
checkpoint['num_classes'],
checkpoint['filters'],
checkpoint['image_size']
)
model.load_state_dict(checkpoint['model_state_dict'])
model.eval()
def predict(image_path):
img = Image.open(image_path).convert("RGB")
img = img.resize((checkpoint['image_size'], checkpoint['image_size']), Image.Resampling.LANCZOS)
img_array = np.array(img).astype(np.float32) / 255.0
img_tensor = torch.from_numpy(img_array).permute(2, 0, 1).unsqueeze(0)
with torch.no_grad():
output = model(img_tensor)
confidence, predicted_idx = torch.max(output, 1)
predicted_class = checkpoint['classes'][predicted_idx.item()]
print(f"Prediction: {predicted_class} (Confidence: {confidence.item()*100:.2f}%)")
predict("exemple.png")| Metric | Value (example) |
|---|---|
| Accuracy | ~90% |
| Epochs | 1000 |
| Dataset | ~500 image for each class |
pip install git+https://github.com/77AXEL/PyCNN.gitOptional: Install CuPy for CUDA support:
pip install cupy-cuda118 # Match your CUDA version- See the CUDA Documentation for more information on how to set it up
We welcome issues, suggestions, and contributions! Check the Discussions tab or see CONTRIBUTING.md
Found a security issue? Please report privately to: π§ a.x.e.l777444000@gmail.com
Released under the MIT License
. See the PyCNN Documentation for more informations and guidelines



