mirror of https://github.com/commaai/tinygrad.git
getting 77% on imagenet eval
This commit is contained in:
parent
810f03dafa
commit
b705510d5c
|
@ -1,28 +1,53 @@
|
||||||
import os
|
# for imagenet download prepare.sh and run it
|
||||||
|
import os, glob, random
|
||||||
import json
|
import json
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
import functools
|
||||||
import torchvision.transforms as transforms
|
import torchvision.transforms as transforms
|
||||||
|
|
||||||
BASEDIR = "/Users/kafka/fun/imagenet"
|
BASEDIR = "/Users/kafka/fun/imagenet"
|
||||||
train_files = open(os.path.join(BASEDIR, "train_files")).read().strip().split("\n")
|
|
||||||
val_files = open(os.path.join(BASEDIR, "val_files")).read().strip().split("\n")
|
|
||||||
ci = json.load(open(os.path.join(BASEDIR, "imagenet_class_index.json")))
|
ci = json.load(open(os.path.join(BASEDIR, "imagenet_class_index.json")))
|
||||||
cir = {v[0]: int(k) for k,v in ci.items()}
|
cir = {v[0]: int(k) for k,v in ci.items()}
|
||||||
|
|
||||||
rrc = transforms.RandomResizedCrop(224)
|
@functools.lru_cache(None)
|
||||||
|
def get_train_files():
|
||||||
|
train_files = open(os.path.join(BASEDIR, "train_files")).read().strip().split("\n")
|
||||||
|
return [os.path.join(BASEDIR, "train", x) for x in train_files]
|
||||||
|
|
||||||
|
@functools.lru_cache(None)
|
||||||
|
def get_val_files():
|
||||||
|
#val_files = open(os.path.join(BASEDIR, "val_files")).read().strip().split("\n")
|
||||||
|
val_files = glob.glob(os.path.join(BASEDIR, "val", "*", "*"))
|
||||||
|
return val_files
|
||||||
|
|
||||||
|
#rrc = transforms.RandomResizedCrop(224)
|
||||||
|
import torchvision.transforms.functional as F
|
||||||
def image_load(fn):
|
def image_load(fn):
|
||||||
img = Image.open(fn).convert('RGB')
|
img = Image.open(fn).convert('RGB')
|
||||||
ret = np.array(rrc(img))
|
img = F.resize(img, 256, Image.BILINEAR)
|
||||||
|
img = F.center_crop(img, 224)
|
||||||
|
img = F.to_tensor(img)
|
||||||
|
img = F.normalize(img, mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225], inplace=False)
|
||||||
|
ret = np.array(img, dtype='float32')
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
def iterate(bs, val=False, shuffle=True):
|
||||||
|
files = get_val_files() if val else get_train_files()
|
||||||
|
order = list(range(0, len(files)))
|
||||||
|
if shuffle: random.shuffle(order)
|
||||||
|
for i in range(0, len(files), bs):
|
||||||
|
X = [image_load(files[i]) for i in order[i:i+bs]]
|
||||||
|
Y = [cir[files[i].split("/")[-2]] for i in order[i:i+bs]]
|
||||||
|
yield (np.array(X), np.array(Y))
|
||||||
|
|
||||||
def fetch_batch(bs, val=False):
|
def fetch_batch(bs, val=False):
|
||||||
files = val_files if val else train_files
|
files = get_val_files() if val else get_train_files()
|
||||||
samp = np.random.randint(0, len(files), size=(bs))
|
samp = np.random.randint(0, len(files), size=(bs))
|
||||||
files = [files[i] for i in samp]
|
files = [files[i] for i in samp]
|
||||||
X = [image_load(os.path.join(BASEDIR, "val" if val else "train", x)) for x in files]
|
X = [image_load(x) for x in files]
|
||||||
Y = [cir[x.split("/")[0]] for x in files]
|
Y = [cir[x.split("/")[0]] for x in files]
|
||||||
return np.transpose(np.array(X), (0,3,1,2)), np.array(Y)
|
return np.array(X), np.array(Y)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
X,Y = fetch_batch(64)
|
X,Y = fetch_batch(64)
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
import numpy as np
|
||||||
|
from tinygrad.tensor import Tensor
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# inference only
|
||||||
|
Tensor.training = False
|
||||||
|
Tensor.no_grad = True
|
||||||
|
|
||||||
|
# Resnet50-v1.5
|
||||||
|
from models.resnet import ResNet50
|
||||||
|
mdl = ResNet50()
|
||||||
|
mdl.load_from_pretrained()
|
||||||
|
|
||||||
|
# evaluation on the mlperf classes of the validation set from imagenet
|
||||||
|
from datasets.imagenet import iterate
|
||||||
|
n,d = 0,0
|
||||||
|
for x,y in iterate(32, True, shuffle=True):
|
||||||
|
dat = Tensor(x.astype(np.float32))
|
||||||
|
outs = mdl(dat)
|
||||||
|
t = outs.numpy().argmax(axis=1)
|
||||||
|
print(t)
|
||||||
|
print(y)
|
||||||
|
n += (t==y).sum()
|
||||||
|
d += len(t)
|
||||||
|
print(f"****** {n}/{d} {n*100.0/d:.2f}%")
|
||||||
|
|
||||||
|
|
|
@ -14,19 +14,17 @@ if __name__ == "__main__":
|
||||||
Tensor.no_grad = True
|
Tensor.no_grad = True
|
||||||
|
|
||||||
# Resnet50-v1.5
|
# Resnet50-v1.5
|
||||||
"""
|
|
||||||
from models.resnet import ResNet50
|
from models.resnet import ResNet50
|
||||||
mdl = ResNet50()
|
mdl = ResNet50()
|
||||||
img = Tensor.randn(1, 3, 224, 224)
|
img = Tensor.randn(1, 3, 224, 224)
|
||||||
test_model(mdl, img)
|
test_model(mdl, img)
|
||||||
"""
|
|
||||||
|
|
||||||
# Retinanet
|
# Retinanet
|
||||||
|
|
||||||
# 3D UNET
|
# 3D UNET
|
||||||
from models.unet3d import UNet3D
|
from models.unet3d import UNet3D
|
||||||
mdl = UNet3D()
|
mdl = UNet3D()
|
||||||
mdl.load_from_pretrained()
|
#mdl.load_from_pretrained()
|
||||||
img = Tensor.randn(1, 1, 5, 224, 224)
|
img = Tensor.randn(1, 1, 5, 224, 224)
|
||||||
test_model(mdl, img)
|
test_model(mdl, img)
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
from tinygrad.tensor import Tensor
|
from tinygrad.tensor import Tensor
|
||||||
import tinygrad.nn as nn
|
import tinygrad.nn as nn
|
||||||
from extra.utils import get_child
|
from extra.utils import get_child
|
||||||
import numpy as np
|
|
||||||
|
|
||||||
class BasicBlock:
|
class BasicBlock:
|
||||||
expansion = 1
|
expansion = 1
|
||||||
|
@ -80,8 +79,7 @@ class ResNet:
|
||||||
self.layer2 = self._make_layer(self.block, 128, self.num_blocks[1], stride=2)
|
self.layer2 = self._make_layer(self.block, 128, self.num_blocks[1], stride=2)
|
||||||
self.layer3 = self._make_layer(self.block, 256, self.num_blocks[2], stride=2)
|
self.layer3 = self._make_layer(self.block, 256, self.num_blocks[2], stride=2)
|
||||||
self.layer4 = self._make_layer(self.block, 512, self.num_blocks[3], stride=2)
|
self.layer4 = self._make_layer(self.block, 512, self.num_blocks[3], stride=2)
|
||||||
# TODO: replace with nn.Linear
|
self.fc = nn.Linear(512 * self.block.expansion, num_classes)
|
||||||
self.fc = {"weight": Tensor.scaled_uniform(512 * self.block.expansion, num_classes), "bias": Tensor.zeros(num_classes)}
|
|
||||||
|
|
||||||
def _make_layer(self, block, planes, num_blocks, stride):
|
def _make_layer(self, block, planes, num_blocks, stride):
|
||||||
strides = [stride] + [1] * (num_blocks-1)
|
strides = [stride] + [1] * (num_blocks-1)
|
||||||
|
@ -93,12 +91,13 @@ class ResNet:
|
||||||
|
|
||||||
def forward(self, x):
|
def forward(self, x):
|
||||||
out = self.bn1(self.conv1(x)).relu()
|
out = self.bn1(self.conv1(x)).relu()
|
||||||
|
out = out.pad2d([1,1,1,1]).max_pool2d((3,3), 2)
|
||||||
out = out.sequential(self.layer1)
|
out = out.sequential(self.layer1)
|
||||||
out = out.sequential(self.layer2)
|
out = out.sequential(self.layer2)
|
||||||
out = out.sequential(self.layer3)
|
out = out.sequential(self.layer3)
|
||||||
out = out.sequential(self.layer4)
|
out = out.sequential(self.layer4)
|
||||||
out = out.mean(3).mean(2)
|
out = out.mean([2,3])
|
||||||
out = out.linear(**self.fc).log_softmax()
|
out = self.fc(out).log_softmax()
|
||||||
return out
|
return out
|
||||||
|
|
||||||
def __call__(self, x):
|
def __call__(self, x):
|
||||||
|
@ -121,7 +120,7 @@ class ResNet:
|
||||||
state_dict = load_state_dict_from_url(self.url, progress=True)
|
state_dict = load_state_dict_from_url(self.url, progress=True)
|
||||||
for k, v in state_dict.items():
|
for k, v in state_dict.items():
|
||||||
obj = get_child(self, k)
|
obj = get_child(self, k)
|
||||||
dat = v.detach().numpy().T if "fc.weight" in k else v.detach().numpy()
|
dat = v.detach().numpy()
|
||||||
|
|
||||||
if 'fc.' in k and obj.shape != dat.shape:
|
if 'fc.' in k and obj.shape != dat.shape:
|
||||||
print("skipping fully connected layer")
|
print("skipping fully connected layer")
|
||||||
|
|
Loading…
Reference in New Issue