# AI Computer Vision Inspection **2020 LiteOn Award** **Detect the defect rate of pcba board** ## ResNet Prefromence ![Slide01](https://hackmd.io/_uploads/Hkp04YsYa.jpg) ![Slide02](https://hackmd.io/_uploads/HyhRVKjYa.jpg) ![Slide03](https://hackmd.io/_uploads/ByhREKiK6.jpg) ![Slide04](https://hackmd.io/_uploads/ByhANtsFp.jpg) ![Slide05](https://hackmd.io/_uploads/r1xn0EYsYT.jpg) ![Slide06](https://hackmd.io/_uploads/S1nANKotp.jpg) ![Slide07](https://hackmd.io/_uploads/B12CNFsF6.jpg) ![Slide08](https://hackmd.io/_uploads/Hk3A4Yita.jpg) ![Slide09](https://hackmd.io/_uploads/rknCVtsta.jpg) ![Slide10](https://hackmd.io/_uploads/BknAVKsY6.jpg) ![Slide11](https://hackmd.io/_uploads/By6CNKjKp.jpg) ![Slide12](https://hackmd.io/_uploads/Hygn0VKiKa.jpg) ![Slide13](https://hackmd.io/_uploads/ByxnR4KjtT.jpg) ![Slide14](https://hackmd.io/_uploads/rJla04KjKT.jpg) ![Slide15](https://hackmd.io/_uploads/HJ3R4titp.jpg) ![Slide16](https://hackmd.io/_uploads/Sk6C4YjK6.jpg) ![Slide17](https://hackmd.io/_uploads/BknREKsKT.jpg) ![Slide18](https://hackmd.io/_uploads/rk2ANtst6.jpg) ## VGG16 Version ``` # -*- coding: utf-8 -*- """liteonvgg30.ipynb Automatically generated by Colaboratory. Original file is located at https://colab.research.google.com/drive/1VOgdwXEpfMTGSdw0Ep4lE2fXu_qQKGog """ from google.colab import drive drive.mount('/content/drive') from __future__ import print_function, division import torch import torch.nn as nn import torch.optim as optim from torch.optim import lr_scheduler from torch.autograd import Variable import numpy as np import torchvision from torchvision import datasets, models, transforms import matplotlib.pyplot as plt import time import os import copy from sklearn.metrics import classification_report plt.ion() use_gpu = torch.cuda.is_available() if use_gpu: print("Using CUDA") else: print("Error") data_dir = 'drive/MyDrive/LiteonRacingData' TRAIN = 'A' TEST = 'B' IMAGENET_MEAN = [0.4914, 0.4822, 0.4465] IMAGENET_STD = [0.2023, 0.1994, 0.201] data_transforms = { TRAIN: transforms.Compose([ transforms.RandomHorizontalFlip(), transforms.RandomVerticalFlip(), transforms.RandomPosterize(bits=2), transforms.ColorJitter(brightness=1, contrast=1, saturation=1.0, hue=0.5), transforms.GaussianBlur(7,3), transforms.RandomAffine(degrees=0,translate=(0.1,0.1),fillcolor=None), transforms.ToTensor(), transforms.Normalize(mean=IMAGENET_MEAN, std=IMAGENET_STD) ]), TEST: transforms.Compose([ transforms.ToTensor(), transforms.Normalize(mean=IMAGENET_MEAN, std=IMAGENET_STD) ]) } image_datasets = { x: datasets.ImageFolder( os.path.join(data_dir, x), transform=data_transforms[x] ) for x in [TRAIN, TEST] } dataloaders = { x: torch.utils.data.DataLoader( image_datasets[x], batch_size=8, shuffle=True, num_workers=4 ) for x in [TRAIN, TEST] } dataset_sizes = {x: len(image_datasets[x]) for x in [TRAIN, TEST]} for x in [TRAIN, TEST]: print("Loaded {} images under {}".format(dataset_sizes[x], x)) print("Classes: ") class_names = image_datasets[TRAIN].classes print(image_datasets[TRAIN].classes) # Get a batch of training data inputs, classes = next(iter(dataloaders[TRAIN])) from torchvision import models # Load the pretrained model from pytorch vgg16 = models.vgg16_bn(pretrained=True) # Freeze training for all layers for param in vgg16.features.parameters(): param.require_grad = False # Newly created modules have require_grad=True by default num_features = vgg16.classifier[6].in_features features = list(vgg16.classifier.children())[:-1] # Remove last layer features.extend([ nn.Linear(num_features, 8) ]) # Add our layer with 4 outputs vgg16.classifier = nn.Sequential(*features) # Replace the model classifier vgg16.load_state_dict(torch.load("drive/MyDrive/969282.pt")) print("Loaded!") if use_gpu: vgg16.cuda() #.cuda() will move everything to the GPU side weight_CE = torch.FloatTensor([0.7,0.8,1,3,0.8,0.8,2,2]) criterion = nn.CrossEntropyLoss(ignore_index=255,weight=weight_CE.cuda()) optimizer_ft = optim.Adam(vgg16.parameters(), lr=5e-5, betas=[0.5, 0.999]) exp_lr_scheduler = lr_scheduler.CosineAnnealingLR(optimizer_ft, 30, 0) #optimizer_ft = optim.SGD(vgg16.parameters(), lr=5e-6, momentum=0.9,weight_decay=5e-4) #exp_lr_scheduler = lr_scheduler.StepLR(optimizer_ft, step_size=7, gamma=0.95) def train_model(vgg, criterion, optimizer, scheduler, num_epochs=50): best_model_wts = copy.deepcopy(vgg.state_dict()) best_acc = 0.0 avg_loss = 0 avg_acc = 0 avg_loss_val = 0 avg_acc_val = 0 train_batches = len(dataloaders[TRAIN]) val_batches = len(dataloaders[TEST]) for epoch in range(num_epochs): if epoch==0: with open('version3.txt', 'w') as f: f.write("epoch:") f.write(str(epoch)) else: with open('version3.txt', 'a') as f: f.write("epoch:") f.write(str(epoch)) print("Epoch {}/{}".format(epoch, num_epochs)) print('-' * 10) loss_train = 0 loss_val = 0 acc_train = 0 acc_val = 0 vgg.train(True) for i, data in enumerate(dataloaders[TRAIN]): if i % 100 == 0: print("\rTraining batch {}/{}".format(i, train_batches/5), end='', flush=True) # Use half training dataset if i >= train_batches /5: break inputs, labels = data #inputs = inputs + torch.rand(inputs.shape) if use_gpu: inputs, labels = Variable(inputs.cuda()), Variable(labels.cuda()) else: inputs, labels = Variable(inputs), Variable(labels) optimizer.zero_grad() outputs = vgg(inputs) #_______________________ # m = nn.LogSoftmax() # closs = nn.NLLLoss() # outputs=m(outputs) # loss = closs(outputs, labels) #print('output:',output) #________________________ _, preds = torch.max(outputs.data, 1) loss = criterion(outputs, labels) loss.backward() optimizer.step() loss_train += loss.item() acc_train += torch.sum(preds == labels.data) del inputs, labels, outputs, preds torch.cuda.empty_cache() print() # * 2 as we only used half of the dataset avg_loss = loss_train * 8 / dataset_sizes[TRAIN] avg_acc = acc_train * 8 / dataset_sizes[TRAIN] vgg.train(False) vgg.eval() #_____ y_pred = [] y_true = [] target_names = ['class 0', 'class 1', 'class 2', 'class 3', 'class 4', 'class 5', 'class 6', 'class 7'] #_____ for i, data in enumerate(dataloaders[TEST]): if i % 100 == 0: print("\rValidation batch {}/{}".format(i, val_batches), end='', flush=True) inputs, labels = data if use_gpu: inputs, labels = Variable(inputs.cuda(), volatile=True), Variable(labels.cuda(), volatile=True) else: inputs, labels = Variable(inputs, volatile=True), Variable(labels, volatile=True) optimizer.zero_grad() outputs = vgg(inputs) #_______________________ # m = nn.LogSoftmax() # closs = nn.NLLLoss() # outputs=m(outputs) # loss = closs(outputs, labels) #print('output:',output) #________________________ _, preds = torch.max(outputs.data, 1) loss = criterion(outputs, labels) loss_val += loss.item() acc_val += torch.sum(preds == labels.data) #____ preds = preds.cpu().numpy() labels = labels.cpu().numpy() for j in range(0, len(labels)): # print(j) y_pred.append(preds[j]) y_true.append(labels[j]) # print(y_pred) #____ # del inputs, labels, outputs, preds # torch.cuda.empty_cache() #print(classification_report(y_true, y_pred, target_names=target_names)) with open('version3.txt', 'a') as f: f.write(classification_report(y_true, y_pred, target_names=target_names)) f.write('_____________________________________________________________\n') #files.download('version1.txt') avg_loss_val = loss_val / dataset_sizes[TEST] avg_acc_val = acc_val / dataset_sizes[TEST] print() print("Epoch {} result: ".format(epoch)) print("Avg loss (train): {:.4f}".format(avg_loss)) print("Avg acc (train): {:.4f}".format(avg_acc)) print("Avg loss (val): {:.4f}".format(avg_loss_val)) print("Avg acc (val): {:.4f}".format(avg_acc_val)) print('-' * 10) print() #eval_model(vgg16, criterion) if avg_acc_val >= best_acc: best_acc = avg_acc_val best_model_wts = copy.deepcopy(vgg.state_dict()) torch.save(vgg16.state_dict(), 'VGG16_18('+str(epoch)+').pt') print() print("Best acc: {:.4f}".format(best_acc)) vgg.load_state_dict(best_model_wts) return vgg vgg16 = train_model(vgg16, criterion, optimizer_ft, exp_lr_scheduler, num_epochs=50) torch.save(vgg16.state_dict(), 'VGG16_3.pt') ```