2022년 11월 13일 일요일

우분투 22.04, GTX 3090 기반 딥러닝 개발 환경 설치하기

이 글은 우분투 22.04, GTX 3090 기반 딥러닝 개발 환경 설치하는 순서를 간단히 요약한다.

  1. 우분투 22.04 설치
  2. 우분투 업데이트
  3. 디펜던시 패키지 설치
  4. 개발 도구 설치
  5. 파이썬 3 설치
  6. Git 설치
  7. NVIDIA 470 드라이버 설치
  8. CUDA 설치
  9. 머신러닝 환경 설치
상세한 내용은 레퍼런스를 참고하라. 

행운을 빈다.


레퍼런스

2022년 11월 6일 일요일

화학, 재료 분자, 다차원 형상 데이터 학습, 예측, 재구성에 사용되는 GCN(Graph Convolutional Networks. GNN)과 GDL (Geometric Deep Learning)에 대해

Introduction
많은 유용한 딥러닝 기술이 릴리즈되고 있다. 그 중에  GCN(Graph Convolutional Networks. GNN)과 GDL (Geometric Deep Learning)에 대해 이야기를 나누어 보자.

GCN은 다음 그림과 같이, 재료를 구성하는 화학 분자 분석, 탐지 및 설계, 영상 컨텍스트 해석 및 생성, 다차원 포인트 클라우드 세그먼테이션 등 다양한 영역에서 사용된다. 

GCN based application (Chemical toxicity prediction based on semi-supervised learning and graph convolutional neural network. link)
GCN based application (Applications of Graph Neural Networks. link)
GCN based application (Learning 3D Semantic Scene Graphs from 3D Indoor Reconstructions. link)
Example. Machine Learning for Scent: Learning Generalizable Perceptual Representations of Small Molecules (link)

Deep learning (Michael Bronstein, 2021, Geometric foundations of Deep Learning)

GCN은 용어 그대로 CNN개념을 행렬로 보았을때 바로 인접되지 않은 데이터에대한 특징을 추출할 수 있는 필터 역할을 한다. 
CNN feature map visualization (link)

GCN(Graph Convolutional Networks. GNN-Graph Neural Network)
GCN은 다음 그림 우측과 같이 인접되지 않은 그래프 형식의 데이터에서 특징을 추출할 때 유용한다.

CNN, GNN(Zongham al et, 2019, A Comprehensive Survey on Graph Neural Network)

일반적으로, CNN은 데이터를 구성하는 텐서의 인접 요소에서 특징을 수집해, 특징 벡터를 생성한다. 
CNN(Thomas Kipf, Topics in AI (CPSC 532S): Multimodal Learning with Vision, Language and Sound. Link)

그래프 형식 데이터는 이런 방식이 불가능하므로, 다음과 같은 인접행렬을 구성해, 그래프 요소간 연결성을 정의하고, 주변 인접 데이터와 관계를 포함한 특징을 계산해야 한다. 
Adjacency Matrix (link)

다음 우측 그림에서 적색 노드 근처 인접된 노드의 특징을 수집해 특징 벡터를 계산해야 한다면, kNN으로 알려진 인접 노드들을 탐색한 후, 인접 행렬을 구성해야 한다. 다음 수식에서 Ni는 이웃 노드 인덱스, Cij는 정규화를 위한 팩터, h는 노드의 특징 벡터, l은 노드 인덱스를 의미한다. 
CNN(Thomas Kipf, Link)

Node, Link, Graph prediction
GCN은 노드, 링크로 구성되는 그래프 데이터에 대한 학습이 가능하다. 다음은 학습된 모델을 통해, 가능한 데이터 분류, 에측, 재구성 등의 사례를 보여준다. 
GNN based classification(Zongham al et, 2019)

GNN based reconstruction(Zongham al et, 2019)

GDL(Geometric Deep Learning)
GDL은 GCN을 이용해 기하학적 딥러닝 모델을 정의할 수 있음을 설명하는 용어이다. 분자 구조, 다차원 포인트 등은 결론적으로 기하학적으로 다차원 요소간의 관계를 표현한 그래프 구조이다. GDL은 가장 떠오르는 딥러닝 분야 중 하나이다.
Non-Euclidean Data(Flawnson Tong, 2019, What is Geometric Deep Learning?)
다차원 데이터를 학습하는 것은 쉽지 않다. 최근 이 기술과 관련된 컨퍼런스가 개최되었다.

또한, 이 기술과 관련된 PyTorch Geometric 오픈소스 프로젝트가 개발되고 있다.
PyG (PyTorch Geometric) (githublink)

PyTorch Geometry 라이브러리는 화학 분자 모델과 같은 위상 그래프 형식 데이터셋을 딥러닝 방식으로 학습, 계산, 분류, 해석하기 위해 개발된 오픈소스로 많이 활용되고 있다. 
이외 다른 오픈소스 라이브러리는 다음 링크를 참고한다.

