2017년 2월 24일 금요일

머신러닝 딥러닝 신경망 개념, 종류 및 개발

1~2년 사이에 오픈소스 머신러닝 딥러닝 프레임웍과 관련 자료들이 많아졌다. 오래전 필기체 인식을 위해, 다층 역전파 신경망을 구현했던 적이 있었는 데, 처리 속도가 매우 느렸었다. 현재는 성능 좋은 GPU, CPU 덕분에 그때 반나절 걸렸던 학습이 몇 분이면 처리된다.

신경망, 딥러닝 개념은 다른 수치해석적 기법들에 비해 비교적 단순하며, 유용하다. 이 글은 딥러닝 종류, 활용, 개발 방법을 간략히 요약하였다. 종류, 활용 부분은 개념을 잘 표현하고 있다고 생각하는 레퍼런스들을 참고하였고, 개발 부분은 딥러닝 레퍼런스(김성필, wikibooks 등)에서 핵심 내용을 요약하였다. 좀 더 깊은 이해가 필요하다면, 본문에 인용된 레퍼런스들을 참고하길 바란다.

1. 딥러닝 종류 및 활용
딥러닝은 응용 목적별로 다양한 신경망으로 발전하고 있다.

1. 컨볼루션 뉴럴 네트워크
컨볼루션 뉴럴 네트워크(CNN. convolutional neural network)는 특징맵을 생성하는 필터까지도 학습이 가능해 비전(vision) 분야에서 성능이 우수하다.
CNN 기반 동물 이미지 학습 분류(PyImageSearch)

2. 순환신경망
순차적 정보가 담긴 데이터에서 규칙적인 패턴을 인식하고, 추상화된 정보를 추출할 수 있는 순환신경망(RNN. Recurrent Neural Network)은 텍스트, 음성, 음악, 영상 등 순차적 데이터를 다루는 데 적합하다. RNN은 그레디언트 소실 문제(Gradient Vanishing Problem)가 있어 패턴 학습을 못하는 경우가 있다. 이를 개선하기 위해, LSTM(Long Short Term Memory)가 개발되었다. RNN문제는 LSTM으로 어느정도 해결되어, 자동 작곡, 작사, 저술, 주가 예측 등 다양한 분야에 활용되고 있다.

LSTM 기반 음악 작곡(LSTM RNN Music Composition)

3. RBM 과 DBN
Geoff Hinton에 제안한 제한된 볼츠만 머신(RBM. Restricted Boltzmann Machine)은 비지도 학습에 활용되며, 차원 축소, 분류, 선형 회귀 분석, 필터링, 특징값 학습, 주제 모델렝에 사용할 수 있는 알고리즘이다. RBM은 undirected graph 구조이며, 노드 출력값은 확률값이다. RBM은 확률은 에너지 함수 형태로 표현되며, 에너지가 최소화되는 방향으로 학습하며, DBM을 구성하는 기본 요소이다.
RBM과 DBN 신경망 구조(Unsupervied Learning, patrickhebron.com)

심층 신뢰 신경망(DBN. Deep Belief Network)이란 잠재 변수(latent variabl)의 다중 계층으로 이뤄진 신경망으로, 사전 훈련된 RBM을 층층이 쌓아 올린 구조이다. DBN은 라벨이 없는 데이터에 대한 비지도학습이 가능하며, 부분적인 이미지에서 전체를 연상하는 일반화, 추상화 과정을 구현할 수 있다.

DBN기반 나뭇잎 이미지 훈련(Unsupervied Learning, patrickhebron.com)

4. GAN
GAN(Generative Adversarial Network. 생성 대립 신경망)은 비지도 학습 방법으로 훈련으로 학습된 패턴을 이용해, 이미지나 음성을 생성할 수 있다. GAN은 이미지 및 음성 복원 등에 적용되었다. DCGAN(Deep Convolution GAN)은 불안정한 GAN 구조를 개선해 새로운 의미를 가진 이미지를 생성할 수 있다.

5. RL
최근 구글의 딥마인드에서 개발한 관계형 네트워크(RL. Relation Networks)는 관계형 추론을 지원한다. RL을 통해, 물리적 사물, 문장, 추상적인 아이디어 들 사이에 관계를 파악해, 논리적 추론을 할 수 있다(손경호, 2017, ZDNet). 구글 딥마인드 팀은 RN을 이용해 주어진 장면을 학습시키면, 테이블 위 여러개 사각형, 구 등 다양한 모양으로 이뤄진 사물간 관계를 추론하는 데 성공하였다.

