Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 40 additions & 63 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,77 +1,42 @@
<h1 align="center">
Goldeneye
GoldenBox
</h1>

<p align="center">
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/license-MIT-blue"></a>
</p>

<p align="center">
<a href="#background">Background</a> •
<a href="#usage">Usage</a> •
<a href="#background">Overview</a> •
<a href="#Installing">Installing</a> •
<a href="#code">Code</a> •
<a href="#acknowledgements">Acknowledgements</a> •
<a href="#citation">Citation</a> •
<!-- <a href="#citation">Citation</a> • -->
<a href="#license">License</a>
</p>

## Background
## Overview

GoldenEye is a functional simulator with fault injection capabilities for common and emerging numerical formats, implemented for the PyTorch deep learning framework. GoldenEye provides a unified framework for numerical format evaluation of DNNs, including traditional number systems such as fixed and floating point, as well as recent DNN-inspired formats such as block floating point and AdaptivFloat. Additionally, GoldenEye enables single- and multi- bit flips at various logical and functional points during a value’s lifetime for resiliency analysis, including for the first time attention to numerical values’ hardware metadata. GoldenEye is an easy-to-use, extensible, versatile, and fast tool for dependability research and future DNN accelerator design.

![](https://user-images.githubusercontent.com/89948656/176387208-cfd64047-3841-4abf-bf54-5d2e63f5a2e5.png)


## Usage

Take a look at our documentation [here](https://goldeneyedocs.readthedocs.io/en/stable/index.html).
GoldenEye Object Detection is an extension of the original [GoldenEye](https://github.com//ma3mool/goldeneye) functional simulator with fault injection capabilities for common and emerging numerical formats. Previously the simulator was only supported image classification models. Now, we have extended our use case to object detection models as well.

### Installing

**Ubuntu with Sudo Privileges**
1. Recursively clone the goldeneye repository.
**Ubuntu-20.04 or later**
1. Clone the goldeneye repository.
```bash
git clone --recurse-submodules git@github.com:ma3mool/goldeneye.git
git clone https://github.com/sajidahmed12/goldeneye-object-detection
```

2. Download ninja-build which is needed for qtorch.
2. Download ninja-build, which is needed for qtorch.
```bash
sudo apt install ninja-build
```

3. Download the other project dependencies. Please make sure you are inside the goldeneye folder when applying this command.
3. Install the other project dependencies from the requirements.txt file.
```bash
pip install -r requirements.txt
```

4. Setup environment variable (replace with the directory where the imagenet dataset is downloaded).
```bash
ML_DATASETS=/dir/to/imagenet/
```

**Docker**
1. Recursively clone the goldeneye repository.
```bash
git clone --recurse-submodules git@github.com:ma3mool/goldeneye.git
```

2. Pull the goldeneye docker image and rename it to simply the next steps
```bash
docker pull goldeneyetool/goldeneye:latest
docker image tag goldeneyetool/goldeneye goldeneye
```

3. Within the goldeneye folder, run the shell on the pulled docker image. Make sure to replace [/path/to/imagenet] with the actual path to your downloaded imagenet dataset.
```bash
cd goldeneye
docker run -ti
--mount type=bind,source=`pwd`/src/,target=/src
--mount type=bind,source=`pwd`/val/,target=/val
--mount type=bind,source=`pwd`/scripts/,target=/scripts
--mount type=bind,source=[/path/to/imagenet],target=/datasets/imagenet
goldeneye
```

### Testing

```bash
Expand All @@ -81,30 +46,42 @@ pytest val/test_num_sys.py
## Code

### Structure
The ```scripts``` folder includes wrappers around the goldeneye framework to simplify its use. The ```src``` folder contains all of the goldeneye core logic such as number system implementation and error injection routines. The ```val``` folder is used for unit-testing the code. You can run it using pytest to check that the installation process was successful.
The ```scripts``` folder includes wrappers around the goldeneye-obj framework to simplify its use. The ```src``` folder contains all of the core components, such as number system implementation, error injection routines, dataloaders, etc. The ```val``` folder is used for unit testing the code. You can run it using pytest to check that the installation process was successful.

## Acknowledgements

- Tarek Aloui (Harvard)
- David Brooks (Harvard)
- Abdulrahman Mahmoud (Harvard)
- Joshua Park (Harvard)
- Thierry Tambe (Harvard)
- Gu-Yeon Wei (Harvard)

## Citation
Example Outputs are saved in this Google Drive [link](https://drive.google.com/drive/folders/1nP0pavu3vprPc9EvuahkF9UsETDlwFEp?usp=sharing)

If you use or reference Goldeneye, please cite:
## Example Commands

Pre-processing
```
@INPROCEEDINGS{GoldeneyeMahmoudTambeDSN2022,
author={A. {Mahmoud} and T. {Tambe} and T. {Aloui} and D. {Brooks} and G. {Wei}},
booktitle={2022 52nd Annual IEEE/IFIP International Conference on Dependable Systems and Networks (DSN)},
title={GoldenEye: A Platform for Evaluating Emerging Data Formats in DNN Accelerators},
year={2022},
}
python preprocess.py -b 16 -n frcnn -d COCO -w 8 -P FP32 -f fp_n -C 0 [MS-COCO FP32](MS-COCO FP32])
```

## License
Profiling
```
python profiling.py -b 16 -n frcnn -d COCO -w 16 -P FP32 -f fp_n -B 32 -R 23
```

Split Data
```
python split_data.py -b 16 -n frcnn -d COCO -o -w 16 -P FP32 -f fp_n -B 32 -R 23
```

Error Injections
```
python injections.py -b 16 -n frcnn -d COCO -w 16 -P FP32 -i 102400 -I 1 -f fp_n -B 32 -R 23
```

Post-processing
```
python postprocess.py -b 16 -n frcnn -d COCO -w 16 -P FP32 -i 102400 -I 1 -f fp_n -B 32 -R 23
```

## Acknowledgements

- This Repository was forked from [Goldeneye](https://github.com/ma3mool/goldeneye/) developed and maintained by [Sajid Ahmed](https://sajidahmed12.github.io) & [Dr. Abdulrahman Mahmoud](https://ma3mool.github.io/)

## License
<a href="LICENSE">MIT License</a>
Empty file added data/put-your-data-here.txt
Empty file.
Empty file added models/__init__.py
Empty file.
229 changes: 229 additions & 0 deletions models/densenet.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
import os
from collections import OrderedDict

import torch
import torch.nn as nn
import torch.nn.functional as F

__all__ = ["DenseNet", "densenet121", "densenet169", "densenet161"]


class _DenseLayer(nn.Sequential):
def __init__(self, num_input_features, growth_rate, bn_size, drop_rate):
super(_DenseLayer, self).__init__()
self.add_module("norm1", nn.BatchNorm2d(num_input_features)),
self.add_module("relu1", nn.ReLU(inplace=True)),
self.add_module(
"conv1",
nn.Conv2d(
num_input_features,
bn_size * growth_rate,
kernel_size=1,
stride=1,
bias=False,
),
),
self.add_module("norm2", nn.BatchNorm2d(bn_size * growth_rate)),
self.add_module("relu2", nn.ReLU(inplace=True)),
self.add_module(
"conv2",
nn.Conv2d(
bn_size * growth_rate,
growth_rate,
kernel_size=3,
stride=1,
padding=1,
bias=False,
),
),
self.drop_rate = drop_rate

def forward(self, x):
new_features = super(_DenseLayer, self).forward(x)
if self.drop_rate > 0:
new_features = F.dropout(
new_features, p=self.drop_rate, training=self.training
)
return torch.cat([x, new_features], 1)


class _DenseBlock(nn.Sequential):
def __init__(self, num_layers, num_input_features, bn_size, growth_rate, drop_rate):
super(_DenseBlock, self).__init__()
for i in range(num_layers):
layer = _DenseLayer(
num_input_features + i * growth_rate, growth_rate, bn_size, drop_rate
)
self.add_module("denselayer%d" % (i + 1), layer)


class _Transition(nn.Sequential):
def __init__(self, num_input_features, num_output_features):
super(_Transition, self).__init__()
self.add_module("norm", nn.BatchNorm2d(num_input_features))
self.add_module("relu", nn.ReLU(inplace=True))
self.add_module(
"conv",
nn.Conv2d(
num_input_features,
num_output_features,
kernel_size=1,
stride=1,
bias=False,
),
)
self.add_module("pool", nn.AvgPool2d(kernel_size=2, stride=2))


class DenseNet(nn.Module):
r"""Densenet-BC model class, based on
`"Densely Connected Convolutional Networks" <https://arxiv.org/pdf/1608.06993.pdf>`_

Args:
growth_rate (int) - how many filters to add each layer (`k` in paper)
block_config (list of 4 ints) - how many layers in each pooling block
num_init_features (int) - the number of filters to learn in the first convolution layer
bn_size (int) - multiplicative factor for number of bottle neck layers
(i.e. bn_size * k features in the bottleneck layer)
drop_rate (float) - dropout rate after each dense layer
num_classes (int) - number of classification classes
"""

def __init__(
self,
growth_rate=32,
block_config=(6, 12, 24, 16),
num_init_features=64,
bn_size=4,
drop_rate=0,
num_classes=10,
):

super(DenseNet, self).__init__()

# First convolution

# CIFAR-10: kernel_size 7 ->3, stride 2->1, padding 3->1
self.features = nn.Sequential(
OrderedDict(
[
(
"conv0",
nn.Conv2d(
3,
num_init_features,
kernel_size=3,
stride=1,
padding=1,
bias=False,
),
),
("norm0", nn.BatchNorm2d(num_init_features)),
("relu0", nn.ReLU(inplace=True)),
("pool0", nn.MaxPool2d(kernel_size=3, stride=2, padding=1)),
]
)
)
# END

# Each denseblock
num_features = num_init_features
for i, num_layers in enumerate(block_config):
block = _DenseBlock(
num_layers=num_layers,
num_input_features=num_features,
bn_size=bn_size,
growth_rate=growth_rate,
drop_rate=drop_rate,
)
self.features.add_module("denseblock%d" % (i + 1), block)
num_features = num_features + num_layers * growth_rate
if i != len(block_config) - 1:
trans = _Transition(
num_input_features=num_features,
num_output_features=num_features // 2,
)
self.features.add_module("transition%d" % (i + 1), trans)
num_features = num_features // 2

# Final batch norm
self.features.add_module("norm5", nn.BatchNorm2d(num_features))

# Linear layer
self.classifier = nn.Linear(num_features, num_classes)

# Official init from torch repo.
for m in self.modules():
if isinstance(m, nn.Conv2d):
nn.init.kaiming_normal_(m.weight)
elif isinstance(m, nn.BatchNorm2d):
nn.init.constant_(m.weight, 1)
nn.init.constant_(m.bias, 0)
elif isinstance(m, nn.Linear):
nn.init.constant_(m.bias, 0)

def forward(self, x):
features = self.features(x)
out = F.relu(features, inplace=True)
out = F.adaptive_avg_pool2d(out, (1, 1)).view(features.size(0), -1)
out = self.classifier(out)
return out


def _densenet(
arch,
growth_rate,
block_config,
num_init_features,
pretrained,
progress,
device,
**kwargs
):
model = DenseNet(growth_rate, block_config, num_init_features, **kwargs)
if pretrained:
script_dir = os.path.dirname(__file__)
state_dict = torch.load(
script_dir + "/state_dicts/" + arch + ".pt", map_location=device
)
model.load_state_dict(state_dict)
return model


def densenet121(pretrained=False, progress=True, device="cpu", **kwargs):
r"""Densenet-121 model from
`"Densely Connected Convolutional Networks" <https://arxiv.org/pdf/1608.06993.pdf>`_

Args:
pretrained (bool): If True, returns a model pre-trained on ImageNet
progress (bool): If True, displays a progress bar of the download to stderr
"""
return _densenet(
"densenet121", 32, (6, 12, 24, 16), 64, pretrained, progress, device, **kwargs
)


def densenet161(pretrained=False, progress=True, device="cpu", **kwargs):
r"""Densenet-161 model from
`"Densely Connected Convolutional Networks" <https://arxiv.org/pdf/1608.06993.pdf>`_

Args:
pretrained (bool): If True, returns a model pre-trained on ImageNet
progress (bool): If True, displays a progress bar of the download to stderr
"""
return _densenet(
"densenet161", 48, (6, 12, 36, 24), 96, pretrained, progress, device, **kwargs
)


def densenet169(pretrained=False, progress=True, device="cpu", **kwargs):
r"""Densenet-169 model from
`"Densely Connected Convolutional Networks" <https://arxiv.org/pdf/1608.06993.pdf>`_

Args:
pretrained (bool): If True, returns a model pre-trained on ImageNet
progress (bool): If True, displays a progress bar of the download to stderr
"""
return _densenet(
"densenet169", 32, (6, 12, 32, 32), 64, pretrained, progress, device, **kwargs
)
Loading