Practice
GCN과 유사한 개념 사용 사례로, 다음과 같이 스캔된 3차원 데이터셋을 분류하는 PointNet 딥러닝 모델이 있다. 스캔된 포인트 클라우드 해석도 그래프 모델로 분석할 수 있다. 

포인트 클라우드의 각 포인트는 화학 분자처럼 특징을 가지고, 포인트 간의 관계를 가진다. 이를 통해, 제시된 포인트 집합이 어떤 종류인지 해석 및 예측할 수 있다. 이는 화학 분자식을 이용해 어떤 단백질인지 예측하는 사례와 개념적으로 동일하다. 

다음 표시된 링크에 실행 코드를 확인할 수 있다. 
3D Object detection classifier (link. explain)

PointGNN은 포인트 클라우드 세그먼테이션에 GNN을 사용한다. 
PointGNN (github)

MeshGraphNet은 학습 모델에 의해 메쉬를 복원한다.
MeshGraphNet (github)

다음은 GNN 관련 유명예제인 카라테 쇼셜 클럽 그래프 데이터를 학습하고 예측하는 예제이다. 
Kerate club classification (colab)

그래프 데이터로 표현된 분자 모델들을 학습해, 용해도를 예측한다. 학습 모델에 목적에 맞게 다양한 분류, 복원이 가능하다(분자 모델 구조에서 향기 분류, 강도 등 분석 예측. 모델 구조 재구성 등). 
GNN classification for molecular structure (colab)

다음은 심장독성 특징이 있는 화학물 분자구조를 예측하는 모델 예이다. 
TF-GNN (kaggle)
Conclusion
이 글은 GCN, GDL의 개념, 사용 라이브러리, 응용 사례에 대해 정리해 보았다. GCN은 아직 이미지, 자연어 딥러닝 분야에 비해 발전 속도가 느리다. 데이터셋 한계, 대용량 데이터셋 이슈, 계산 과정의 복잡성 등의 문제가 있지만, 오픈소스 커뮤니티를 통해 이런 문제가 해결되고 있는 중이다. 이 분야는 하드웨어 성능 개선과 더불어 꾸준히 발전할 것이다. 

GCN 기술 개발 역사 (link)

Reference




2022년 10월 31일 월요일

파이썬 기반 데이터 처리 파이프라인 소개

이 글은 파이썬 기반 데이터 처리 파이프라인에 대한 간단한 소개이다.


파이썬에는 데이터를 처리 분석하기 위한 유용한 도구가 많다. 이는 보통 ETL도구로도 알려져 있다. 

AirBnB에서 개발한 Airflow를 사용하면 작업 실행 시점 및 흐름을 정의할 수 있다. Pandas를 이용하면 엑셀 등 다양한 데이터소스를 엑셀처럼 행렬로 계산 분석할 수 있다. 

