from fastai.vision.all import *
path = untar_data(URLs.MNIST_SAMPLE)
Path.BASE_PATH = path
path.ls()
(#3) [Path('train'),Path('labels.csv'),Path('valid')]
images = (path/'train'/'3').ls()
images
(#6131) [Path('train/3/55705.png'),Path('train/3/32379.png'),Path('train/3/36132.png'),Path('train/3/50201.png'),Path('train/3/39704.png'),Path('train/3/8475.png'),Path('train/3/5139.png'),Path('train/3/32610.png'),Path('train/3/7784.png'),Path('train/3/45704.png')...]
Image.open(images[0])
a = torch.stack([tensor(Image.open(o)) for o in (path/'train'/'3').ls()]).reshape(-1, 28*28)/255.
b = torch.stack([tensor(Image.open(o)) for o in (path/'train'/'7').ls()]).reshape(-1, 28*28)/255.
X = torch.cat([a, b])
y = tensor([1]*len(a) + [0]*len(b))

a = torch.stack([tensor(Image.open(o)) for o in (path/'valid'/'3').ls()]).reshape(-1, 28*28)/255.
b = torch.stack([tensor(Image.open(o)) for o in (path/'valid'/'7').ls()]).reshape(-1, 28*28)/255.
X_valid = torch.cat([a, b])
y_valid = tensor([1]*len(a) + [0]*len(b))

X.shape, y.shape, X_valid.shape, y_valid.shape
(torch.Size([12396, 784]),
 torch.Size([12396]),
 torch.Size([2038, 784]),
 torch.Size([2038]))
ds = list(zip(X, y))
dl = DataLoader(ds, batch_size=256, shuffle=True)

ds_valid = list(zip(X_valid, y_valid))
dl_valid = DataLoader(ds_valid, batch_size=256)

dls = DataLoaders(dl, dl_valid)
weights = torch.randn((28*28, 1)).requires_grad_()
bias = torch.randn(1).requires_grad_()

weights[:3], bias
(tensor([[-0.4108],
         [ 0.9965],
         [ 0.5047]], grad_fn=<SliceBackward0>),
 tensor([-0.0758], requires_grad=True))
X[:5]@weights + bias
tensor([[ 5.9452],
        [10.0471],
        [-8.5174],
        [ 7.4015],
        [ 3.0735]], grad_fn=<AddBackward0>)
W = torch.randn((28*28, 1)).requires_grad_()
b = torch.randn(1).requires_grad_()
lr = 1.
X, t = first(dl)

def doit():
    y = (lambda x: 1/(1+torch.exp(-x)))(X@W + b)
    loss = ((t-y)**2).mean()
    loss.backward()
    print(loss.item(), W.grad.mean(), b.grad)
    for p in W, b:
        p.data -= lr*p.grad
        p.grad.zero_()
        
      
for _ in range(3):    
    doit()
0.429675817489624 tensor(-0.0002) tensor([-0.0027])
0.4291311502456665 tensor(-0.0002) tensor([-0.0027])
0.42858171463012695 tensor(-0.0002) tensor([-0.0027])
W = torch.randn((28*28, 1)).requires_grad_()
b = torch.randn(1).requires_grad_()
lr = 1.

def accuracy():
    y = (lambda x: 1/(1+torch.exp(-x)))(X_valid@W + b)
    return ((y > 0.5)==t).float().mean()

for epoch in range(30):
    for X, t in dl:
        y = (lambda x: 1/(1+torch.exp(-x)))(X@W + b)
        loss = ((t-y)**2).mean()
        loss.backward()
        for p in W, b:
            p.data -= lr*p.grad
            p.grad.zero_()
    print(epoch, loss.item(), accuracy())
0 0.42189547419548035 tensor(0.5064)
1 0.43536025285720825 tensor(0.5000)
2 0.40831637382507324 tensor(0.4987)
3 0.4077708125114441 tensor(0.5011)
4 0.4055875837802887 tensor(0.5067)
5 0.40033259987831116 tensor(0.5110)
6 0.39839795231819153 tensor(0.5065)
7 0.38762959837913513 tensor(0.5020)
8 0.36699414253234863 tensor(0.5065)
9 0.39512205123901367 tensor(0.5059)
10 0.3689902424812317 tensor(0.5048)
11 0.34809964895248413 tensor(0.5012)
12 0.34387949109077454 tensor(0.5050)
13 0.3494081497192383 tensor(0.5050)
14 0.3504391312599182 tensor(0.4992)
15 0.333186537027359 tensor(0.5017)
16 0.32519006729125977 tensor(0.5150)
17 0.31659629940986633 tensor(0.5301)
18 0.3194851875305176 tensor(0.5057)
19 0.31758102774620056 tensor(0.5000)
20 0.3440946042537689 tensor(0.5864)
21 0.36963266134262085 tensor(0.5365)
22 0.30330464243888855 tensor(0.5538)
23 0.33537527918815613 tensor(0.4992)
24 0.3367502987384796 tensor(0.5366)
25 0.3061891496181488 tensor(0.4945)
26 0.3117249011993408 tensor(0.5044)
27 0.39691346883773804 tensor(0.5499)
28 0.3109123110771179 tensor(0.5000)
29 0.338569700717926 tensor(0.4946)