지금까지 딥러닝은 분류, 이미지 인식, 음성 인식, 번역, 이미지 생성에만 국한된 한계가 있었다. RL는 딥러닝 기술을 인간의 사고에 근사한 논리적 추론이 가능한 분야까지 확대하였다. 


여기서는 대표적인 딥러닝 신경망 모델만 설명하였다. 참고로, 응용 목적에 따라 다음 그림과 같이 다양한 신경망 모델이 있다.

좀 더 다양한 딥러닝의 종류별 응용은 다음 링크를 참고한다.

앞으로 딥러닝은 많은 분야에서 다양한 응용 사례가 나올 것이다.

신경망 구조
신경망 구조는 비교적 단순하다. 신경망은 입력층, 은닉층, 출력층으로 구성된다.
신경망 구조(wikibooks)

신경망은 특정 Input 데이터 특징 패턴이 주어졌을 때, 학습된 특정 Output 데이터를 출력하게 된다. 신경망 학습은 Input 데이터와 Output 데이터(라벨. label) 간의 가중치를 통계적으로 조정하는 것이다. 신경망 구조에서 노드 간 연결 링크는 가중치를 포함한다.

앞의 신경망 구조를 수식으로 표현하면 다음과 같다.
   v = W·x + b
  여기서, x = 입력벡터
            W = 가중치
            b = bias값

계산된 v값을 출력값 y로 계산하는 것은 활성화함수(activation functions)이 한다. 활성화함수는 시그모이달, softmax 같은 함수가 있다.
   y = φ(v)
  여기서, φ = 활성함수



활성화함수(wikibooks)

시그모이달 활성화함수(wikibooks)

정답 label과 출력값y의 차이는 에러e로 정의한다.
   e = d - y
   여기서, d = 정답(라벨)
             e = 오차

신경망의 가중치 W는 e가 줄어들도록 학습규칙(델타규칙)을 반복 수행해 조절한다.
     w = w + a·e·x         ... 간략식
   w = w + a·φ'(v)·x      ... 일반식    
   여기서, a = 학습률 (0 ~ 1)
                φ' = φ 함수의 도함수 δ

학습규칙
학습규칙은 다음과 같은 것이 사용된다.
  • Stochastic gradient descent(SGD. 경사하강법): 각 학습데이터 하나씩 가중치 갱신. 학습 성능이 무작위로 변하는 경향이 있음.

         w = a·δ·x

         w = w + w 

  • 배치 방식(batch): 모든 학습 데이터 오차에 관한 가중치 갱신을 계산한 후 이들 평균값으로 가중치를 갱신하는 기법. 무작위 변화는 줄어드나, 학습 시간이 오래 걸림.

         w = 1/n·∑w(k)

       여기서, k는 k번째 학습 데이터
  • 미니 배치 방식(mini batch): 전체 학습 데이터 중 일부 데이터만 골라 배치 방식으로 학습.

시그모이달 함술수를 사용할 때 δ는 다음과 같다.

        δ = φ(v) (1 - φ(v)) e 


SGD 알고리즘 예는 다음과 같다.
X = [0 0 1;
       0 1 1;
       1 0 1;
       1 1 1;
      ];
D = [0
       0
       1
       1
      ];
W = 2*rand(1, 3) - 1;

for epoch = 1:10000
  W = DeltaSGD(W, X, D);
end

N = 4;
for k = 1:N
  x = X(k, :)';
  v = W * x;
  y = Sigmoid(v)
end

function y = Sigmoid(x)
  y = 1 / (1 + exp(-));
end

function W = DeltaSGD(W, X, D)
  alpha = 0.9;
  N = 4;
  for k = 1:N
    x = X(k, :)';
    d = D(k);

    v = W * x;
    y = Sigmoid(v);

    e = d - y;
    delta = y. * (1-y). * e;                % SGD

    dW = alpha * delta * x';

    W(1) = W(1) + dW(1);
    W(2) = W(2) + dW(2);
    W(3) = W(3) + dW(3);
  end
end

역전파 알고리즘
역전파 알고리즘은 출력오차를 수식 왼쪽의 모든 은닉층 w를 조정해 간다. 다음은 matlab 코드 예이다.

function [W1, W2] = backprop(W1, W2, X, D)
  alpha = 0.9;
  N = 4;
  for k = 1:N
    x = X(k, :)';
    d = D(k);

    v1 = W1 * x;
    y1 = Sigmoid(v1);
    v = W2 * y1;
    y = Sigmoid(v);

    e = d - y;
    delta = y. * (1-y). * e;

    e1 = W2' * delta;
    delta1 = y1. * (1-y). * e1;
    dW1 = alpha * delta1 * x';
    W1 = W1 + dW1;

    dW2 = alpha * delta * y1';
    W2 = W2 + dW2;
  end
