<jupyter_start><jupyter_text>Data  Download<jupyter_code>!git clone https://github.com/rois-codh/kmnist
!python kmnist/download_data.py 
!tar xf kkanji.tar<jupyter_output><empty_output><jupyter_text>Visualize<jupyter_code>PATH = Path('kkanji2')
!ls {PATH}/U+4E71/
imdata = plt.imread(str(PATH/'U+4E71/0d0cd162e69ced42.png'))
imdata = io.imread(str(PATH/'U+4E71/0d0cd162e69ced42.png'))
imdata/256
imdata.shape
np.expand_dims(imdata, axis=-1).shape
plt.imshow(imdata)<jupyter_output><empty_output><jupyter_text>Scan filenames<jupyter_code>filenames = []
labels = []
for p in tqdm(PATH.glob('*/*.png')):
    fname = str(p)
    filenames.append(fname)
    label = fname.split('/')[1]
    labels.append(label)
    
size = len(filenames)
classes = list(set(labels))

ctoi = dict((c, i) for i, c in enumerate(classes))
itoc = dict((i, c) for i, c in enumerate(classes))
class_size = len(classes)
itoc[1], ctoi['U+6D17']
labels = [ctoi[lbl] for lbl in labels]
def ceildiv(a, b):
    return -(-a // b)

def plots_from_files(imspaths, figsize=(10,5), rows=1, titles=None, maintitle=None):
    """Plot the images in a grid"""
    f = plt.figure(figsize=figsize)
    if maintitle is not None: plt.suptitle(maintitle, fontsize=10)
    for i in range(len(imspaths)):
        sp = f.add_subplot(rows, ceildiv(len(imspaths), rows), i+1)
        sp.axis('Off')
        if titles is not None: sp.set_title(titles[i], fontsize=16)
        img = plt.imread(imspaths[i])
        plt.imshow(img, cmap='gray') # cmap='binary'
idxs = [np.random.randint(0, size-1) for i in range(9)]
imspaths = [filenames[i] for i in idxs]
titles = [labels[i] for i in idxs]

plots_from_files(imspaths, rows=3, titles=titles, figsize=(10, 10))<jupyter_output><empty_output><jupyter_text>DataLoader<jupyter_code>bs = 128
data = np.zeros((len(filenames), 1, 64, 64), dtype=np.float)
for index, fname in tqdm(enumerate(filenames)):
    imdata = io.imread(fname)
    # normalize the data
    normalized = imdata / 256
    data[index] = np.expand_dims(normalized, axis=0) # shape (1, 64, 64)
    
data.shape<jupyter_output>140424it [01:50, 1269.52it/s]<jupyter_text>normalize the data to be between 0 and 1<jupyter_code>np.save(PATH/'data.pkl', data)
np.save(PATH/'labels.pkl', labels)
data = np.load(PATH/'data.pkl')
labels = np.load(PATH/'labels.pkl')
data_cuda   = torch.FloatTensor(data).cuda()
labels_cuda = torch.LongTensor(labels).cuda()
valid_offset = int(data_cuda.shape[0] * 0.9)

X_train, y_train = data_cuda[: valid_offset], labels_cuda[: valid_offset]
X_valid, y_valid = data_cuda[valid_offset: ], labels_cuda[valid_offset: ]

X_train.shape, len(y_train), X_valid.shape, len(y_valid)
train_ds = torch.utils.data.TensorDataset(X_train, y_train)
train_dl = torch.utils.data.DataLoader(train_ds, batch_size=bs, shuffle=True)
valid_ds = torch.utils.data.TensorDataset(X_valid, y_valid)
valid_dl = torch.utils.data.DataLoader(valid_ds, batch_size=bs, shuffle=True)<jupyter_output><empty_output><jupyter_text>Model<jupyter_code>def conv2d(ni, nf, k=3, s=2, p=1): return nn.Conv2d(ni, nf, kernel_size=k, stride=s, padding=p)
def upsample(ni, nf, k=3, s=2, p=1, op=0): return nn.ConvTranspose2d(ni, nf, kernel_size=k, stride=s, padding=p, output_padding=op)
class Flatten(nn.Module):
    def __init__(self):
        super().__init__()
    def forward(self, x):
        x = x.view(x.size()[0], -1)
        return x
class ResnetBlock(nn.Module):
    def __init__(self, nf):
        super().__init__()
        self.conv1 = conv2d(nf, nf, s=1)
        self.batchnorm = nn.BatchNorm2d(nf)
        self.relu = nn.ReLU(True)
        self.conv2 = conv2d(nf, nf, s=1)
        
    def forward(self, x):
        out = self.conv1(x)
        out = self.batchnorm(out)
        out = self.relu(out)
        out = self.conv2(out)
        return x + out
def conv_res(ni, nf): return nn.Sequential(conv2d(ni, nf), ResnetBlock(nf))
def up_res(ni, nf): return nn.Sequential(upsample(ni, nf, op=1), ResnetBlock(nf))
def create_encoder(image_size=64, latent_dim=4):
    channels = [1, 4, 8, 16, 32]
    layers = []
    layers.append(conv_res(channels[0], channels[1]))  # (bs, 32, 32)
    layers.append(conv_res(channels[1], channels[2]))  # (bs, 16, 16)
    layers.append(conv_res(channels[2], channels[3]))  # (bs, 8, 8)
    layers.append(conv_res(channels[3], channels[4]))  # (bs, 4, 4)
    return nn.Sequential(*layers)
def create_decoder(image_size=64, latent_dim=4):
    channels = [32, 16, 8, 4, 1]
    layers = []
    # use upsampling
    layers.append(up_res(channels[0], channels[1])) # (bs, 16, 16)
    layers.append(up_res(channels[1], channels[2])) # (bs, 8, 8)
    layers.append(up_res(channels[2], channels[3])) # (bs, 4, 4)
    layers.append(up_res(channels[3], channels[4])) # (bs, 1, 1)
    return nn.Sequential(*layers)
enc = create_encoder()
dec = create_decoder()
enc
dec<jupyter_output><empty_output><jupyter_text>Classification Model<jupyter_code>class Classifier(nn.Module):
    def __init__(self, enc, class_size):
        super().__init__()
        self.enc = enc
        self.flatten = Flatten()                          # (bs, 16 * 32)
        self.relu = nn.ReLU(True)
        self.drop = nn.Dropout()
        self.lin  = nn.Linear(in_features= 512, out_features=class_size)
        
    def forward(self, X):
        y = self.enc(X)
        y = self.flatten(y)
        y = self.relu(y)
        y = self.drop(y)
        return self.lin(y)
model = Classifier(enc, class_size).cuda()
lr=2e-2
loss_func = nn.CrossEntropyLoss()
def update(x,y,lr):
    opt = optim.Adam(model.parameters(), lr)
    y_hat = model(x)
    loss = loss_func(y_hat, y)
    loss.backward()
    opt.step()
    opt.zero_grad()
    return loss.item()
losses = [update(x,y,1e-3) for x,y in train_dl]
plt.plot(losses);<jupyter_output><empty_output><jupyter_text>AutoEncoder Model<jupyter_code>class AutoEncoder(nn.Module):
    def __init__(self, encoder, decoder):
        super().__init__()
        self.enc = encoder
        self.dec = decoder
        
    def forward(self, X):
        y = self.enc(X)
        y = self.dec(y)
        return y
enc = create_encoder()
dec = create_decoder()
model = AutoEncoder(enc, dec).cuda()
lr=2e-2
loss_func = nn.L1Loss()
def update(x,y,lr):
    opt = optim.Adam(model.parameters(), lr)
    y_hat = model(x)
    loss = loss_func(y_hat, y)
    loss.backward()
    opt.step()
    opt.zero_grad()
    return loss.item()
train_ds = torch.utils.data.TensorDataset(X_train, X_train)
train_dl = torch.utils.data.DataLoader(train_ds, batch_size=bs, shuffle=True)
epochs = 10
valid_losses = []
for epoch in tqdm(range(epochs)):
    losses = [update(x,y,lr) for x,y in train_dl]
    y_hat = model(X_valid)
    valid_loss = loss_func(y_hat, X_valid)
    valid_losses.append(valid_loss.item())
plt.plot(losses)<jupyter_output><empty_output><jupyter_text>AutoEncoder<jupyter_code>#model = nn.Sequential(enc, dec).cuda()<jupyter_output><empty_output>
StarcoderdataJupyterStructuredCleanDedup