---
# System prepended metadata

title: NOC-HW1
tags: [NoC]

---

# Machine Learning Intelligent Chip Design
# [HW1] Implementation of AlexNet in SystemC

## Description

In this task, you are required to implement the AlexNet convolutional neural network architecture using SystemC. AlexNet is a seminal deep learning model that achieved significant breakthroughs in image classification tasks. The network consists of multiple layers, including convolutional layers, max-pooling layers, and fully connected layers.

## Implementation Details

* **Network Architecture**:
You are provided with the network architecture details including the number of layers, the size of input and output feature maps, filter sizes, and strides.

* **Input Data**:
Input data for the network will be provided to you. Each input image will have the appropriate dimensions compatible with the network's input layer.

* **Weights and Biases**:
The weights and biases for each layer of the network will be provided. These parameters are essential for the convolutional and fully connected layers' computations.

* **Simulation**:
Once you have implemented the network in SystemC and integrated the input data, weights, and biases, you should simulate the network to obtain the predicted output. This will involve passing the input data through the network layers, applying convolutional operations, activation functions, and pooling, followed by fully connected layers, until you get the final output.

## Alexnet Training Model

![image](https://hackmd.io/_uploads/H1hIi_w36.png)


## The Pre-trained AlexNet Model Information
![image](https://hackmd.io/_uploads/H1J4jdvhT.png)

## Provided Data Description
Values in the pre-train model in Pytorch are floating point with 16 digits after the decimal. We export these value as txt file for you. Values in these txt files are floating point but rounded to the sixth decimal place.
* **Model layer parameters**
![image](https://hackmd.io/_uploads/ryll37_2a.png)
* **imagenet_classes.txt**
https://gist.github.com/ageitgey/4e1342c10a71981d0b491e1b8227328b
* **Input Data**
    * dog.txt
    ![dog1](https://hackmd.io/_uploads/r1_otu_n6.jpg)
    * cat.txt
    ![cat3](https://hackmd.io/_uploads/BJgC5u_ha.jpg)


## Reference Result

* **Simulation results of AlexNet executed in Python**
    * Dog
    ![image](https://hackmd.io/_uploads/HJLDft_36.png)
    * Cat
    ![image](https://hackmd.io/_uploads/SklONKun6.png)


* **Simulation results of AlexNet executed in SystemC**
    * Dog
    ![image](https://hackmd.io/_uploads/ByuETdu2a.png)
    * Cat
    ![image](https://hackmd.io/_uploads/rJwiftd2T.png)

## Implement Notes
The purpose of this assignment is just to make students familiar with SystemC, so as long as the execution results are correct, we will not restrict how students implement it.

Here are some tips for your reference:
- You can use one `SC_MODULE` to implement the entire module, or implement each layer with different `SC_MODULE`.
- You can use `sc_signal` to connect different modules.
- We strongly recommend building a monitor module to receive output and print out the execution results.

## Submission Guidelines

* Please compress a folder named HW<ID>_<studend-ID> into a zip file with the same name and upload it to E3.
* The folder should including:
    * Report (Name: HW<ID>_<student ID>.pdf)
    * Code
    * Makefile
* Example:
    ![image](https://hackmd.io/_uploads/SyIj4WCna.png =35%x)
* You don't need to upload parameters.
* Ensure that your code is well-commented and organized for clarity and understanding.
* **Plagiarism is forbidden, otherwise you will get 0 point!!!**


## Deliverables

* **SystemC Implementation**:
    Complete implementation of AlexNet architecture using SystemC.

* **Report**: 
    A brief report documenting containing
    - Simulation results demonstrating the predicted output for the provided input data.
    - Your implementation approach, challenges faced, and any observations or insights gained during the implementation and simulation process.
    
# Appendix

## Generating Input Data for Image Classification Model
```=python
# Generate Input data 
import torchvision.transforms as transforms
import torchvision.datasets as datasets
import scipy.io as io
import numpy as np

# Define transformation for input data
transform = transforms.Compose([
    transforms.Resize((224, 224)),  
    transforms.ToTensor(),           
    transforms.Normalize(            
        mean=[0.485, 0.456, 0.406],   
        std=[0.229, 0.224, 0.225]     
    )
])

# Load dataset
dataset = datasets.ImageFolder(root='C:/Users/micha/Desktop/dataset', transform=transform)

# Print class labels and number of images in dataset
print("Class labels:", dataset.classes)
print("Number of images:", len(dataset))

# Get information of the first image in the dataset
image, label = dataset[3]
print("First image shape:", image.shape)
print("First image label:", label)

# Convert image to numpy array and save it to a txt file
result = np.array(image)
result_2d = result.reshape(-1, result.shape[-1])
np.savetxt('input_1.txt', result_2d)
```
## Extracting and Saving Model Parameters for AlexNet
``` =python
# Importing necessary libraries
from torchvision import models
import torchinfo

# Loading the pre-trained AlexNet model
alexnet = models.alexnet(pretrained=True, progress=True)

# Print the total number of parameters in the model
print('Total number of parameters:', sum([param.numel() for param in alexnet.parameters()]))

# Print detailed model information using torchinfo
torchinfo.summary(alexnet, (3, 224, 224), batch_dim=0, col_names=("input_size", "output_size", "num_params", "kernel_size", "mult_adds"), verbose=0)

# Iterate through the model parameters and save them to separate txt files
for name, param in alexnet.named_parameters():
    if 'weight' in name:
        file_name = name.replace('.', '_')
        weight_data = param.data.flatten().cpu().numpy()
        with open(f'{file_name}.txt', 'w') as f:
            for val in weight_data:
                f.write(f'{val:.6f}\n')
    elif 'bias' in name:
        file_name = name.replace('.', '_')
        bias_data = param.data.cpu().numpy()
        with open(f'{file_name}.txt', 'w') as f:
            for val in bias_data:
                f.write(f'{val:.6f}\n')

```
    
## Implementation of AlexNet Inference with Custom Parameters and Input Data
```=python
import torch
import torch.nn as nn
from torchvision import models

class MyAlexNet(nn.Module):
    def __init__(self):
        super(MyAlexNet, self).__init__()
        # Define the network architecture similar to pretrained AlexNet
        self.features = models.alexnet(pretrained=False).features
        self.avgpool = nn.AdaptiveAvgPool2d((6, 6))
        self.classifier = nn.Sequential(
            nn.Dropout(),
            nn.Linear(256 * 6 * 6, 4096),
            nn.ReLU(inplace=True),
            nn.Dropout(),
            nn.Linear(4096, 4096),
            nn.ReLU(inplace=True),
            nn.Linear(4096, 1000),
        )

    def forward(self, x):
        x = self.features(x)
        x = self.avgpool(x)
        x = torch.flatten(x, 1)
        x = self.classifier(x)
        return x

# Create a new instance of AlexNet
my_alexnet = MyAlexNet()

# Load weights and biases from saved parameter files
state_dict = {}
for name, param in my_alexnet.named_parameters():
    file_name = name.replace('.', '_') + '.txt'
    with open(file_name, 'r') as f:
        values = [float(line.strip()) for line in f.readlines()]
        state_dict[name] = torch.tensor(values).view_as(param)  # Ensure loaded parameters match the shape of current model parameters

# Set loaded parameters to the model
my_alexnet.load_state_dict(state_dict)

# Set the model to evaluation mode
my_alexnet.eval()

# Check the loaded model
print(my_alexnet)

#%%
import numpy as np
import torch
from torchvision import transforms
from PIL import Image
from torchvision import models

# Read data from text file
with open('dog.txt', 'r') as f:
    data = f.read()

# Process data (example: convert to NumPy array and reshape)
data_array = np.fromstring(data, dtype=float, sep='\n')
data_array = data_array.reshape((3, 224, 224))

# Convert to PyTorch tensor
data_tensor = torch.tensor(data_array, dtype=torch.float32)

# Normalize data (example: using torchvision.transforms.Normalize)
normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
preprocess = transforms.Compose([transforms.ToPILImage(), transforms.ToTensor(), normalize])
input_tensor0 = preprocess(data_tensor)

# Reshape tensor to match expected input shape of AlexNet (add batch dimension)
input_tensor = input_tensor0.unsqueeze(0)

# Set model to evaluation mode
my_alexnet.eval()

# Perform inference
output = my_alexnet(input_tensor)

# Load class labels from imagenet_classes.txt
with open('imagenet_classes.txt', 'r') as f:
    class_labels = [line.strip() for line in f.readlines()]

# Get predicted class index
predicted_index = torch.argmax(output, dim=1).item()

# Get predicted class label
predicted_label = class_labels[predicted_index]

print("Predicted class:", predicted_label)

```
    
## Reference
* [卷積神經網絡 CNN 經典模型 — LeNet、AlexNet、VGG、NiN with Pytorch code](https://medium.com/ching-i/%E5%8D%B7%E7%A9%8D%E7%A5%9E%E7%B6%93%E7%B6%B2%E7%B5%A1-cnn-%E7%B6%93%E5%85%B8%E6%A8%A1%E5%9E%8B-lenet-alexnet-vgg-nin-with-pytorch-code-84462d6cf60c)
* [alexnet.py](https://github.com/pytorch/vision/blob/main/torchvision/models/alexnet.py)
* [AlexNet, VGGNet, ResNet, and Inception](https://medium.com/@karandeepdps/alexnet-vggnet-resnet-and-inception-11880a1ed3cd)
*   [ImageNet Classification with Deep Convolutional Neural Networks](https://proceedings.neurips.cc/paper_files/paper/2012/file/c399862d3b9d6b76c8436e924a68c45b-Paper.pdf)

    
