diff --git a/hpvm/projects/torch2hpvm/torch2hpvm/compile.py b/hpvm/projects/torch2hpvm/torch2hpvm/compile.py
index 06c9a1c297f3bdfd69a2871387a71b91f37aae0e..f76b801ef9e577d1308fa0ca83c7339045ca69d9 100644
--- a/hpvm/projects/torch2hpvm/torch2hpvm/compile.py
+++ b/hpvm/projects/torch2hpvm/torch2hpvm/compile.py
@@ -62,18 +62,17 @@ class ModelExporter:
     def export_datasets(self, n_images: Optional[int]):
         from PIL import Image
         from math import log10, ceil
-
-        labels = []
-        n_images = self.dataset_size if n_images is None else n_images
-        n_digits = int(ceil(log10(n_images)))
-        for i in range(n_images):
+        if n_images:
+            indices = torch.randperm(self.dataset_size)[:n_images].numpy()
+        else:
+            indices = range(self.dataset_size)
+        n_digits = int(ceil(log10(self.dataset_size)))
+        for i in indices:
             image, label = self.dataset[i]
             image = (image - image.min()) / (image.max() - image.min()) * 255
             image = image.transpose((1, 2, 0)).astype(np.uint8)
             name = str(i).zfill(n_digits)
-            Image.fromarray(image).save(self.dataset_dir / f"{name}.jpg")
-            labels.append(label)
-        np.array(labels).tofile(self.output_dir / self.label_name)
+            Image.fromarray(image).save(self.dataset_dir / f"{name}_{label}.jpg")
         return self
 
     def compile(self, output_binary: PathLike, working_dir: Optional[PathLike] = None):
diff --git a/hpvm/projects/torch2hpvm/torch2hpvm/graph_ir.py b/hpvm/projects/torch2hpvm/torch2hpvm/graph_ir.py
index 3ddcb1868576ab9f09444a060a371e1817d1ee3c..06907cd2777838df67e9c9a9a846988cf5ae111c 100644
--- a/hpvm/projects/torch2hpvm/torch2hpvm/graph_ir.py
+++ b/hpvm/projects/torch2hpvm/torch2hpvm/graph_ir.py
@@ -105,6 +105,9 @@ class WeightTensor(TensorNode):
 
     def dump_weight(self, file_name: PathLike, to_fp16: bool = False):
         data = self.input_data.astype(np.float16) if to_fp16 else self.input_data
+        if len(data.shape) == 2:
+            # weight tensor needs to be transposed
+            data = data.T
         data.tofile(file_name)
 
     def transpose_(self):
diff --git a/hpvm/test/epoch_dnn/assets/miniera/miniera.pth b/hpvm/test/epoch_dnn/assets/miniera/miniera.pth
index f264a4ea67f88c361923e7c7f0208703001a622d..6796117d7821bc9574ffbb7194f21a03dc559e73 100644
Binary files a/hpvm/test/epoch_dnn/assets/miniera/miniera.pth and b/hpvm/test/epoch_dnn/assets/miniera/miniera.pth differ
diff --git a/hpvm/test/epoch_dnn/assets/miniera/scales/calib_NONE.txt b/hpvm/test/epoch_dnn/assets/miniera/scales/calib_NONE.txt
index 9bffa5b8d0b5e315820ac3209c4796f1de2c44e5..f99b4434b6f8e6491e738928e80f3ed97bbc1cb0 100644
--- a/hpvm/test/epoch_dnn/assets/miniera/scales/calib_NONE.txt
+++ b/hpvm/test/epoch_dnn/assets/miniera/scales/calib_NONE.txt
@@ -1,4 +1,4 @@
-nput:	0.007874015748031496 
+input:	0.007874015748031496
 conv1:	0.041152522047244094
 add1:	0.041152522047244094
 relu1:	0.03673215196850394
@@ -19,4 +19,3 @@ relu5:	0.20020370078740157
 gemm2:	0.6007037007874017
 add6:	0.6007037007874017
 softmax1:	0.007874015748031496
-
diff --git a/hpvm/test/epoch_dnn/main.py b/hpvm/test/epoch_dnn/main.py
index fb02a15f40177d01e134fd4afbd8fec77290e167..2a66aae2009739d066aed8aa91a2f8d0fb611869 100644
--- a/hpvm/test/epoch_dnn/main.py
+++ b/hpvm/test/epoch_dnn/main.py
@@ -9,7 +9,7 @@ from torch2hpvm import BinDataset, ModelExporter
 self_folder = Path(__file__).parent.absolute()
 site.addsitedir(self_folder.as_posix())
 
-from torch_dnn import MiniERA, quantize
+from torch_dnn import MiniERA, quantize, CIFAR
 
 
 # Consts (don't change)
