<jupyter_start><jupyter_text>IntroductionThis notebook continues from the _DataPrep_ notebook and tries to use a CNN based on ResNet in the MxNet framework for classification. Data Set[Qingyi](https://www.kaggle.com/qingyi). (February 2018). WM-811K wafer map, Version 1. Retrieved January 2018 from https://www.kaggle.com/qingyi/wm811k-wafer-map/downloads/wm811k-wafer-map.zip/1. LicenseCopyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.SPDX-License-Identifier: MIT-0<jupyter_code>%reload_ext autoreload
%autoreload 2
%matplotlib inline
from mxnet import gluon, init, nd
from mxnet.gluon import data as gdata, loss as gloss, model_zoo
from mxnet.gluon import utils as gutils
import matplotlib.pyplot as plt
import os
import zipfile<jupyter_output><empty_output><jupyter_text>Data loader and transformations<jupyter_code>data_dir = 'vdata'
train_imgs = gdata.vision.ImageFolderDataset(
    os.path.join(data_dir, 'train'))
valid_imgs = gdata.vision.ImageFolderDataset(
    os.path.join(data_dir, 'valid'))
train_imgs.synsets
def show_images(imgs, labels, num_rows, num_cols, scale=2):
    """Plot a list of images."""
    figsize = (num_cols * scale, num_rows * scale)
    _, axes = plt.subplots(num_rows, num_cols, figsize=figsize)
    for i in range(num_rows):
        for j in range(num_cols):
            axes[i][j].imshow(imgs[i * num_cols + j].asnumpy())
            axes[i][j].axes.get_xaxis().set_visible(False)
            axes[i][j].axes.get_yaxis().set_visible(False)
            axes[i][j].set_title(labels[i * num_cols + j], fontsize=10)
    return axes
# Show 5 examples of each class
images_to_show = []
labels_to_show = []
label_counter = { ii: 0 for ii in range(len(train_imgs.synsets)) }
for item in train_imgs:
    img = item[0]
    label = item[1]
    if label_counter[label] > 4:
        continue
    else:
        images_to_show.append(img)
        labels_to_show.append(train_imgs.synsets[label])
        label_counter[label] = label_counter[label] + 1
        
ax = show_images(images_to_show, labels_to_show, 9, 5)
normalize = gdata.vision.transforms.Normalize(
    [0.485, 0.456, 0.406], [0.229, 0.224, 0.225])

train_augs = gdata.vision.transforms.Compose([
    gdata.vision.transforms.RandomResizedCrop(224),
    gdata.vision.transforms.RandomFlipLeftRight(),
    gdata.vision.transforms.RandomFlipTopBottom(),
    gdata.vision.transforms.ToTensor(),
    normalize])

valid_augs = gdata.vision.transforms.Compose([
    gdata.vision.transforms.Resize(256),
    gdata.vision.transforms.CenterCrop(224),
    gdata.vision.transforms.ToTensor(),
    normalize])
batch_size = 64
epochs = 3
learning_rate = 0.001
wd = 0.001<jupyter_output><empty_output><jupyter_text>Training<jupyter_code>import mxnet as mx
from mxnet import autograd
from mxnet import gluon
from mxnet.gluon.model_zoo import vision as models

ctx = [mx.gpu()]
    
# Define pretrained model
pretrained_net = model_zoo.vision.resnet18_v2(ctx=ctx, pretrained=True)
net = model_zoo.vision.resnet18_v2(ctx=ctx, classes=9)
net.features = pretrained_net.features
net.output.initialize(init.Xavier(), ctx=ctx)
net.output.collect_params().setattr('lr_mult', 10)
train_iter = gdata.DataLoader(
    train_imgs.transform_first(train_augs), batch_size, shuffle=True)
valid_iter = gdata.DataLoader(
    valid_imgs.transform_first(valid_augs), batch_size)
# Trainer is for updating parameters with gradient.
net.collect_params().reset_ctx(ctx)
net.hybridize()
loss = gluon.loss.SoftmaxCrossEntropyLoss()
trainer = gluon.Trainer(net.collect_params(), 'adam', 
                        optimizer_params={'learning_rate': learning_rate, 'wd': wd})
def _get_batch(batch, ctx):
    """Return features and labels on ctx."""
    features, labels = batch
    if labels.dtype != features.dtype:
        labels = labels.astype(features.dtype)
    return (gutils.split_and_load(features, ctx),
            gutils.split_and_load(labels, ctx), features.shape[0])
def evaluate_accuracy(data_iter, net, ctx=[mx.cpu()]):
    """Evaluate accuracy of a model on the given data set."""
    if isinstance(ctx, mx.Context):
        ctx = [ctx]
    acc_sum, n = nd.array([0]), 0
    for batch in data_iter:
        features, labels, _ = _get_batch(batch, ctx)
        for X, y in zip(features, labels):
            y = y.astype('float32')
            acc_sum += (net(X).argmax(axis=1) == y).sum().copyto(mx.cpu())
            n += y.size
        acc_sum.wait_to_read()
    return acc_sum.asscalar() / n
import time
def train(train_iter, test_iter, net, loss, trainer, ctx, num_epochs, log_steps=500):
    """Train and evaluate a model."""
    print('training on', ctx)
    if isinstance(ctx, mx.Context):
        ctx = [ctx]
    for epoch in range(num_epochs):
        train_l_sum, train_acc_sum, n, m, start = 0.0, 0.0, 0, 0, time.time()
        for i, batch in enumerate(train_iter):
            Xs, ys, batch_size = _get_batch(batch, ctx)
            ls = []
            with autograd.record():
                y_hats = [net(X) for X in Xs]
                ls = [loss(y_hat, y) for y_hat, y in zip(y_hats, ys)]
            for l in ls:
                l.backward()
            trainer.step(batch_size)
            train_l_sum += sum([l.sum().asscalar() for l in ls])
            n += sum([l.size for l in ls])
            train_acc_sum += sum([(y_hat.argmax(axis=1) == y).sum().asscalar()
                                  for y_hat, y in zip(y_hats, ys)])
            m += sum([y.size for y in ys])
            if i % log_steps == 0 and i > 0:
                print("Batch {0}: accuracy = {1}".format(str(i), str(train_acc_sum/m)))
        test_acc = evaluate_accuracy(test_iter, net, ctx)
        print('epoch %d, loss %.4f, train acc %.3f, test acc %.3f, '
              'time %.1f sec'
              % (epoch + 1, train_l_sum / n, train_acc_sum / m, test_acc,
                 time.time() - start))
ctx
train(train_iter, valid_iter, net, loss, trainer, ctx, epochs)
net.save_parameters('{}/model-resnet18-121.params'.format('vdata/mxnet'))
net.export("model_gluon_resnet18_121", epoch=5)<jupyter_output><empty_output><jupyter_text>Test Set<jupyter_code>test_imgs = gdata.vision.ImageFolderDataset(
    os.path.join(data_dir, 'test'))
test_augs = gdata.vision.transforms.Compose([
    gdata.vision.transforms.Resize(256),
    gdata.vision.transforms.CenterCrop(224),
    gdata.vision.transforms.ToTensor(),
    normalize])
def plot_confusion_matrix(cm, classes,
                          normalize=False,
                          title='Confusion matrix',
                          cmap=plt.cm.Blues):
    """
    This function prints and plots the confusion matrix.
    Normalization can be applied by setting `normalize=True`.
    """
    if normalize:
        cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]
        print("Normalized confusion matrix")
    else:
        print('Confusion matrix, without normalization')

    print(cm)

    plt.imshow(cm, interpolation='nearest', cmap=cmap)
    plt.title(title)
    plt.colorbar()
    tick_marks = np.arange(len(classes))
    plt.xticks(tick_marks, classes, rotation=45)
    plt.yticks(tick_marks, classes)

    fmt = '.2f' if normalize else 'd'
    thresh = cm.max() / 2.
    for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
        plt.text(j, i, format(cm[i, j], fmt),
                 horizontalalignment="center",
                 color="white" if cm[i, j] > thresh else "black")

    plt.ylabel('True label')
    plt.xlabel('Predicted label')
    plt.tight_layout()
