CNN을 통한 품질보증시스템
Image Outlier Detection using Artificial Neural Network
인공 신경망을 이용한 이미지 이상점 탐지
Introduction
인공지능은 프로세스를 자동화하고, 비즈니스에 대한 통찰력을 모으고, 프로세스 속도를 높이기 위해 다양한 산업에서 사용되고 있습니다. 인공지능이 실제로 산업에 어떤 영향을 미치는지 실제 시나리오에서 인공지능의 사용을 연구하기 위해 Python을 사용할 것입니다.
기계 학습에서 이상 탐지 작업은 매우 일반적입니다. 데이터 과학자들은 이상 징후를 보여주고 설명하고 예측해야 하는 문제에 자주 관여합니다. 이상 징후를 미리 감지하고 예측하면 많은 비용을 절감할 수 있습니다. 항상 그렇듯이 AI는 이 경우에 우리를 도울 수 있습니다.
이 노트북에서는 인공 신경망을 사용한 이미지 이상값 감지에 중점을 둘 것입니다.
Context
우리는 Kaggle에서 가져온 완벽한 벽과 금이 간 벽을 보여주는 데이터 세트로 작업할 것이다. 데이터 세트 이미지의 반은 새롭고 손상되지 않은 벽 조각을 보여줍니다; 나머지 부분은 다양한 치수와 유형의 균열을 가진 벽 조각을 보여줍니다.
Side note: VGG 란 무엇입니까??
VGG는 대규모 이미지 인식에 사용되는 신경망입니다. 우리는 이 노트북에서 VGG를 많이 사용할 것입니다. 이것은 1,400만 개가 넘는 수작업으로 라벨링된 이미지가 있는 ImageNet 데이터베이스에서 훈련되었습니다.
Use Python to open csv files
scikit-learn, pandas, TensorFlow와 Keras를 사용하여 데이터 세트를 작업합니다. Scikit-learn은 예측 데이터 분석을 위한 효율적인 도구를 제공하는 매우 유용한 기계 학습 라이브러리입니다. TensorFlow 및 Keras는 ML 모델을 개발하고 교육하는 데 도움이 되는 오픈 소스 라이브러리입니다. Pandas는 데이터 과학을 위한 인기 있는 Python 라이브러리입니다. 강력하고 유연한 데이터 구조를 제공하여 데이터 조작 및 분석을 더 쉽게 만듭니다.
Import Libraries
라이브러리가 설치되어 있지 않은 경우 터미널에서 다음 단계를 수행하십시오.
pip install tensorflow
pip install torch
pip install torchvision
pip install tqdm « 예도 설치해야 되더라;;;
아무튼 없다면 없는대로 설치;;
# 없을테니 설치...
%pip install tensorflow
%pip install torch
%pip install torchvision
Collecting tensorflow
Downloading tensorflow-2.10.0-cp39-cp39-win_amd64.whl (455.9 MB)
------------------------------------- 455.9/455.9 MB 12.8 MB/s eta 0:00:00
......
---------------------------------------- 1.1/1.1 MB 6.3 MB/s eta 0:00:00
Requirement already satisfied: requests in c:\users\user\.conda\envs\myai\lib\site-packages (from torchvision) (2.28.1)
Requirement already satisfied: typing-extensions in c:\users\user\.conda\envs\myai\lib\site-packages (from torchvision) (4.4.0)
Requirement already satisfied: numpy in c:\users\user\.conda\envs\myai\lib\site-packages (from torchvision) (1.23.4)
Requirement already satisfied: torch==1.13.0 in c:\users\user\.conda\envs\myai\lib\site-packages (from torchvision) (1.13.0)
Requirement already satisfied: pillow!=8.3.*,>=5.3.0 in c:\users\user\.conda\envs\myai\lib\site-packages (from torchvision) (9.3.0)
Requirement already satisfied: certifi>=2017.4.17 in c:\users\user\.conda\envs\myai\lib\site-packages (from requests->torchvision) (2022.9.24)
Requirement already satisfied: urllib3<1.27,>=1.21.1 in c:\users\user\.conda\envs\myai\lib\site-packages (from requests->torchvision) (1.26.12)
Requirement already satisfied: charset-normalizer<3,>=2 in c:\users\user\.conda\envs\myai\lib\site-packages (from requests->torchvision) (2.1.1)
Requirement already satisfied: idna<4,>=2.5 in c:\users\user\.conda\envs\myai\lib\site-packages (from requests->torchvision) (3.4)
Installing collected packages: torchvision
Successfully installed torchvision-0.14.0
Note: you may need to restart the kernel to use updated packages.
# 이것도 설치;;
%pip install tqdm
Collecting tqdm Using cached tqdm-4.64.1-py2.py3-none-any.whl (78 kB) Requirement already satisfied: colorama in c:\users\user\.conda\envs\myai\lib\site-packages (from tqdm) (0.4.6) Installing collected packages: tqdm Successfully installed tqdm-4.64.1 Note: you may need to restart the kernel to use updated packages.
import numpy as np
import pandas as pd
import scipy as sp
import matplotlib.pyplot as plt
import tensorflow as tf
from tensorflow.keras.applications import vgg16
from tensorflow.keras.preprocessing.image import load_img, img_to_array, array_to_img, ImageDataGenerator
from tensorflow.keras.models import *
from tensorflow.keras.layers import *
from tensorflow.keras import optimizers
from tensorflow.keras.utils import *
from PIL import Image
import requests
from io import BytesIO
import os
import random
import pickle
import tqdm
import itertools
import torch
import torchvision
from torchvision import datasets, models, transforms
import matplotlib.pyplot as plt
import torch.nn as nn
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report, accuracy_score, confusion_matrix
Dataset 읽기
여기에서 훈련 및 테스트 디렉토리를 정의합니다. [Dataset]Module11TrainQualityAssuranceSystem 및 [Dataset]Module11TestQualityAssuranceSystem 폴더에는 훈련 및 테스트 데이터가 포함되어 있습니다.
축소된 훈련 데이터 세트: [Dataset]Module11TrainReducedQualityAssuranceSystem은 더 작은 훈련 세트를 로드하고 훈련 시간을 줄여야 하는 경우에도 사용할 수 있습니다. 계속하기 전에 폴더의 압축을 풀어줍니다.
훈련 디렉토리에는 2개의 하위 디렉토리가 있습니다:
-
cracked(폴더에 금이 간 벽 이미지가 포함되어 있습니다.)
-
uncracked(폴더에 금이 가지 않은 벽 이미지가 포함되어 있습니다.)
# 훈련 및 테스트 데이터 디렉토리 정의
# [Dataset]Module11TrainReducedQualityAssuranceSystem을 사용하여 훈련 시간을 줄일 수도 있습니다.
train_dir = '[Dataset]Module11TrainReducedQualityAssuranceSystem'
# 클래스는 이러한 이름을 가진 각 디렉토리의 폴더입니다.
classes = ['cracked','uncracked']
#classes = ['blue','red', 'yellow']
# 우리의 인공 신경망은 특정 크기 224X224 이미지를 처리합니다.
# 따라서 우리는 먼저 이미지 크기를 변환합니다.
data_transform = transforms.Compose([transforms.RandomResizedCrop(244), transforms.ToTensor()])
train_data = datasets.ImageFolder(train_dir, transform=data_transform)
#test_data = datasets.ImageFolder(test_dir, transform=data_transform)
Task 1: 훈련 데이터의 길이 출력
# your code here
print("Num training images: ", len(train_data))
Num training images: 240
train_c_dir = '[Dataset]Module11TrainReducedQualityAssuranceSystem/cracked'
train_uc_dir = '[Dataset]Module11TrainReducedQualityAssuranceSystem/uncracked'
#train_c_dir = 'signal/red'
#train_uc_dir = 'signal/blue'
def get_files_count(folder_path):
dirListing = os.listdir('./' + folder_path)
return len(dirListing)
print("Cracked image 개수:", get_files_count(train_c_dir))
print("Uncraked image 개수:", get_files_count(train_uc_dir))
#print("빨간 신호등 개수:", get_files_count(train_c_dir))
#print("파란 신호등 개수:", get_files_count(train_uc_dir))
Cracked image 개수: 120 Uncraked image 개수: 120
# 매개변수 정의
batch_size = 50
train_loader = torch.utils.data.DataLoader(train_data, batch_size=batch_size, shuffle=True)
#test_loader = torch.utils.data.DataLoader(test_data, batch_size=batch_size, shuffle=True)
# 일부 이미지를 표시해 보겠습니다.
dataiter = iter(train_loader)
images, labels = next(dataiter)
images = images.numpy() # 표시를 위해 이미지를 numpy로 변환
# 해당 라벨과 함께 배치 이미지를 보여줍니다.
fig = plt.figure(figsize=(25, 4))
for idx in np.arange(20):
ax = fig.add_subplot(2, 10, idx+1, xticks=[], yticks=[])
plt.imshow(np.transpose(images[idx], (1, 2, 0)))
ax.set_title(classes[labels[idx]])
훈련 시작하기 먼저!!!!
만일! CPU보다 GPU 쿠다등 성능이 더 좋고 빠르다!
라고 한다면.. CUDA로 쓰라는 코드 유무를 확인하고, 없을 경우 변경해둘것!!!!!
만약.. gpu가 멀쩡히 있는데도 작동을 안한다면…
cuda 전용 소프트웨어 설치가 시급..
https://normal-engineer.tistory.com/163 - 참고1
쿠다가 정상적으로 되어있어도 만일 안된다면 pytorch 재설치를 해야함…
cuda version에 맞게;;;
https://pytorch.org/get-started/locally/
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print(device)
cuda:0
# GPU 사용가능인지 확인
torch.cuda.is_available()
True
# 모델을 초기화 합니다.
vgg16 = models.vgg16(weights=True)
vgg16 = vgg16.to(device) # 쿠다로 가능하도록..
# 모델 구조 출력
print(vgg16)
C:\Users\User\.conda\envs\myai\lib\site-packages\torchvision\models\_utils.py:223: UserWarning: Arguments other than a weight enum or `None` for 'weights' are deprecated since 0.13 and may be removed in the future. The current behavior is equivalent to passing `weights=VGG16_Weights.IMAGENET1K_V1`. You can also use `weights=VGG16_Weights.DEFAULT` to get the most up-to-date weights. warnings.warn(msg)
VGG(
(features): Sequential(
(0): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(1): ReLU(inplace=True)
(2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(3): ReLU(inplace=True)
(4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(5): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(6): ReLU(inplace=True)
(7): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(8): ReLU(inplace=True)
(9): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(10): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(11): ReLU(inplace=True)
(12): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(13): ReLU(inplace=True)
(14): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(15): ReLU(inplace=True)
(16): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(17): Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(18): ReLU(inplace=True)
(19): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(20): ReLU(inplace=True)
(21): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(22): ReLU(inplace=True)
(23): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(24): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(25): ReLU(inplace=True)
(26): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(27): ReLU(inplace=True)
(28): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(29): ReLU(inplace=True)
(30): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)
(avgpool): AdaptiveAvgPool2d(output_size=(7, 7))
(classifier): Sequential(
(0): Linear(in_features=25088, out_features=4096, bias=True)
(1): ReLU(inplace=True)
(2): Dropout(p=0.5, inplace=False)
(3): Linear(in_features=4096, out_features=4096, bias=True)
(4): ReLU(inplace=True)
(5): Dropout(p=0.5, inplace=False)
(6): Linear(in_features=4096, out_features=1000, bias=True)
)
)
# 입력 및 출력 feature 수를 출력해 보겠습니다.
print(vgg16.classifier[6].in_features)
print(vgg16.classifier[6].out_features)
4096 1000
훈련
테스트 데이터에서 이상을 식별할 수 있도록 VGG 모델을 사용하여 데이터 세트를 훈련합니다. 이를 위해 softmax 함수와 categorical_crossentropy 손실 함수를 사용할 것입니다.
softmax 함수는 지수 함수이며 분류 및 회귀 방법에 사용됩니다. Softmax 함수는 잠재적 결과 목록의 확률 분포를 나타내는 벡터를 출력합니다. 자세한 내용은 Softmax를 참조하십시오.
범주형 교차엔트로피(Categorical crossentropy)는 분류 작업에 사용되는 손실 함수입니다. 손실 함수는 분류가 얼마나 좋은지를 나타내는 척도입니다. 손실이 낮을수록 분류가 잘된 것입니다. 자세한 내용은 loss에서 확인하세요.
하나의 Epoch는 전체 데이터 세트가 신경망을 통해 한 번 앞뒤로 전달되는 경우입니다. 배치 크기는 단일 배치에 있는 훈련 예제의 총 수입니다.
# VGG 모델에는 컨볼루션 레이어, 최대 풀링 레이어 및 고밀도 레이어와 같은 다양한 레이어가 있습니다.
# 우리는 계산을 위해 모든 레이어를 사용할 필요는 없습니다.
# 모든 "특징" 레이어에 대한 훈련 동결
for param in vgg16.features.parameters():
param.requires_grad = False
n_inputs = vgg16.classifier[6].in_features
last_layer = nn.Linear(n_inputs, len(classes)).to(device)
vgg16.classifier[6] = last_layer
import torch.optim as optim
# 손실 함수 지정(범주형 교차 엔트로피)
criterion = nn.CrossEntropyLoss().to(device)
# optimizer는 stochastic gradient descent로 지정
# 학습률(learning rate) = 0.001
optimizer = optim.SGD(vgg16.classifier.parameters(), lr=0.001)
Training
n_epochs = 60
larr = []
for epoch in range(1, n_epochs+1):
# 훈련 및 검증 손실 추적
train_loss = 0.0
###################
# train the model #
###################
# 기본적으로 모델은 훈련으로 설정되어 있습니다.
for batch_i, (data, target) in enumerate(train_loader):
data = data.to(device)
target = target.to(device)
# CUDA를 사용할 수 있는 경우 텐서를 GPU로 이동
optimizer.zero_grad()
# 순방향 전달: 입력을 모델에 전달하여 예측된 출력을 계산합니다.
output = vgg16(data)
# 배치 손실을 계산
loss = criterion(output, target)
# 역방향 패스: 모델 매개변수에 대한 손실 기울기 계산
loss.backward()
# 단일 최적화 단계 수행(매개변수 업데이트)
optimizer.step()
# 훈련 손실 업데이트
train_loss += loss.item()
if epoch % 1 == 0: # 지정된 수의 미니 배치마다 훈련 손실 출력
print('Epoch %d, Batch %d loss: %.16f' %
(epoch, batch_i + 1, train_loss / 32))
larr.append(train_loss / 32)
train_loss = 0.0
Epoch 1, Batch 1 loss: 0.0223015006631613 Epoch 1, Batch 2 loss: 0.0225327182561159 Epoch 1, Batch 3 loss: 0.0221402570605278 Epoch 1, Batch 4 loss: 0.0213284045457840 Epoch 1, Batch 5 loss: 0.0238252207636833 Epoch 2, Batch 1 loss: 0.0228128693997860 Epoch 2, Batch 2 loss: 0.0217789486050606 Epoch 2, Batch 3 loss: 0.0211439821869135 Epoch 2, Batch 4 loss: 0.0221301298588514 Epoch 2, Batch 5 loss: 0.0220028869807720 Epoch 3, Batch 1 loss: 0.0216766241937876 Epoch 3, Batch 2 loss: 0.0216344818472862 Epoch 3, Batch 3 loss: 0.0217473953962326 Epoch 3, Batch 4 loss: 0.0217833500355482 Epoch 3, Batch 5 loss: 0.0211814008653164 ...... Epoch 59, Batch 1 loss: 0.0202604718506336 Epoch 59, Batch 2 loss: 0.0209795162081718 Epoch 59, Batch 3 loss: 0.0210705287754536 Epoch 59, Batch 4 loss: 0.0203020982444286 Epoch 59, Batch 5 loss: 0.0206648670136929 Epoch 60, Batch 1 loss: 0.0216166395694017 Epoch 60, Batch 2 loss: 0.0212676469236612 Epoch 60, Batch 3 loss: 0.0198379606008530 Epoch 60, Batch 4 loss: 0.0214051157236099 Epoch 60, Batch 5 loss: 0.0211311690509319
# 손실 그래프
plt.plot(larr)
[<matplotlib.lines.Line2D at 0x1ad550d1c40>]
Task 2: 학습률을 0.1, 0.0001로 변경하고 네트워크를 다시 훈련시키십시오.
시간이 더 걸리나요?
이전엔..
loss: 0.0212165545672178 (최종)
gpu cuda 기준으로 30초 정도..
학습률 변경 후.. : 0.1
loss: 0.0191897824406624 (최종)
gpu cuda 기준으로 30초 정도..
학습률 변경 후.. : 0.0001
loss: 0.0210543293505907 (최종)
gpu cuda 기준으로 30초 정도..
시간은 별 차이가 없을… cpu로 하면 차이가 날려나….
Task 3: Epoch 수를 60, 10 으로 변경하여 네트워크를 다시 훈련시키십시오.
손실이 어떻게 변화하나요?
학습율은 0.001 그대로에서 epoch를 60 이나 10으로 변경.
60으로…
Epoch 60, Batch 5 loss: 0.0149131594225764
10으로..
Epoch 10, Batch 5 loss: 0.0219363141804934
결론..
살짝은 줄지만.. 데이터 양을 생각하면.. 그렇게.. 차이는..
만일.. 원래 데이터 양으로 한다면…
이때까지는 축소된 데이터양으로 진행. 그렇다보니.. 시간차이도 오류율도 그대로 일 수도있다.
그렇다면 원래 훈련 데이터로 하게된다면..
step1
# 훈련 및 테스트 데이터 디렉토리 정의
# [Dataset]Module11TrainReducedQualityAssuranceSystem을 사용하여 훈련 시간을 줄일 수도 있습니다.
train_dir = '[Dataset]Module11TrainReducedQualityAssuranceSystem'
# 클래스는 이러한 이름을 가진 각 디렉토리의 폴더입니다.
classes = ['cracked','uncracked']
#classes = ['blue','red', 'yellow']
# 우리의 인공 신경망은 특정 크기 224X224 이미지를 처리합니다.
# 따라서 우리는 먼저 이미지 크기를 변환합니다.
data_transform = transforms.Compose([transforms.RandomResizedCrop(244), transforms.ToTensor()])
train_data = datasets.ImageFolder(train_dir, transform=data_transform)
#test_data = datasets.ImageFolder(test_dir, transform=data_transform)
# your code here
print("Num training images: ", len(train_data))
train_c_dir = '[Dataset]Module11TrainQualityAssuranceSystem/cracked'
train_uc_dir = '[Dataset]Module11TrainQualityAssuranceSystem/uncracked'
#train_c_dir = 'signal/red'
#train_uc_dir = 'signal/blue'
print("Cracked image 개수:", get_files_count(train_c_dir))
print("Uncraked image 개수:", get_files_count(train_uc_dir))
#print("빨간 신호등 개수:", get_files_count(train_c_dir))
#print("파란 신호등 개수:", get_files_count(train_uc_dir))
Num training images: 240 Cracked image 개수: 7501 Uncraked image 개수: 7449
# 매개변수 정의
batch_size = 50
train_loader = torch.utils.data.DataLoader(train_data, batch_size=batch_size, shuffle=True)
#test_loader = torch.utils.data.DataLoader(test_data, batch_size=batch_size, shuffle=True)
# 일부 이미지를 표시해 보겠습니다.
dataiter = iter(train_loader)
images, labels = next(dataiter)
images = images.numpy() # 표시를 위해 이미지를 numpy로 변환
# 해당 라벨과 함께 배치 이미지를 보여줍니다.
fig = plt.figure(figsize=(25, 4))
for idx in np.arange(20):
ax = fig.add_subplot(2, 10, idx+1, xticks=[], yticks=[])
plt.imshow(np.transpose(images[idx], (1, 2, 0)))
ax.set_title(classes[labels[idx]])
step2
여기서는 모델 생성은 패스, 바로 훈련준비
# VGG 모델에는 컨볼루션 레이어, 최대 풀링 레이어 및 고밀도 레이어와 같은 다양한 레이어가 있습니다.
# 우리는 계산을 위해 모든 레이어를 사용할 필요는 없습니다.
# 모든 "특징" 레이어에 대한 훈련 동결
for param in vgg16.features.parameters():
param.requires_grad = False
n_inputs = vgg16.classifier[6].in_features
last_layer = nn.Linear(n_inputs, len(classes)).to(device)
vgg16.classifier[6] = last_layer
# 손실 함수 지정(범주형 교차 엔트로피)
criterion = nn.CrossEntropyLoss().to(device)
# optimizer는 stochastic gradient descent로 지정
# 학습률(learning rate) = 0.001
optimizer = optim.SGD(vgg16.classifier.parameters(), lr=0.001)
step3 훈련
n_epochs = 60
larr = []
for epoch in range(1, n_epochs+1):
# 훈련 및 검증 손실 추적
train_loss = 0.0
###################
# train the model #
###################
# 기본적으로 모델은 훈련으로 설정되어 있습니다.
for batch_i, (data, target) in enumerate(train_loader):
data = data.to(device)
target = target.to(device)
# CUDA를 사용할 수 있는 경우 텐서를 GPU로 이동
optimizer.zero_grad()
# 순방향 전달: 입력을 모델에 전달하여 예측된 출력을 계산합니다.
output = vgg16(data)
# 배치 손실을 계산
loss = criterion(output, target)
# 역방향 패스: 모델 매개변수에 대한 손실 기울기 계산
loss.backward()
# 단일 최적화 단계 수행(매개변수 업데이트)
optimizer.step()
# 훈련 손실 업데이트
train_loss += loss.item()
if epoch % 1 == 0: # 지정된 수의 미니 배치마다 훈련 손실 출력
print('Epoch %d, Batch %d loss: %.16f' %
(epoch, batch_i + 1, train_loss / 32))
larr.append(train_loss / 32)
train_loss = 0.0
Epoch 1, Batch 1 loss: 0.0220786780118942 Epoch 1, Batch 2 loss: 0.0213427897542715 Epoch 1, Batch 3 loss: 0.0214892216026783 Epoch 1, Batch 4 loss: 0.0223208907991648 Epoch 1, Batch 5 loss: 0.0228392165154219 Epoch 2, Batch 1 loss: 0.0213486142456532 Epoch 2, Batch 2 loss: 0.0223400648683310 Epoch 2, Batch 3 loss: 0.0210086181759834 Epoch 2, Batch 4 loss: 0.0210963506251574 Epoch 2, Batch 5 loss: 0.0221033729612827 Epoch 3, Batch 1 loss: 0.0223134066909552 Epoch 3, Batch 2 loss: 0.0205910205841064 Epoch 3, Batch 3 loss: 0.0216252747923136 Epoch 3, Batch 4 loss: 0.0231794379651546 Epoch 3, Batch 5 loss: 0.0217113532125950 Epoch 4, Batch 1 loss: 0.0221475269645452 Epoch 4, Batch 2 loss: 0.0217335876077414 Epoch 4, Batch 3 loss: 0.0214411299675703 Epoch 4, Batch 4 loss: 0.0228641703724861 Epoch 4, Batch 5 loss: 0.0212537497282028 ...... Epoch 59, Batch 1 loss: 0.0194798819720745 Epoch 59, Batch 2 loss: 0.0212294012308121 Epoch 59, Batch 3 loss: 0.0206220932304859 Epoch 59, Batch 4 loss: 0.0210658423602581 Epoch 59, Batch 5 loss: 0.0217369534075260 Epoch 60, Batch 1 loss: 0.0215414837002754 Epoch 60, Batch 2 loss: 0.0190316364169121 Epoch 60, Batch 3 loss: 0.0195462927222252 Epoch 60, Batch 4 loss: 0.0218246001750231 Epoch 60, Batch 5 loss: 0.0197362415492535
step4 훈련그래프 결과
# 손실 그래프
plt.plot(larr)
[<matplotlib.lines.Line2D at 0x1ad54f07cd0>]
결론
epoch = 60, learning rate = 0.001, batch를 줄여서 시도…
마지막 로그 : Epoch 60, Batch 5 loss: 0.0214790515601635
걸린 시간 : 대략 1분..
별 차이는 없어보임…
신호등으로 해보자
이번엔 신호등 파란불, 빨간불 구분으로 학습을…
step1
# 훈련 및 테스트 데이터 디렉토리 정의
# [Dataset]Module11TrainReducedQualityAssuranceSystem을 사용하여 훈련 시간을 줄일 수도 있습니다.
train_dir = 'signal'
# 클래스는 이러한 이름을 가진 각 디렉토리의 폴더입니다.
# classes = ['cracked','uncracked']
#classes = ['blue','red', 'yellow']
classes = ['blue', 'red']
# 우리의 인공 신경망은 특정 크기 224X224 이미지를 처리합니다.
# 따라서 우리는 먼저 이미지 크기를 변환합니다.
data_transform = transforms.Compose([transforms.RandomResizedCrop(244), transforms.ToTensor()])
train_data = datasets.ImageFolder(train_dir, transform=data_transform)
#test_data = datasets.ImageFolder(test_dir, transform=data_transform)
# your code here
print("Num training images: ", len(train_data))
#train_c_dir = '[Dataset]Module11TrainQualityAssuranceSystem/cracked'
#train_uc_dir = '[Dataset]Module11TrainQualityAssuranceSystem/uncracked'
train_c_dir = 'signal/red'
train_uc_dir = 'signal/blue'
#print("Cracked image 개수:", get_files_count(train_c_dir))
#print("Uncraked image 개수:", get_files_count(train_uc_dir))
print("빨간 신호등 개수:", get_files_count(train_c_dir))
print("파란 신호등 개수:", get_files_count(train_uc_dir))
Num training images: 200 빨간 신호등 개수: 99 파란 신호등 개수: 101
# 매개변수 정의
batch_size = 50
train_loader = torch.utils.data.DataLoader(train_data, batch_size=batch_size, shuffle=True)
#test_loader = torch.utils.data.DataLoader(test_data, batch_size=batch_size, shuffle=True)
# 일부 이미지를 표시해 보겠습니다.
dataiter = iter(train_loader)
images, labels = next(dataiter)
images = images.numpy() # 표시를 위해 이미지를 numpy로 변환
# 해당 라벨과 함께 배치 이미지를 보여줍니다.
fig = plt.figure(figsize=(25, 4))
for idx in np.arange(20):
ax = fig.add_subplot(2, 10, idx+1, xticks=[], yticks=[])
plt.imshow(np.transpose(images[idx], (1, 2, 0)))
ax.set_title(classes[labels[idx]])
step2
여기서는 모델 생성은 패스, 바로 훈련준비
# VGG 모델에는 컨볼루션 레이어, 최대 풀링 레이어 및 고밀도 레이어와 같은 다양한 레이어가 있습니다.
# 우리는 계산을 위해 모든 레이어를 사용할 필요는 없습니다.
# 모든 "특징" 레이어에 대한 훈련 동결
for param in vgg16.features.parameters():
param.requires_grad = False
n_inputs = vgg16.classifier[6].in_features
last_layer = nn.Linear(n_inputs, len(classes)).to(device)
vgg16.classifier[6] = last_layer
# 손실 함수 지정(범주형 교차 엔트로피)
criterion = nn.CrossEntropyLoss().to(device)
# optimizer는 stochastic gradient descent로 지정
# 학습률(learning rate) = 0.001
optimizer = optim.SGD(vgg16.classifier.parameters(), lr=0.001)
step3 훈련
n_epochs = 60
larr = []
for epoch in range(1, n_epochs+1):
# 훈련 및 검증 손실 추적
train_loss = 0.0
###################
# train the model #
###################
# 기본적으로 모델은 훈련으로 설정되어 있습니다.
for batch_i, (data, target) in enumerate(train_loader):
data = data.to(device)
target = target.to(device)
# CUDA를 사용할 수 있는 경우 텐서를 GPU로 이동
optimizer.zero_grad()
# 순방향 전달: 입력을 모델에 전달하여 예측된 출력을 계산합니다.
output = vgg16(data)
# 배치 손실을 계산
loss = criterion(output, target)
# 역방향 패스: 모델 매개변수에 대한 손실 기울기 계산
loss.backward()
# 단일 최적화 단계 수행(매개변수 업데이트)
optimizer.step()
# 훈련 손실 업데이트
train_loss += loss.item()
if epoch % 1 == 0: # 지정된 수의 미니 배치마다 훈련 손실 출력
print('Epoch %d, Batch %d loss: %.16f' %
(epoch, batch_i + 1, train_loss / 32))
larr.append(train_loss / 32)
train_loss = 0.0
Epoch 1, Batch 1 loss: 0.0210936516523361 Epoch 1, Batch 2 loss: 0.0229267030954361 Epoch 1, Batch 3 loss: 0.0230638626962900 Epoch 1, Batch 4 loss: 0.0216429680585861 Epoch 2, Batch 1 loss: 0.0223056431859732 Epoch 2, Batch 2 loss: 0.0218394976109266 Epoch 2, Batch 3 loss: 0.0207645148038864 Epoch 2, Batch 4 loss: 0.0240599196404219 Epoch 3, Batch 1 loss: 0.0218602158129215 Epoch 3, Batch 2 loss: 0.0228070020675659 Epoch 3, Batch 3 loss: 0.0222926754504442 Epoch 3, Batch 4 loss: 0.0212500169873238 Epoch 4, Batch 1 loss: 0.0237588230520487 Epoch 4, Batch 2 loss: 0.0225628595799208 Epoch 4, Batch 3 loss: 0.0215207394212484 Epoch 4, Batch 4 loss: 0.0201022438704967 ....... Epoch 58, Batch 1 loss: 0.0156913977116346 Epoch 58, Batch 2 loss: 0.0115372277796268 Epoch 58, Batch 3 loss: 0.0145329367369413 Epoch 58, Batch 4 loss: 0.0145702371373773 Epoch 59, Batch 1 loss: 0.0159023050218821 Epoch 59, Batch 2 loss: 0.0160456486046314 Epoch 59, Batch 3 loss: 0.0157261490821838 Epoch 59, Batch 4 loss: 0.0127053381875157 Epoch 60, Batch 1 loss: 0.0168359708040953 Epoch 60, Batch 2 loss: 0.0131517192348838 Epoch 60, Batch 3 loss: 0.0156200854107738 Epoch 60, Batch 4 loss: 0.0160929299890995
step4 훈련그래프 결과
# 손실 그래프
plt.plot(larr)
[<matplotlib.lines.Line2D at 0x1ad5367d160>]
결론
epoch = 60, learning rate = 0.001
이정도 설정으로 배치4까지 반복으로 진행.
걸린시간은 1분
Epoch 60, Batch 4 loss: 0.0139679992571473
그래프 까지 참조해본 결과 학습이 잘 됨을 볼 수 있음.
최종결론
데이터가 중요하다.
그 외로…
10, 50, 100원 동전 구별하는 데이터셋 준비중…
정제 후, 들어가야 결과가 나오니…
이 파트는 추후 여유되는대로 다시 업로드..
Conclusion
이 노트북에서는 AI가 이상 탐지에 어떻게 사용되는지 살펴보았습니다. 우리는 벽 이미지의 균열을 식별하기 위해 신경망을 훈련시켰습니다. 우리는 이상 징후를 감지하고 이상치를 거부할 수 있도록 기계 학습 시스템을 훈련할 수 있습니다.
마무리…
-
이미지처리로 어떠한 모델로 쓰이며, 어떠한 프레임워크로 하는지 익히는 계기가 됨.
-
cpu보다 gpu가 더 빠른건 말 안해도 진리일듯하다.
단, gpu로 할거라면 모델, 데이터 처리할때 일원화 되도록 해야 돌아감!
-
pytorch가 왜 자주 쓰이는지 알 것 같기도…
-
그 외 데이터 추가해서 크랙유무, 신호등으로 해보았는데 아래와 같은 사항들이 중요할 것 같다.
- 데이터를 잘 분별해서 수집, 구별이 중요하다. 첫 단추가 시작의 반이다고 하듯..
- 반복(에포크), 학습률(lr)등 적당한 수치가 가장 중요하다.
그 외 참조한 사이트들.
https://stackoverflow.com/questions/62549990/what-does-next-and-iter-do-in-pytorchs-dataloader
만일.. iter next라는 함수를 못찾는 경우….
버전이 바뀌면 써야되는 함수형태도..
https://wandb.ai/wandb_fc/korean/reports/PyTorch-GPU—VmlldzoxNTEwNjg5
pytorch를 gpu cuda로 돌리는 방법1
주의사항
본 포트폴리오는 인텔 AI 저작권에 따라 그대로 사용하기에 상업적으로 사용하기 어려움을 말씀드립니다.
댓글남기기