이와 bonobo (https://www.bonobo-project.org/) 등을 이용하면 파이썬 기반 ETL을 수행할 수 있다. 예를 들어 다음 그림과 같이 이멜 수신에서 특정 텍스트 패턴을 마이닝해 추출된 정보를 몽고디비에 저장하는 등의 작업을 손쉽게 개발할 수 있다. 

참고
https://www.innuy.com/blog/build-data-pipeline-python/

2022년 8월 20일 토요일

간단한 Mask R-CNN 기반 객체 세그먼테이션 딥러닝 학습 및 예측 프로그램 만들기

이 글은 Mask R-CNN 기반 객체 세그먼테이션 딥러닝 학습 및 예측 프로그램 개발 방법을 간략히 설명한다. 객체 감지 및 인스턴스 분할은 이미지에서 객체를 식별하고 분할하는 작업이다. 여기에는 각 객체에 대한 경계 상자, 정확한 객체를 덮는 마스크 및 객체 클래스를 찾는 작업이 포함된다. Mask R-CNN 은 이를 달성하기 위한 가장 일반적인 방법 중 하나이다. 이 글은 Mask R-CNN의 이론적 내용을 자세히 설명하지는 않는다(자세한 내용은 레퍼런스를 참고한다).
세그먼테이션된 객체들
Fast R-CNN 아키텍처 개념도

개발 환경 설정
개발을 위해, 파이썬 및 파이토치 개발 환경을 마련한 후(참고), 다음 라이브러리를 설치한다. 
pip install opencv-python

구현하기
다음과 같이, 토치비전에서 R-CNN 라이브러리를 불러오고, 초기화한다.
import random
from torchvision.models.detection.faster_rcnn import FastRCNNPredictor
import numpy as np
import torch.utils.data
import cv2
import torchvision.models.segmentation
import torch
import os
batchSize=2
imageSize=[600,600]
device = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')

다음과 같이 이미지 경로를 변수에 설정한다. 
trainDir="LabPicsChemistry/Train"

imgs=[]
for pth in os.listdir(trainDir):
    imgs.append(trainDir+"/"+pth +"//")

해당 이미지는 다음과 같이 특정 경로에 마스크 이미지가 저장되어 있다고 가정한다(참고 - 연구실 학습용 데이터셋 다운로드 링크). 앞의 trainDir 변수 경로에 맞게, 학습용 데이터셋 폴더 경로가 설정되어 있도록 한다.

저장된 데이터들을 로딩한 후, 학습에 맞게 변환하는 코드를 구현한다.
def loadData():
  batch_Imgs=[]
  batch_Data=[]
  for i in range(batchSize):
        idx=random.randint(0,len(imgs)-1)
        img = cv2.imread(os.path.join(imgs[idx], "Image.jpg"))
        img = cv2.resize(img, imageSize, cv2.INTER_LINEAR)    # 이미지 크기 변환
        maskDir=os.path.join(imgs[idx], "Vessels")
        masks=[]
        for mskName in os.listdir(maskDir):
            vesMask = cv2.imread(maskDir+'/'+mskName, 0)
            vesMask = (vesMask > 0).astype(np.uint8) 
            vesMask=cv2.resize(vesMask,imageSize,cv2.INTER_NEAREST)
            masks.append(vesMask)
        num_objs = len(masks)
        if num_objs==0: return loadData()
        boxes = torch.zeros([num_objs,4], dtype=torch.float32)
        for i in range(num_objs):
            x,y,w,h = cv2.boundingRect(masks[i])
            boxes[i] = torch.tensor([x, y, x+w, y+h])
        masks = torch.as_tensor(masks, dtype=torch.uint8)
        img = torch.as_tensor(img, dtype=torch.float32)    # 텐서 데이터로 변환
        data = {}
        data["boxes"] =  boxes
        data["labels"] =  torch.ones((num_objs,), dtype=torch.int64)   
        data["masks"] = masks
        batch_Imgs.append(img)
        batch_Data.append(data)  
  
  batch_Imgs=torch.stack([torch.as_tensor(d) for d in batch_Imgs],0)
  batch_Imgs = batch_Imgs.swapaxes(1, 3).swapaxes(2, 3)
  return batch_Imags, batch_Data

다음과 같이, 딥러닝 학습 코드를 구현한다.
model=torchvision.models.detection.maskrcnn_resnet50_fpn(pretrained=True)  # 전이학습

for i in range(10001):
   images, targets = loadData()
   images = list(image.to(device) for image in images)
   targets=[{k: v.to(device) for k,v in t.items()} for t in targets]
   
   optimizer.zero_grad()
   loss_dict = model(images, targets)   # 모델 손실 계산
   losses = sum(loss for loss in loss_dict.values())
   
   losses.backward()    # 역전파   
   optimizer.step()       # 신경망 가중치 업데이트
   
   print(i,'loss:', losses.item())
   if i%200==0:
           torch.save(model.state_dict(), str(i)+".torch")
           print("Save model to:",str(i)+".torch")

학습 후, 이미지 데이터를 모델에 입력해, 예측해 본다. 
images = cv2.imread(imgPath)  # 특정 경로 이미지 로딩
images = cv2.resize(images, imageSize, cv2.INTER_LINEAR)
images = torch.as_tensor(images, dtype=torch.float32).unsqueeze(0)
images=images.swapaxes(1, 3).swapaxes(2, 3)
images = list(image.to(device) for image in images)

with torch.no_grad():
    pred = model(images)  # 모델 예측. 세그먼테이션

예측 스코어가 0.8 이상 세그먼트만 출력해 본다.
im= images[0].swapaxes(0, 2).swapaxes(0, 1).detach().cpu().numpy().astype(np.uint8)
im2 = im.copy()
for i in range(len(pred[0]['masks'])):
    msk=pred[0]['masks'][i,0].detach().cpu().numpy()
    scr=pred[0]['scores'][i].detach().cpu().numpy()
    if scr>0.8 :
        im2[:,:,0][msk>0.5] = random.randint(0,255)
        im2[:, :, 1][msk > 0.5] = random.randint(0,255)
        im2[:, :, 2][msk > 0.5] = random.randint(0, 255)
cv2.imshow(str(scr), np.hstack([im,im2]))
cv2.waitKey()

다음은 예측 결과이다.

마무리
최근 이미지, 텍스트, 사운드 기반 분류, 예측, 패턴 인식, 재구성과 같은 널리 알려진 문제에 대한 솔류션은 PyTorch, Keras 등에 내장되어 쉽게 학습된 모델을 다운로드하고, 사용할 수 있게 되었다. 이러한 기능을 잘 활용한다면, 인공지능을 이용한 서비스를 좀 더 쉽게 개발할 수 있을 것이다.

레퍼런스 

2022년 7월 8일 금요일

우분투 apt-get update 시 NO_PUBKEY 문제 해결 방법

이 글은 우분투 apt-get update 시 NO_PUBKEY 문제 해결 방법을 간략히 정리한다. 

가끔 다음과 같이 실행하면, NO_PUBKEY나 EXPKEYSIG 에러 발생하는 경우가 있다.
sudo apt-get update 

에러 화면

이 경우는 업데이트 저장 사이트가 변경되거나 등의 이유로 해당 키값이 적절히 등록되어 있지 않아 발생하는 것이다. 

아래 명령으로 각 키값을 등록한다.
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-key [NO_PUBKEY 에러 키값]

EXTKEYSIG 에러는 다음 명령으로 해당 키를 삭제한다. 
sudo apt-key del [EXTKEYSIGN 에러 키값]

그럼 다음과 같이 정상적으로 업데이트된다. 

레퍼런스

2022년 7월 7일 목요일

PyTorch 소스코드 빌드 기반 설치 방법

이 글은 파이토치(PyTorch) 소스코드를 이용해 빌드 기반으로 설치하는 방법을 간략히 설명한다. 
딥러닝 프레임웍인 파이토치에 대한 상세 내용은 다른 링크를 참고한다. 
파이토치를 이용할때 가장 빈번하게 발생하는 고질적 문제는 아래와 같다. 
  • NVIDIA DRIVER, CUDA 버전 불일치로 인한 패키지 설치 에러
  • 사용 라이브러리 버전 불일치로 인한 GPU 버전 동작 에러
이런 문제를 해결하기 위해서는 소스코드를 깃허브에서 다운로드 받고 빌드해 설치해야 한다. 빌드 환경은 우분투 리눅스, CUDA 11.2 버전이며, NVIDIA GPU 드라이버는 미리 설치되어 있어야 한다. 이 부분도 많은 단계가 있다. 여기서는 모두 다 설치되어 있다고 가정한다. 

아래는 빌드 테크트리이다. 
우선, conda나 virtualenv로 가상 환경을 생성하고, 활성화한다. 

아래와 같이 관련 패키지들을 설치한다. 
conda install astunparse numpy ninja pyyaml setuptools cmake cffi typing_extensions future six requests dataclasses

github에서 pytorch 소스코드 다운로드하고 빌드한다.


만약, cuda 에러가 발생하면, 다음과 같이 설치 프로그램을 다운로드하고, 기존 cuda 삭제한 후 다시 설치한다.
 
sudo apt clean
sudo apt update
sudo apt purge nvidia-* 
sudo apt autoremove
sudo apt install -y cuda

모두 설치되면, 다음과 같이 설치 버전을 확인해 본다. 
nvidia-smi
nvcc --version
cat /usr/local/cuda/version.txt

python
import torch
torch.cuda.is_available()
torch.cuda.device(0)
torch.cuda.device_count()
torch.cuda.get_device_name(0)
torch.version.cuda







2022년 6월 11일 토요일

파이썬 GDAL 설치 시 에러 수정 방법

GDAL은 래스터와 벡터 지리공간 자료 형식을 변환하는 라이브러리이다. 오픈소스이며, OSG재단에서 관리된다. 설치 방법은 다음과 같다. 

GDAL 개념

단, 설치 시 다음과 같이 파이썬 GDAL 라이브러리 단계에서 에러 발생 경우가 있다. 이 글은 GDAL PIP 설치 시 다음과 같이 발생하는 수정 방법을 간략히 정리한 것이다.

pip install GDAL

GDAL 설치 에러 발생 화면

에러가 발생하는 이유에 대한 관련 정보도 많이 나와 있지 않은 데, 마지막 줄 로그가 힌트가 된다. 

error in GDAL setup command: use_2to3 is invalid.

use_2to3 명령은 pip 에서 사용하는 setuptools의명령으로 버전 58에서는 더이상 지원하지 않는다. 그러므로, 최신 pip setuptools에서는 에러가 발생하는 것이다. 

다음과 같이 버전을 약간 낮추어 setuptools를 설치하고 재시도해본다. 

pip install setuptools==57.4.0

그리고, 현재 GDAL 설치 버전을 확인하고, 해당 버전의 PYTHON GDAL 패키지를 설치하면 된다.

ogrinfo --version

pip install GDAL==3.0.4

GDAL 파이썬 버전 설치 성공

이제, 파이썬에서 다음과 같이 gdal을 사용할 수 있다. 

def convert_tiff_jpg():        
    options_list = [
        '-ot Byte',
        '-of JPEG',
        '-b 1',
        '-scale'
    ]           

    options_string = " ".join(options_list)
        
    gdal.Translate(
        'save_image_path.jpg',
        'image_path.tif',
        options=options_string
    )