end

학습 규칙에 모멘텀(momentum)을 추가하면, 관성에 따라 일정 방향으로 가중치 갱신값이 커진다.

w = a·δ·x

m = w + ß·m^
w = w + m
m^ = m

다음은 모멘텀을 추가한 코드이다.
function [W1, W2] = BackpropMnt(W1, W2, X, D)
  alpha = 0.9;
  beta = 0.9;

  mmt1 = zeros(size(W1));
  mmt2 = zeros(size(W2));

  N = 4;
  for k = 1:N
    x = X(k, :)';
    d = D(k);

    v1 = W1 * x;
    y1 = Sigmoid(v1);
    v = W2 * y1;
    y = Sigmoid(v);

    e = d - y;
    delta = y. * (1-y). * e;

    e1 = W2' * delta;
    delta1 = y1. * (1-y). * e1;
    dW1 = alpha * delta1 * x';
    mnt1 = dW1 + beta * mnt1;
    W1 = W1 + mnt1;

    dW2 = alpha * delta * y1';
    mnt2 = dW2 + beta * mnt2;
    W2 = W2 + mnt2;
  end
end

비용함수
앞서 언급한 학습 규칙은 비용 함수에서 도출되었다. 신경망 오차가 크면, 비용 함수 값도 크다.
비용 함수(stats.stackexchange.com)

다음은 Sum of squared error 비용함수이다.

         J = 1/n·(d - y)^2


Cross entropy함수는 Sum of squared error 보다 더 민감하게 반응해, 학습 성능이 더 좋다.

         J = ∑{-d ln(y) - (1 - d)ln(1 - y)}


다음은 Cross entropy 비용함수 구현이다. 아래 경우, 활성함수가 시그모이드 함수일 경우, 델타와 출력 오차가 같다. 

function [W1, W2] = BackpropCE(W1, W2, X, D)
  alpha = 0.9;

  N = 4;
  for k = 1:N
    x = X(k, :)';
    d = D(k);

    v1 = W1 * x;
    y1 = Sigmoid(v1);
    v = W2 * y1;
    y = Sigmoid(v);

    e = d - y;
    delta = e;

    e1 = W2' * delta;
    delta1 = y1. * (1-y). * e1;
    dW1 = alpha * delta1 * x';
    W1 = W1 + dW1;

    dW2 = alpha * delta * y1';
    W2 = W2 + dW2;
  end
end

다범주 분류
다범주 분류를 위해서는, 출력 노드 벡터를 one-hot 인코딩(1-of-N 인코딩)하는 것이 좋다.
예) 범주1   범주2   범주3
       1         0         0
       0         1         0
       0         0         1

다범주 분류시에는 출력노드 활성함수로 소프트맥스(softmax) 함수를 사용하는 것이 일반적이다. 소프트맥스 함수는 자신 가중합 뿐 아니라, 다른 출력 노드들 가중합도 고려한다.

소프트맥스 함수는 각 출력 노드 값을 0 ~ 1로 제한할 뿐 아니라, 출력 노드 모든 합을 항상 1이 되게 한다. 시그모이드 함수의 경우, 자신 출력에만 관여하기 때문에 다음 출력도 가능하다.
예)   1
       1
       1

다음은 소프트맥스를 이용한 다범주분류의 예이다.

function [W1, W2] = MultiClass(W1, W2, X, D)
  alpha = 0.9;

  N = 5;
  for k = 1:N
    x = reshape(X(:, :, k), 25, 1);  % 5x5 픽셀 1,2,3,4,5숫자 이미지 입력
    d = D(k, :)';

    v1 = W1 * x;
    y1 = Sigmoid(v1);
    v = W2 * y1;
    y = Softmax(v);

    e = d - y;
    delta = e;

    e1 = W2' * delta;
    delta1 = y1. * (1-y). * e1;
    dW1 = alpha * delta1 * x';
    W1 = W1 + dW1;

    dW2 = alpha * delta * y1';
    W2 = W2 + dW2;
  end
end

function y = Softmax(x)
  ex = exp(x);
  y = ex / sum(ex);
end

심층 신경망
역전파 알고리즘 문제는 다음과 같다.
  • 그레디언트 소실(vanishing gradient): 앞쪽의 은직층까지 오차가 거의 전달되지 않는 현상
  • 과적합(overfit): 은닉층을 늘릴 때, 
  • 많은 계산량
그레디언트 소실 문제는 활성함수를 ReLU(Rectified Linear Unit)을 적용해 해결할 수 있다. 
    φ(v) = x, x > 0
              0, x <= 0
           = max(0, x)

