--- title: Title keywords: fastai sidebar: home_sidebar summary: "summary" ---
%load_ext autoreload
%autoreload 2
def type_info(obj):
print(type(obj))
for type_ in (Preprocessor, FeatureScaler, MinMaxScaler):
print(type_, isinstance(obj, type_))
print(obj)
class Preprocessor:
def __init__(self):
pass
def forward(self):
print('forward')
def __repr__(self):
return 'Preprocessor()'
pre = Preprocessor()
pre.forward()
type_info(pre)
class FeatureScaler(Preprocessor):
def __init__(self, x):
super().__init__()
self.x = x
self.processed = False
def process(self):
print('processing')
self.processed = True
@classmethod
def from_list(cls, *args):
return cls(*args)
scaler = FeatureScaler([1, 2, 3])
scaler.forward()
scaler.process()
type_info(scaler)
scaler2 = FeatureScaler.from_list([1, 2])
scaler2.x
class MinMaxScaler(FeatureScaler):
def __init__(self, x, y):
super().__init__(x)
self.y = y
def scale(self):
return [arg/2 for arg in self.x]
minmax = MinMaxScaler([1, 2, 3], 4)
minmax.forward()
minmax.process()
print(minmax.scale())
type_info(minmax)
minmax2 = MinMaxScaler.from_list(*[7, 8])
minmax2.x, minmax2.y
class StandardScaler(FeatureScaler):
def __init__(self, x, y, z):
super().__init__(x)
self.y = y
self.z = z
def backward(self):
return self.z, self.y, self.x
ss = StandardScaler(11, 22, 33)
ss.forward()
print(ss.backward())
ss2 = StandardScaler.from_list(*[7, 9, 11])
ss2.forward()
print(ss2.backward())
type_info(ss2)
class TmpModule(nn.Module):
def __init__(self, init_args):
super().__init__()
init_args.pop('self', None)
init_args.pop('__class__', None)
self.init_args = init_args
def get_args(self):
print('init args:', self.init_args)
@classmethod
def from_list(cls, arr):
return cls(*arr)
class ImgModel(TmpModule):
def __init__(self, dim, hidden, bn):
super().__init__(locals())
self.dim = dim
self.hidden = hidden
self.bn = bn
def forward(self, x):
return 2 * x
img = ImgModel(12, 4, True)
img.__dict__
img2 = ImgModel.from_list([3, 6, False])
img2.__dict__
img2.get_args()
import torch
import torch.nn as nn
from htools.ml import ModelMixin
-nn.Module comes first here
-still a bit confused about exactly how order and init statements work
class Net(nn.Module, ModelMixin):
def __init__(self, x_dim):
super().__init__()
ModelMixin.__init__(self, locals())
self.fc = nn.Linear(x_dim, 1)
self.act = nn.Sigmoid()
def forward(self, x):
return self.act(self.fc(x))
x = torch.randint(6, (4, 3), dtype=torch.float)
x
net = Net(3)
net
net(x)
net.dims()
net.trainable()
net.weight_stats()
net.plot_weights()
net.save(12, '../data')
net2 = Net.from_path('../data/model_12.pth')
net2
net2(x)
-ModelMixin must come before nn.Module
-locals() must be passed to super init so mixin can store args
class NetB(ModelMixin, nn.Module):
def __init__(self, x_dim):
super().__init__(locals())
self.fc = nn.Linear(x_dim, 1)
self.act = nn.Sigmoid()
def forward(self, x):
return self.act(self.fc(x))
netb = NetB(3)
netb
netb(x)
netb.trainable()
netb.dims()
netb.save(4, '../data')
netb2 = NetB.from_path('../data/model_4.pth')
netb2
netb2(x)
data = torch.load('../data/model_4.pth')
data.keys()
import os
import torch
import torch.nn as nn
from ml_htools.torch_utils import BaseModel
class SubModel(BaseModel):
def __init__(self, dim, norm):
super().__init__(locals())
layers = [nn.Linear(dim, 1)]
if norm:
layers.append(nn.BatchNorm1d(1))
layers.append(nn.Sigmoid())
self.layers = nn.Sequential(*layers)
def forward(self, x):
return self.layers(x)
x = torch.randint(6, (3, 5), dtype=torch.float)
x
m = SubModel(5, True)
m
m.weight_stats()
m(x)
m.save(1, '../data')
m.save(1, '../data')
penalty = m(x).std()
penalty.backward()
for p in m.parameters():
print(p.data)
p.data -= 5 * p.grad
print(p.data, '\n')
m.weight_stats()
m(x)
m.weight_dir
m.save(2)
m1 = SubModel.from_path('../data/model_e1.pth')
m1.train()
m1(x)
m1.weight_stats()
m.load_epoch(2)
m.weight_stats()
m(x)
m.load_epoch(1)
m.weight_stats()
m(x)
import re
num = 2
[file for file in os.listdir('../data') if file.endswith(f'_e{num}.pth')]
list(filter(re.compile(f'.*_e{1}.pth').match, os.listdir('../data')))
os.listdir('../data')