@@ -38,7 +38,7 @@ def run_test_over_ssh(host: str, password: str, working_dir: str, image_dir: Pat
 
     print(f"Running test on remote host {host}...")
     args = options.split(" ") + [host]
-    child = pexpect.spawn("ssh", args)
+    child = pexpect.spawn("ssh", args, timeout=60)
     child.expect(r"password:")
     child.sendline(password)
     child.expect("# ")  # The bash prompt
@@ -62,7 +62,7 @@ def run_test_over_ssh(host: str, password: str, working_dir: str, image_dir: Pat
 ASSET_DIR = self_folder / "assets/miniera"
 QUANT_STRAT = "NONE"  # Quantization method
 WORKING_DIR = Path("/tmp/miniera")
-N_IMAGES = 100
+N_IMAGES = 50
 # Remote configs
 SCP_OPTS = "-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -P 5506"
 SSH_OPTS = "-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -p 5506"
@@ -70,14 +70,17 @@ SCP_HOST = "root@espgate.cs.columbia.edu"
 SCP_PWD = "openesp"
 SCP_DST = "~/NV_NVDLA"
 
+# Reproducibility
+np.random.seed(42)
 
-makedirs(WORKING_DIR, exist_ok=True)
+makedirs(WORKING_DIR, exist_ok=False)
 
 # Calculate quantization scales
 ckpt = (ASSET_DIR / "miniera.pth").as_posix()
 model = MiniERA()
 model.load_state_dict(torch.load(ckpt))
-scale_output = quantize(model, ASSET_DIR, QUANT_STRAT, WORKING_DIR)
+dataset = CIFAR.from_file(ASSET_DIR / "input.bin", ASSET_DIR / "labels.bin")
+scale_output = quantize(model, dataset, QUANT_STRAT, WORKING_DIR)
 
 # Code generation (into /tmp/miniera/hpvm-mod.nvdla)
 nvdla_buffer = WORKING_DIR / BUFFER_NAME
@@ -85,7 +88,7 @@ print(f"Generating NVDLA buffer into {nvdla_buffer}")
 bin_dataset = BinDataset(
     ASSET_DIR / "input.bin", ASSET_DIR / "labels.bin", (5000, 3, 32, 32)
 )
-exporter = ModelExporter(model, bin_dataset, WORKING_DIR, scale_output)
+exporter = ModelExporter(model, bin_dataset, WORKING_DIR, ASSET_DIR / "scales/calib_NONE.txt")
 exporter.generate(n_images=N_IMAGES).compile(WORKING_DIR / "miniera", WORKING_DIR)
 
 # SCP essential files to remote device
@@ -93,8 +96,11 @@ input_images = exporter.dataset_dir
 split_and_scp([nvdla_buffer, input_images], SCP_HOST, SCP_DST, SCP_PWD, SCP_OPTS)
 
 # SSH to run test remotely
-labels_file = WORKING_DIR / exporter.label_name
-labels = np.fromfile(labels_file, dtype=np.int32)
+n_total, correct = 0, 0
 for image_path, output in run_test_over_ssh(SCP_HOST, SCP_PWD, SCP_DST, input_images, SSH_OPTS):
-    idx = int(image_path.stem)
-    print(idx, np.array(output).argmax(), labels[idx])
+    idx, label = [int(s) for s in image_path.stem.split("_")]
+    output = np.array(output)
+    print(idx, output.argmax(), label, output)
+    n_total += 1
+    correct += int(output.argmax() == label)
+print(f"Accuracy: {correct / n_total * 100}% ({n_total} images)")
diff --git a/hpvm/test/epoch_dnn/torch_dnn/miniera.py b/hpvm/test/epoch_dnn/torch_dnn/miniera.py
index 84c88ac8f882b4b6d1ba98cdb3a88f92cf418075..3e200673189185b0a5e3c19d037ca47e4ba0154a 100644
--- a/hpvm/test/epoch_dnn/torch_dnn/miniera.py
+++ b/hpvm/test/epoch_dnn/torch_dnn/miniera.py
@@ -36,8 +36,8 @@ class MiniERA(Module):
         for conv in self.convs:
             if not isinstance(conv, Conv2d):
                 continue
-            weight_np = np.fromfile(prefix / "conv2d_{count+1}_w.bin", dtype=np.float32)
-            bias_np = np.fromfile(prefix / "conv2d_{count+1}_b.bin", dtype=np.float32)
+            weight_np = np.fromfile(prefix / f"conv2d_{count+1}_w.bin", dtype=np.float32)
+            bias_np = np.fromfile(prefix / f"conv2d_{count+1}_b.bin", dtype=np.float32)
             conv.weight.data = torch.tensor(weight_np).reshape(conv.weight.shape)
             conv.bias.data = torch.tensor(bias_np).reshape(conv.bias.shape)
             count += 1
@@ -46,8 +46,8 @@ class MiniERA(Module):
         for linear in self.fcs:
             if not isinstance(linear, Linear):
                 continue
-            weight_np = np.fromfile(prefix / "dense_{count+1}_w.bin", dtype=np.float32)
-            bias_np = np.fromfile(prefix / "dense_{count+1}_b.bin", dtype=np.float32)
+            weight_np = np.fromfile(prefix / f"dense_{count+1}_w.bin", dtype=np.float32)
+            bias_np = np.fromfile(prefix / f"dense_{count+1}_b.bin", dtype=np.float32)
             cout, cin = linear.weight.shape
             linear.weight.data = torch.tensor(weight_np).reshape(cin, cout).T
             linear.bias.data = torch.tensor(bias_np).reshape(linear.bias.shape)
diff --git a/hpvm/test/epoch_dnn/torch_dnn/quantizer.py b/hpvm/test/epoch_dnn/torch_dnn/quantizer.py
index 8543f80603ab70bade01414664029ade083dcde6..7bbbbda45c3848f7772ea63a0afe875886ed477b 100644
--- a/hpvm/test/epoch_dnn/torch_dnn/quantizer.py
+++ b/hpvm/test/epoch_dnn/torch_dnn/quantizer.py
@@ -6,6 +6,7 @@ from shutil import move
 
 import distiller
 import torch
+from torch.utils.data.dataset import Dataset
 import yaml
 from distiller.data_loggers import collect_quant_stats
 from distiller.quantization import PostTrainLinearQuantizer
@@ -13,7 +14,6 @@ from torch import nn
 from torch.utils.data import DataLoader
 
 from .datasets import CIFAR
-from .miniera import MiniERA
 
 PathLike = Union[str, Path]
 STATS_FILENAME = "acts_quantization_stats.yaml"
@@ -38,15 +38,13 @@ LAYER_DISTILLER_NAME = {
 
 def quantize(
     model: nn.Module,
-    dataset_path: PathLike,
+    dataset: Dataset,
     strat: str = "NONE",
     working_dir: PathLike = ".",
     output_name: str = "calib.txt",
 ):
     # possible quant strats ['NONE', 'AVG', 'N_STD', 'GAUSS', 'LAPLACE']
     print("Quantizing...")
-    dataset_path = Path(dataset_path)
-    dataset = CIFAR.from_file(dataset_path / "input.bin", dataset_path / "labels.bin")
     dataloader = DataLoader(dataset, batch_size=1)
 
     # Collect Pre Quantization Stats
@@ -57,12 +55,13 @@ def quantize(
     if not os.path.isfile(stats_file):
         # generates `stats_file`
         collect_quant_stats(
-            model, lambda model: evaluate(model, dataloader), save_dir=working_dir
+            model, lambda model: get_loss(model, dataloader), save_dir=working_dir
         )
 
     # Generate Quantized Scales
+    new_model = deepcopy(model)
     quantizer = PostTrainLinearQuantizer(
-        deepcopy(model),
+        new_model,
         model_activation_stats=stats_file,
         mode="SYMMETRIC",
         bits_activations=8,
@@ -77,7 +76,7 @@ def quantize(
     # We don't need QUANT_AFTER_FILENAME, remove it
     Path(QUANT_AFTER_FILENAME).unlink()
 
-    print("Quantization process finished.")
+    print(f"Quantization process finished; accuracy {evaluate(new_model, dataloader)}%")
     # converts .yaml file stats to hpvm standard
     generate_calib_file(model, working_dir, working_dir / output_name)
     return working_dir / output_name
@@ -96,7 +95,6 @@ def generate_calib_file(model: nn.Module, working_dir: Path, output_file: Path):
     input_scale = max(abs(input_min_max["min"]), abs(input_min_max["max"])) / 127
     lines.append(f"input:\t{input_scale}\n")
 
-    # because of definition of miniera
     layer_count = {
         nn.ReLU: 0,
         nn.Linear: 0,
@@ -131,7 +129,7 @@ def generate_calib_file(model: nn.Module, working_dir: Path, output_file: Path):
 
 
 @torch.no_grad()
-def evaluate(model: MiniERA, dataloader: DataLoader):
+def get_loss(model: nn.Module, dataloader: DataLoader):
     from torch.nn import functional as F
 
     # Turn on evaluation mode which disables dropout.
@@ -142,3 +140,17 @@ def evaluate(model: MiniERA, dataloader: DataLoader):
         output = model(data)
         total_loss += len(data) * F.cross_entropy(output, targets)
     return total_loss / len(dataloader)
+
+
+@torch.no_grad()
+def evaluate(model: nn.Module, dataloader: DataLoader):
+    model.eval()
+    correct = 0
+    total = 0
+    for data in dataloader:
+        images, labels = data[0], data[1]
+        outputs = model(images)
+        _, predicted = torch.max(outputs.data, 1)
+        total += labels.size(0)
+        correct += (predicted == labels).sum().item()
+    return 100 * correct / total