ReLU는 신경망 노드 출력이 1을 넘어갈 수 있다. 이를 통해, 그레디언트 소실 문제를 해결한다.
    φ'(v) =1, x > 0
              0, x <= 0

과적합은 입력값과 너무 적합하게 학습된 상황을 의미한다. 
Under-fitting, generalized-fitting, over-fitting(The Shape of Data)

과적합 해결 책 중 하나는 드롭아웃(dropout) 기법이다. 드롭아웃은 신경망 전체를 학습하지 않고, 일부 노드만 무작위로 골라 학습한다. 보통, 드롭아웃 비율은 은닉층은 50%, 입력노드는 25% 수준이다. 

다음은 ReLU 함수이다. 
function y = ReLU(x)
  y = max(0, x)
end

다음은 드롭아웃 함수이다.
function ym = Dropout(y, ratio)
  [m, n] = size(y);
  ym = zeros(m, n);

  num = round(m * n * (1 - ratio));
  idx = randperm(m * n, num);
  ym(idx) = 1 / (1 - ratio);
end

컨벌루션 신경망
컨브넷는 학습 데이터의 특징을 추출하는 특징 추출기를 신경망 학습 과정에 포함시켜 일괄 처리한다. 특징 추출기 신경망의 가중치도 학습을 통해 결정된다.

컨브넷에 입력된 원본 이미지는 앞쪽의 특징 추출 신경망을 통과한다. 여기서 추출된 이미지 특징 맵(feature map)는 뒷 부분의 분류 신경망에 다시 입력된다. 분류 신경망은 이미지 특징을 기반으로 이미지 최종 범주를 분류한다.

   Image - Conv - ReLU - Pool - Deep Neural Network (ReLU - Softmax) -> label

컨벌루션 레이어는 컨벌루션 연산을 통해 입력 이미지를 변환한다. 디지털 필터(컨벌루션 필터) 역할을 한다.
풀링(pooling) 레이어는 주위 픽셀을 묶어 하나의 대표 픽셀을 만든다. 이미지 차원을 축소하는 역할이다. 풀링은 입력 이미지에 인식 대상이 한 쪽으로 치우쳐있거나 돌아가 있는 것을 보상해 준다.  

다음은 MNIST 이미지를 분류하는 CNN 코드이다. 