from sklearn.metrics import *
import itertools
def evaluate_metrics(dataset, net, ctx=[mx.cpu()]):
    """Evaluate accuracy of a model on the given data set."""
    if isinstance(ctx, mx.Context):
        ctx = [ctx]
    preds = []
    trues = []
    cnt = 0
    cnt_step = 500
    for item in dataset:
        img = item[0]
        label = item[1]    
        img = test_augs(img)
        img = img.expand_dims(axis=0)
        trues.append(label)
        
        output = net(img.as_in_context(mx.gpu()))
        output_label = output.argmax(axis=1).copyto(mx.cpu())  
        output_label_cpu = int(output_label.asnumpy()[0])
        preds.append(output_label_cpu)  
        if cnt % cnt_step == 0:
            print("Working on " + str(cnt))
        cnt = cnt + 1
    return trues, preds
    
trues, preds = evaluate_metrics(test_imgs, net, ctx)
import numpy as np
print("Accuracy: {0}".format(accuracy_score(trues, preds)))
print("Weighted F1 Score: {0}".format(f1_score(trues, preds, average='weighted')))
print("Weighted F-beta: {0}".format(fbeta_score(trues, preds, average='weighted', beta=1.0)))
print("Macro F1 Score: {0}".format(f1_score(trues, preds, average='macro')))
print("Macro F-beta: {0}".format(fbeta_score(trues, preds, average='macro', beta=1.0)))
print("Micro F1 Score: {0}".format(f1_score(trues, preds, average='micro')))
print("Micro F-beta: {0}".format(fbeta_score(trues, preds, average='micro', beta=1.0)))
print(classification_report(trues, preds, target_names=test_imgs.synsets))
cm = confusion_matrix(trues, preds)
plot_confusion_matrix(cm, test_imgs.synsets, normalize=False)
plot_confusion_matrix(cm, test_imgs.synsets, normalize=True)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.13341996967727962, 'fraction_numerical': 0.018193632228719947, 'mean_word_length': 3.3417959567465916, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 20, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '417570', 'license': 'MIT-0', 'n_tokens_mistral': 3315, 'n_tokens_neox': 3197, 'n_words': 696, 'path': 'notebooks/Classify-MxNet-121.ipynb', 'repo_name': 'andreluiz365/chip-wafer-classification-deep-learning', 'size': '9234'}