function [W1, W5, Wo] = MnistConv(W1, W5, Wo, X, D)
  alpha = 0.01;
  beta = 0.95;

  momentum1 = zeros(sizeof(W1);
  momentum2 = zeros(sizeof(W5);
  momentum3 = zeros(sizeof(Wo);

  N = length(D);

  bsize = 100;  % 미니배치 학습 개수는 100개.
  blist = 1:bsize:(N - bsize + 1);   % 미니배치 방식 학습.

  for batch = 1:length(blist)
    dW1 = zeros(sizeof(W1));
    dW5 = zeros(sizeof(W5));
    dWo = zeros(sizeof(Wo));

    begin = blist(batch);
    for k = begin:begin + bsize - 1
      x = X(:, :, k);           % input, 28 x 28
      y1 = Conv(x, W1);   % conv, 20 x 20 x 20. W1을 받아, 필터를 구성함. 필터 20개.
      y2 = ReLU(y1);
      y3 = Pool(y2);        % Pool, 10 x 10 x 20
      y4 = reshape(y3, [], 1)      % 2000
      v5 = W5 * y4;
      y5 = ReLU(v5);
      v = Wo * y5;
      y = Softmax(v);

      % one-hot encoding
      d = zeros(10, 1);
      d(sub2ind(size(d), D(k), 1)) = 1;

      % back propagation
      e = d - y;
      delta = e;

      e5 = Wo' * delta;    % hidden(ReLU) layer
      delta5 = (y5 > 0) .* e5;

      e4 = W5' * delta5;
      e5 = reshape(e4, size(y3));

      e2 = zeros(size(y2));
      W3 = ones(size(y2)) / (2*2);
      for c = 1:20
         e2(:, :, c) = kron(e3(:, :, c), ones([2 2])) .* W3(:, :, c);
      end

      delta2 = (y2 > 0) .* e2;   % ReLU layer

      delta1_x = zeros(size(W1));    % Conv layer
      for c = 1:20
         delta1_x(:, :, c) = conv2(:, :), rot90(delta2(:, :, c), 2), 'valid');
      end

      dW1 = dW1 + delta1_x;
      dW5 = dW5 + delta5 * y4';
      dWo = dWo + delta * y5';
    end

    % update weights
    dW1 = dW1 / bsize;
    dW5 = dW5 / bsize;
    dWo = dWo / bsize;

    momentum1 = alpha * dW1 + beta * momentum1;
    W1 = W1 + momentum1;
    momentum5 = alpha * dW5 + beta * momentum5;
    W5 = W5 + momentum5;
    momentumo = alpha * dWo + beta * momentumo;
    Wo = Wo + momentumo;
  end
end

RNN과 LSTM
이 모델은 순서가 있는 시계열 데이터의 일부를 학습데이터와 라벨링데이터로 활용해 시계열 데이터 자체에 포함된 패턴을 학습한다. 이를 통해, 소설쓰기, 작곡 작사, 주가 예측 등이 가능하다. 
LSTM 모델

LSTM 단위

U-Net과 인코딩-디코딩
U-Net은 인코딩과 디코딩(encoding - decoding)이 반대로 붙어 있는 모양으로 정의된 딥러닝 모델이다. ResNet과 같이 skip connection을 지원하므로, 입력 데이터에서 특징을 추출하며 일반화될 때 발생하는 데이터 크기가 작아지는 문제를 해결한다. 그러므로, 데이터 세그먼테이션에 주로 많이 사용된다.
UNet 모델 



트랜스포머와 어텐션
트랜스포머(transformer)와 어텐션(attention)는 데이터에서 위치를 인코딩해, 공간 데이터 특징을 캡쳐할 수 있도록 인코딩을 설계하고, 데이터 간의 관계에 대한 특징을 학습함으로써, 이와 관련된 모든 딥러닝 모델에 적용될 수 있도록 개발되었다. 다국어 번억, 챗봇, 문서 텍스트 마이닝 및 특징 분류, 이미지 세그먼테이션 등 다양한 곳에 사용된다.  

GCN과 GDL
GCN(Graph Convolutional Networks. GNN)과 GDL (Geometric Deep Learning)은 다음 그림과 같이, 재료를 구성하는 화학 분자 분석, 탐지 및 설계, 영상 컨텍스트 해석 및 생성, 다차원 포인트 클라우드 세그먼테이션 등 다양한 영역에서 사용된다. 자세한 내용은 여기를 참고한다.
마무리

최근 나오고 있는 신경망들은 대부분 앞의 개념에 기반한다. 신경망은 학습모델을 만드는 통계적 기법이다. 앞서 언급된 모델들은 Keras, PyTorch로 구현되어, YOLO, OpenAI, Bert 와 같은 이름으로 공개되고 있다. 딥러닝은 좀 더 범용적인 문제를 해결할 수 있도록 발전될 것이다.

레퍼런스
1. 병렬처리 – First Contact with TensorFlow
2. Deep Learning을 위해 어떤 GPU를 써야 할까?
3. 김성필, 딥러닝 첫걸음
4. wikibooks, Artificial Neural Networks/Print Version
5. Google, 텐서플로우 메뉴얼
6. YOLO: real-time object detection (paper)
7. ConvNetJS
8. carpedm20.github.io/faces

2017년 2월 5일 일요일

스텐 와이어줄(로프), 피팅, 로프 매듭 방법

천장에 매달거나, 벽걸이, 액자걸이 작품 등을 만들다보면, 스텐 와이어 로프를 사용할 필요성이 생긴다. 스텐 와이어 로프는 무거운 물체도 매달수 있을 만큼 튼튼하다. 이 글에서는 스텐 와이어를 사용방법과 피팅(fitting)을 간략히 설명한다.

1.  스텐 와이어 로프
스텐 와이어 로프는 스텐와이어줄이라고도 불리며,  스테인리스 강선의 일종이다. 강선은 선 지름과 재료에 따라 표준화가 되어 있다. 1mm두께 100미터 스텐 와이어 가격은 대략 20,000 에서 30,000 사이이다.



스텐 와이어는 일반 가위나 벤치로는 잘 안짤라진다. 보통, 다음과 같은 클림프 집게(압착기, 캇타)(Crimping)를 사용해 절단하고, 피팅하는 것이 일반적이다.

2. 액자 레일(rail)
액자 레일은 작품을 균일한 위치로 잘 매달수 있는 프레임 역할을 한다. 와이어 고리(걸이)와 함께 사용된다. 


3. 와이어 케이블 피팅(cable fitting)
와이어 케이블 피팅은 와이어 엔드(끝)이나 중간에 무언가를 매달때, 혹은 와이어를 매듭짓거나, 와이어 끝을 마무리할 때 사용하는 악세사리를 말한다.


4. 와이어 고리 및 레일걸이
와이어 고리, 레일걸이는 와이어를 절단한 후, 와이어 끝에 작품, 액자 등을 걸때 사용한다. 다음 그림과 같이 매우 다양한 고리 종류가 있다.


레일걸이와 와이어 고리

참고로, 그림 왼쪽과 같은 유형은 스틸 와이어를 꼽아 넣으면, 내부 클립이 단단하게 줄을 잡아 준다.
레일 걸이 응용 예

5. 구리 캡(copper cap) 및 구리 슬리브(copper sleeve)
와이어 엔드를 매듭지어 주거나, 와이어 끝을 마무리해야 할 때 캡이나 슬리브를 사용한다.

구리 캡

구리 슬리브 사용방법


이외에 다음 영상과 같이 와이어를 피팅하는 매우 다양한 방법이 있다.


6. 로프 매듭
천장에 매다는 작품을 준비 하다보니, 로프 매는 방법까지 공부해야 한다. ㅎ
아래는 로프 매는 방법에 대한 동영상과 사이트이다.



기타. 로프 매듭법

2017년 1월 20일 금요일

목재 스프레이 / 페인팅 하기

이 글에서는 아트, 건축, 파빌리온, 오브제 전시, 가구, 목공  등 에서 많이 사용되는 목재의 표면을 페인팅하는 방법을 간단히 요약한다. 페인트 작업은 손이 많이 가는 작업이다. 그리고, 첫 작업 결과가 다음 작업의 결과에 큰 영향을 준다. 처음 작업할 때 계획을 잘 세우고 진행하는 것이 좋다.

1. 개요
여러가지 이유로 페인트나 스프레이를 사용해야할 때가 있다. 이 경우, 가공의 편의상 목재를 재료로 많이 사용한다. 목공에 많이 사용하는 목재 중 하나인 MDF는 톱밥 등을 접착, 압축해 만든 재료이다. MDF는 가공이 쉽고 저렴해서 많은 곳에 사용된다. 800 X 1500 mm 크기 MDF 한장이 대략 10,000 ~ 15,000원 정도이다.

MDF 가공하기

MDF같은 목재에 직접 페인팅이나 스프레이를 뿌려보면, 재료가 페인트 수분을 빨아들여 실제 원하는 색이 안나오는 것을 알 수 있다. 보통, 이런 문제를 해결하기 위해, 재료에 젯소(gesso)란 도료로 칠한 후, 수성 도료로 페인팅한다. 만약, 표면이 거칠다면, 목재용 퍼티(putty)를 칠한 후, 도료를 페인팅한다.
만약, 목재 결 자체를 표현하려면 바니쉬(varnish)로 로 페인트한다.

목재의 페인트 수분 흡수로 인한 문제 
2. 순서
페인팅이나 스프레이 칠하는 순서는 다음과 같은 과정을 거쳐야 한다.

1. 평평한 곳에 페인트 칠할 재료 놓기
   평평한 곳에 재료를 놓지 않고 페인트를 하면, 페인트 흘러내린 자국들이 생긴다.
2. 재료 표면 처리
   재료 표면이 거칠거나 먼지가 묻어 있다면, 페인트 칠한 표면이 매끄럽지 않다.
   사포질 및 먼지 제거한다.
   더 심한 경우, 퍼티(putty)로 칠해 표면을 매끄럽게 만든다(이 경우 5~6시간 말린다).
   참고로, 퍼티는 베란다 울퉁불퉁 표면 매우는 데도 많이 사용되며, 가격도 매우 저렴하다.
3. 표면에 젯소(gesso) 칠하기
   붓의 끝에서 중간 정도까지만 젯소를 적당히 묻힌 후, 재료에 골고루 칠한다.
   재료에 칠한 부분은 서로 적당히 겹치도록 해, 빈 곳이 없도록 한다.
4. 1~2시간 건조하기
5. 다시 사포질해서 거친 부분 다듬기
6. 이제 페인팅이나 스프레이 뿌리기
7. 1~2시간 건조하기
8. 수성 바니쉬(varnish)로 표면 코팅하기
   이 단계는 생략할 수 있다. 다만, 처음부터 페인트하지 않고, 목재결을 살릴려면 표면 처리 후 바니취를 칠한다.

다음은 이와 관련된 튜토리얼 영상이다.

젯소(Gesso) 사용 방법

바니쉬(varnish) 사용 방법

참고로, 젯소는 보통 1L에 만원 정도 한다. 수성바니쉬는 1L에 만원 정도이다. 다음 영상은 스프레이하는 방법에 대한 것이다. 스프레이는 이전 스프레이한 구간과 15% 정도 오버랩되도록 분사한다. 참고로, 락커 스프레이는 하나에 천오백원정도이다.

스프레이 사용법

만약, 스프레이가 원하지 않는 곳에 칠해졌다면, 락카 신너를 사용해, 락커 스프레이를 지울 수 있다.

3. 기타 사항
페인트 작업 시 페인트가 주변에 튀기도 하므로, 주변을 잘 정리하고 작업하는 것이 좋다. 집에서 페인트할 때는 신문지 등을 깔아 놓고 작업한다. 페인트나 스프레이 작업을 할 때 더러워져도 되는 옷을 입고 작업하는 것이 좋다.

페인트할 때는 공간이 클 수록 좋다. 초벌만으로 칠해진 페인트는 농도가 낮고, 불균일 한 경우가 많다. 잘 말린 후 두세번 걸쳐 칠하는 것이 좋다. 그래서, 재료에 칠해진 페인트가 잘 말려지도록 바닥에 널어 놓고 작업하는 것이 좋다. 작업 공간이 부족하면, 선반 등에 페인트 된 재료를 널어 놓고 말리는 것이 좋다.
베란다에서 페인트 칠하기(그리 권장하고 싶지는 않다ㅎ 간이 커야 함)

냄새가 그리 몸에 좋지는 않으므로, 환기가 잘 되는 곳에서, 마스크, 장갑 등 보호 장구를 착용하고 작업하는 것이 좋다.

페인트 작업이 끝나면, 다음 작업을 위해, 사용했던 붓, 트레이 등을 물로 깨끗이하고, 주변을 잘 청소, 정리한다.

참고 - 애나멜과 같은 유성 페인트 작업시에는 신나를 20% 추가해서 작업성을 좋게 만든 후 페인트한다. 다만, 유성은 표면에 기름 막이 형성되므로 재료 외부와 내부의 미세한 통로가 막힌다. 이로 인해 재료 내부에 습기가 생기면 막이 떠서 예쁘게 처리되지 않으므로, 금속과 같은 재료에 사용하는 것이 좋다. 유성 페인트 냄새는 휘발되기 위해서 몇 일은 걸리므로 사모님 잔소리가 무섭다면 집에서 작업하진 말자.

참고 - 일반 스프레이 색칠은 표면이 고르게 분사되기에는 어려움이 있다. 이 경우, 에어건으로 스프레이하는 것이 좋다.

라이노 메쉬에서 솔리드 NURBS 곡면 변환 방법

3D 스튜디오(3DS), 3차원 포인트 클라우드 스캔 장치, Tinker CAD(팅커캐드)와 같은 도구에서 생성된 메쉬 모델 파일(OBJ, STL 등)을 라이노(rhino)에서 편집하려면 솔리드 NURBS 모델로 변환해야 하는 일이 생긴다.

이럴 경우, 몇몇 상용 애드인을 통해 해결할 수 있지만, 다음과 같은 라이노 기본 명령을 통해서도, 모델 변환을 할 수 있다.

메쉬 모델을 라이노로 임포트(import)한 후, 명령 실행 순서는 다음과 같다. 

1. Mesh > Mesh Repair > Fill Holes
2. Mesh > Mesh Repair > Unify Normals
3. Mesh > Mesh Boolean > Union
4. MeshtoNURBS

이제, 제대로 변환되었는 지 변환된 모델을 'What'명령어로 확인해 본다. 
아래는 이와 관련된 튜토리얼 동영상이다. 


레퍼런스

2017년 1월 17일 화요일

Spout과 프로젝션 맵핑

이 글에서는 간단히 Spout과 프로젝션 맵핑에 대한 이야기를 해 보겠습니다.

Spout은 윈도우즈 운영체계에서 OpenGL과 같은 3차원 렌더링 엔진을 통해 렌더링되는 그래픽을 다른 어플리케이션들과 공유하기 위해서 개발되었습니다. 그래서, 3차원 렌더링 엔진을 사용하는 어플리케이션의 화면을 가로채서, 자신이 개발한 프로그램 안에 보여줄 수 있지요. 참고로, 맥킨토시 운영체계에서는 Syphon을 사용합니다.

프로젝션 맵핑을 하다 보면, Processing 등에서 개발된 그래픽을 VPT와 같은 프로젝션 맵핑 도구에 렌더링하고 싶을 때가 있는 데, 이때 Spout 라이브러리를 사용하면 됩니다.


이와 관련해, 튜토리얼 및 관련 자료를 아래에 링크합니다. 따라하다 보면 Processing과 같은 그래픽 저작 도구에서 프로젝션 맵핑 툴로 그래픽 컨텐츠 소스를 오버레이할 수 있습니다.

VPT, Mad mapper 등을 이용한 프로젝션 맵핑 방법은 아래 튜토리얼에 잘 나와 있으니 참고하시길 바랍니다.

프로젝션 맵핑 튜토리얼




2017년 1월 12일 목요일

아마존 에코(Amazon Echo) 알렉사(Alexa) 기반 라즈베리파이 제어

이 글은 아마존 에코(Amazon Echo) 알렉사(Alexa) 기반 라즈베리파이 제어에 관한 이야기입니다. 최근 CES 2017에서도 알렉사가 인공지능 비서로써 스마트 홈, IoT, 무인 자동차 등 다양한 어플리케이션에 사용되었습니다. 오픈 소스를 기반으로 한 이런 어플리케이션은 앞으로도 더욱 많아 질 것이라 생각합니다.

이 글은 다음 레퍼런스를 참고하였습니다.


2017년 1월 1일 일요일

Javascript 기반 로봇 제어 플랫폼

Javascript는 인터넷 기반으로 동작되므로, 네트워크 상에서 센서와 액추에이터 제어와 관련된 메시지 교환이 많은 로봇 제어에 유리할 수 있다. Javascript는 사용이 쉽고 Node.js와 같은 훌륭한 라이브러리를 많이 지원하고 있다. 이런 이유로 Javascript기반 로봇제어 방식이 NodeBots와 같은 커뮤니티를 통해 점차 확산되고 있다. 이 글에서는 손쉽게 로봇을 컨트롤할 수 있는 Javascript 기반 오픈소스 플랫폼을 소개한다.

1. Johnny-Five 
Johnny-Five는 Javascipt 기반 로봇 및 IoT 플랫폼으로 Bocoup 그룹에서 2012년에 릴리즈된 오픈소스이다. 75명이상의 개발자가 이 프로젝트에 참여하고 있으며, 계속적인 기능 개선 및 확장이 이루어지고 있다.


참고로 Johnny-Five란 이름은 로봇 영화로 유명한 조니 5에서 따온것이다.

80년대 어린이의 우상 Johnny-Five 한장면ㅎ

로봇의 센서와 액추에이터를 추상화한 사용하기 쉬운 API를 제공한다. 다음은 Johnny-Five를 어떻게 사용하는 지 간단히 보여준다.


API는 대부분의 센서와 액추에이터를 지원하며, 예제와 사용법 설명이 매우 쉽게 잘 되어 있다. 아두이노, 라즈베리파이 등 수많은 오픈소스 보드를 지원한다.

다음은 Johnny-Five를 이용해 만든 워킹로봇이다.


2. Cylon.js
오픈 소스 드론, 로봇 등 다양한 플랫폼을 지원하는 Javascript기반 로봇 프레임웍이다.


Johnny-Five와 마찬가지로, 수많은 센서와 액추에이터를 추상화해, 사용법이 매우 간단하다. 다음은 간단한 blink 예제이다.

var Cylon = require("cylon");

// Initialize the robot
Cylon.robot({
  // Change the port to the correct port for your Arduino.
  connections: {
    arduino: { adaptor: 'firmata', port: '/dev/ttyACM0' }
  },

  devices: {
    led: { driver: 'led', pin: 13 }
  },

  work: function(my) {
    every((1).second(), function() {
      my.led.toggle();
    });
  }
}).start();

다음은 지원하는 플랫폼 일부이다.


API는 REST, socket.io, mqtt 프로토콜을 지원하고 있다. Cylon.js를 설치하고, 실행하면, 다음과 같이 로봇 플랫폼을 연결하고, 제어할 수 있는 데쉬보드를 지원한다.


다음은 Cylon.js 를 사용해 BB-8와 드론을 제어한 사례이다.


3. ROSnodejs
이름과 같이 ROSnodejs는 로봇 제어 오픈소스 미들웨어로 유명한 ROS(robot operating system)의 Javascript버전으로 ROS와 연결되어 사용되는 로봇 제어 클라이언트 라이브러리이다.

사실 ROS를 직접 사용해도 되지만, 설정 등 작업해야 할 것들이 많다. 이를 Javascript로 추상화하였다.

다음은 echo rostopic 메시지를 다른 로봇 ROS 노드에 전달하는 예제이다.

ros.types([ 'std_msgs/String' ], function(String) { var node = ros.node('talker'); node.topics([ { topic: 'publish_example', messageType: String } ], function(publishExample) { // Uses the ROS command line tool rostopic to echo messages published // over the 'publish_example' topic. var subscribeCommand = 'rostopic' + ' echo' + ' /publish_example'; var child = exec(subscribeCommand, function(error, stdout, stderr) { should.not.exist(error); }); var message = new String({ data: 'howdy' }); publishExample.publish(message); setTimeout(done, 1500); }); });

다음은 자바스크립트로 로봇 플랫폼인 PR2를 제어하는 예이다.