2018년 7월 26일 목요일

Deep learsing note, links

배운것 기억나는 선에서 대충 간략히 정리함.
틀릴 수 있음. cross check 필요

http://charlie0301.blogspot.com/2018/07/ai-machine-learning-links.html


Deep learning
: https://en.wikipedia.org/wiki/Deep_learning

Deep learning (also known as deep structured learning or hierarchical learning) is part of a broader family of machine learning methods based on learning data representations, as opposed to task-specific algorithms. Learning can be supervised, semi-supervised or unsupervised.



Single-Layer Perceptron (단층 퍼셉트론)
 : https://en.wikipedia.org/wiki/Perceptron



 : 뉴런을 따라 만든 알고리즘 하나의 단위, 여러 input에 대해 output을 출력
 : 계산은 연결된 이전 퍼셉트론과의 Linear Combination + Activation function
 : Linear Combination - 이전 Layer의 연결된 뉴런들의 출력값 * 연결 weight
 : Activation - 이전 뉴런 들과의 Linear Combination 값을 non-linear function을 통해 Activation
  - Activation function들 : Sigmoid, Hyperbolic Tangent (tanh), Rectified Linear Unit (ReLU)
    https://en.wikipedia.org/wiki/Activation_function

Logistic (a.k.a. Sigmoid or Soft step)Activation logistic.svg[1]
TanH                                        Activation tanh.svg
Rectified linear unit (ReLU)               Activation rectified linear.svg


Multi-Layer Perceptron (다층 퍼셉트론)
 : https://en.wikipedia.org/wiki/Multilayer_perceptron
 : 복수의 Perceptron을 연결한 구조
 : Non-linear Activation function + Multi-Layer


Artificial Neural Network (인공 신경망)
 : https://en.wikipedia.org/wiki/Artificial_neural_network



 : 다수의 Neuron이 Layer로 연결되어 복잡한 문제를 해결
 : Input Layer > Hidden Layer > Output Layer 로 구성
  - Input Layer : 초기값을 받는 가장 첫번째 Layer
  - Hidden Layer : 중간 단계의 모든 Layer
  - Output Layer : 마지막 Layer로 출력값 계산
    . 결과값을 그대로 받아 Regression
    . Sigmoid를 거쳐 Binary Classification
    . Softmax를 거쳐 K-Class Classification
 : Forward Propagation
 : Back Propagation Algorithm
  

Neural Network Learning Process 
1) Initialization
 : 학습하고자 하는 Parameter(θ) 초기값 선정
 : Xavier Initialization (for Sigmoid, tanh), He Initialization (for ReLU)

2) Cost Function
 : 함수 정의 (Cost Function을 최소화 하도록 학습 진행)
 : 용도에 따라 Least Square Error 또는 Cross-Entropy를 사용함.
 : Parameter의 많아질 수록 overfitting 현상이 심화 되어 Cost Function + Regularization Term 추가
  > https://en.wikipedia.org/wiki/Regularization_(mathematics)

 : Overfitting을 방지하기 위한 방법으로 Dropout 방법도 있음.
  > https://en.wikipedia.org/wiki/Convolutional_neural_network#Dropout

3) Optimizer
 : Cost Function을 최소화하는 방향으로 Parameter(θ)를 변경하는 학습 방식을 적용
 : 일반적으로 Gradient Descent를 이용한 방식 사용
 : Batch normalization, Optimizer (Adam)





2018년 7월 25일 수요일

머신러닝 관련 note, links

배운것 기억나는 선에서 대충 간단하게 정리함.
틀릴 수 있음. cross check 필요

http://charlie0301.blogspot.com/2018/07/ai-machine-learning-links.html



Machine learning
: https://en.wikipedia.org/wiki/Machine_learning

Machine learning is a subset of artificial intelligence in the field of computer science that often uses statistical techniques to give computers the ability to "learn" (i.e., progressively improve performance on a specific task) with data, without being explicitly programmed.


머신러닝 분류




Supervised Learning (지도 학습)
 : Input에 대한 Output을 예측하기 위해 학습, 정답이 존재

Unsupervised Learning (비지도 학습)
 : Input 데이터에서 패턴을 발견하는 것, 정답이 없음

Reinforcement Learning (강화 학습)
 : Trial & Error를 통한 학습

자세한 내용은 아래 링크 참조

머신 러닝(Machine Learning) 알고리즘 분류 – 지도 학습(Supervised Learning), 비지도 학습(Unsupervised Learning), 강화 학습(Reinforcement Learning) by Solaris



Output에 따른 분류

- Regression
 : 결과가 연속값(Continuous value)으로 주어짐, 모델이 그리는 선을 기반하여 결과값을 예측

- Logistic Regression, Binary Classification
 : 결과가 양자 택일 값(Binary value)임

- Clustering 
 : 결과가 여러개의 불연속값(Multiple discrete value)임



Machine Learning algorithms/methods 간략 설명



- Linear Regression (선형 회귀)



 : y와 한개 이상의 x와의 상관관계를 모델링
 : Cost Function (비용 함수), Linear Regression의 경우 Mean square error function(평균 제곱 오차 함수)을 활용
  => Gradient Descent Algorithm(경사하강법, 미분으로 경사를 확인하여 음의 방향으로 이동하여 다시 계산)을 사용해서 Cost가 최소가 되는 지점을 찾음. 이때 적절한 이동을 위해 Learning Rate(학습률)이 중요함.


- Logistic Regression (로지스틱 회귀)


 : 이진 분류(binary classification) 문제를 해결하기 위한 모델
 : Sigmoid Function을 이용하여 특정 데이터가 positive/negative class에 속할 확률을 계산
 : Cross-entropy를 비용함수로 설정하고 Gradient-based optimizer를 통해 학습을 진행함.


- Softmax Algorithm (소프트맥스 알고리즘)

 : 다중 클래스 분류 문제(Multi-class)를 위한 알고리즘
 : Logistic Regression을 변형/발전시킨 방법으로 binary class에서 multiple class 문제로 일반화

- Support Vector Machine (SVM, 서포트 벡터 머신)


 : 패턴 인식을 위한 지도 학습 모델, 주로 분류를 위해 사용
 : Soft-Margin SVM => margin을 최대화 하는 분류 경계면을 찾는 기법
  => Plus & Minus plain에 여유 변수를 두어 Robustness를 향상
 : Kernel Support Vector Machines => margin을 최대화 하는 분류 경계면을 찾는 기법
  => 데이터가 선형적으로 분리되지 않ㅇ르 경우 고차원 공간으로 변환하여 해결


등등등...

2018년 7월 24일 화요일

AI 관련 note, links

배운것 기억나는 선에서 대충 간략히 정리함.
틀릴 수 있음. cross check 필요


Artificial intelligence

Artificial intelligence (AI), sometimes called machine intelligence, is intelligence demonstrated by machines, in contrast to the natural intelligence displayed by humans and other animals. In computer science AI research is defined as the study of "intelligent agents": any device that perceives its environment and takes actions that maximize its chance of successfully achieving its goals.


Machine learning

Machine learning is a subset of artificial intelligence in the field of computer science that often uses statistical techniques to give computers the ability to "learn" (i.e., progressively improve performance on a specific task) with data, without being explicitly programmed.


Deep learning

Deep learning (also known as deep structured learning or hierarchical learning) is part of a broader family of machine learning methods based on learning data representations, as opposed to task-specific algorithms. Learning can be supervisedsemi-supervised or unsupervised.


뭔소린지 모르겠음.
아래 NVIDIA 글이 설명이 잘 되어 있음.

인공 지능과 머신 러닝, 딥 러닝의 차이점을 알아보자, NVIDIA KOREA

What’s the Difference Between Artificial Intelligence, Machine Learning, and Deep Learning?, MICHAEL COPELAND

위 기사에서 발췌
인간의 감각, 사고력을 지닌 채 인간처럼 생각하는 인공 지능을 ‘일반 AI(General AI)’라고 하지만, 현재의 기술 발전 수준에서 만들 수 있는 인공지능은 ‘좁은 AI(Narrow AI)’의 개념에 포함됩니다. 좁은 AI는 소셜 미디어의 이미지 분류 서비스나 얼굴 인식 기능 등과 같이 특정 작업을 인간 이상의 능력으로 해낼 수 있는 것이 특징이죠.

머신 러닝은 기본적으로 알고리즘을 이용해 데이터를 분석하고, 분석을 통해 학습하며, 학습한 내용을 기반으로 판단이나 예측을 합니다.

딥 러닝은 인공신경망에서 발전한 형태의 인공 지능으로, 뇌의 뉴런과 유사한 정보 입출력 계층을 활용해 데이터를 학습합니다. 


- 머신러닝과 딥러닝의 주요 차이점 중 하나는 머신러닝을 위해서는 Feature 제공하여 학습을 하는데 반해 딥러닝은 모델 내부에 Feature extractor가 존재함.


참고 사이트
- 모두를 위한 머신러닝/딥러닝 강의

- 머신러닝 단기집중과정

- Machine Learning 강의노트
 : https://wikidocs.net/book/587

밑바닥부터 시작하는 딥러닝
 : https://github.com/WegraLee/deep-learning-from-scratch
- [개앞맵시] 스카이넷도 딥러닝부터





2018년 7월 23일 월요일

[Links] Pandas links, 복습...

이미 정리된 사이트들이 많아 그냥 찾아서 링크함.

10 Minutes to pandas
: https://pandas.pydata.org/pandas-docs/stable/10min.html

Python - Pandas 튜토리얼 1(데이터프레임 생성, 접근, 삭제, 수정), Deep Play
: http://3months.tistory.com/292

PANDAS(판다스) 기초 정리
http://doorbw.tistory.com/172


복습으로 서울시 인구 수를 Pandas를 가지고 확인해봄.
제대로 했는지 모르겠음.
: https://colab.research.google.com/github/hallower/pandas_study/blob/master/seoul_people_count/Age.ipynb

2018년 6월 20일 수요일

[Link] Python 개인 정리

Python 공부하면서 개인적으로 몰랐던 부분을 정리..


점프 투 파이썬
 : https://wikidocs.net/book/1

사이트를 참고하였음.



** 제곱연산자
: https://wikidocs.net/12#x-y


문자열 formatting
https://wikidocs.net/13#format

>>> "I eat {0} apples".format(3) 'I eat 3 apples'

>>> number = 10 >>> day = "three" >>> "I ate {0} apples. so I was sick for {1} days.".format(number, day) 'I ate 10 apples. so I was sick for three days.'


Container
- list [,]
 : https://wikidocs.net/14#_7
 : append, pop/delete/remove
- dict {:}
 : https://wikidocs.net/16#_6
 : [], get, del
 : keys, values
- tuple (,)
- set {,}


list slicing
https://wikidocs.net/14#_4

>>> a = [1, 2, 3, 4, 5] >>> a[0:2] [1, 2]


if
https://wikidocs.net/20#if_1

if 조건문: 수행할 문장1 수행할 문장2 ... else: 수행할 문장A 수행할 문장B ...


for
https://wikidocs.net/22#for

for 변수 in 리스트(또는 튜플, 문자열): 수행할 문장1 수행할 문장2 ...


function
https://wikidocs.net/24#_6

def 함수이름(매개변수): <수행할 문장> ... return 결과값

* ':' 다음 줄의 들여쓰기가 중요.


with
https://wikidocs.net/26#with

f = open("foo.txt", 'w') f.write("Life is too short, you need python") f.close()
를 아래와 같이 handle scope내에서 파일 처리 가능
with open("foo.txt", "w") as f: f.write("Life is too short, you need python")


class method의 첫번째 매개변수
https://wikidocs.net/28#_6




dir 내장 함수
https://wikidocs.net/32#dir


2018년 5월 21일 월요일

C++ 11/14 관련 내용 대충 정리, weak_ptr

최신 C++을 공부하려 책을 보긴 했었는데
내용이 기존 문법과 함께 여기저기 흩어져 있어 보기에 좀 어려워
MSDN을 참고하여 대충 정리하려함.


C++11/14/17 기능에 대한 지원(최신 C++)
https://msdn.microsoft.com/ko-kr/library/hh567368.aspx


weak_ptr

https://msdn.microsoft.com/ko-kr/library/hh279672.aspx


- 참조수를 늘리지 않고 개체에 엑세스 하고자 할 경우 사용
 : shared_ptr instance 사이에서 순환 참조가 발생할 경우 shared_ptr가 삭제되지 않는 경우 발생
- weak_ptr 자체는 참조 수 계산에 참가하지 않으므로 shared_ptr가 유지되는 경우에서만 사용 가능함
 : 개체가 삭제된 경우 bad_weak_ptr 예외가 발생된다.


예제 :

https://msdn.microsoft.com/ko-kr/library/hh279672.aspx#Anchor_0

번역으로 본문의 결과가 좀 이상한데 실제 실행해 보면 다음과 같다.

Creating Controller0
Creating Controller1
Creating Controller2
Creating Controller3
Creating Controller4
push_back to v[0]: 1
push_back to v[0]: 2
push_back to v[0]: 3
push_back to v[0]: 4
push_back to v[1]: 0
push_back to v[1]: 2
push_back to v[1]: 3
push_back to v[1]: 4
push_back to v[2]: 0
push_back to v[2]: 1
push_back to v[2]: 3
push_back to v[2]: 4
push_back to v[3]: 0
push_back to v[3]: 1
push_back to v[3]: 2
push_back to v[3]: 4
push_back to v[4]: 0
push_back to v[4]: 1
push_back to v[4]: 2
push_back to v[4]: 3
use_count = 1
Status of 1 = On
Status of 2 = On
Status of 3 = On
Status of 4 = On
use_count = 1
Status of 0 = On
Status of 2 = On
Status of 3 = On
Status of 4 = On
use_count = 1
Status of 0 = On
Status of 1 = On
Status of 3 = On
Status of 4 = On
use_count = 1
Status of 0 = On
Status of 1 = On
Status of 2 = On
Status of 4 = On
use_count = 1
Status of 0 = On
Status of 1 = On
Status of 2 = On
Status of 3 = On
Destroying Controller0
Destroying Controller1
Destroying Controller2
Destroying Controller3
Destroying Controller4

Controller class는 내부에 others weak_ptr를 가지고 있고
RunTest()에서 다른 shared_ptr들을 others에 삽입하여 참조하도록 하였음.

Controller class 내부의 others를 shared_ptr로 바꾸면
각각의 use_count는 5가 되고 순환 참조로 인해 Controller들이 삭제 되지 않는다.



Modern Effective C++에서 관련된 chapter는 다음과 같고
더 자세한 내용을 원한다면 책을 꼭 읽는 것을 추천.
단 Modern Effective C++이 처음이라면 Effective C++을 먼저 읽는 것을 추천.

Effective Modern C++: 42 Specific Ways to Improve Your Use of C++11 and C++14
http://a.co/0MIIC9k

Item 20: Use std::weak_ptr for std::shared_ptr- like pointers that can dangle.


- std::shared_ptr와 거의 유사하지만 참조 횟수에 영향을 미치지 않고
  지칭하는 객체를 잃은 상황을 확인할 수 있음.

std::shared_ptr<Widget> spw1 = wpw.lock();
auto spw2 = wpw.lock();
std::shared_ptr<Widget> spw3(wpw);

wpw이 expired 되었다면 spw1, spw2는 null이고
spw3를 만들때는 std::bad_weak_ptr exception 발생

아래는 책에서 말하는 loadWidget caching code임

std::shared_ptr<const Widget> fastLoadWidget(WidgetID id)
{
   static std::unordered_map<WidgetID, std::weak_ptr<const Widget>> cache;
   auto objPtr = cache[id].lock();
      if (!objPtr) {
         objPtr = loadWidget(id);
         cache[id] = objPtr;
      }
   return objPtr;
}

cache에 있는 widget이 만료되지 않았다면 (lock() != nullptr) cache된 widget을 제공.

- shared_ptr 개체를 참조할 때 순환 참조를 피하고자 사용하지만 이는 일반적인 상황은 아님,,,

C++ 11/14 관련 내용 대충 정리, shared_ptr

최신 C++을 공부하려 책을 보긴 했었는데
내용이 기존 문법과 함께 여기저기 흩어져 있어 보기에 좀 어려워
MSDN을 참고하여 대충 정리하려함.

C++11/14/17 기능에 대한 지원(최신 C++)
https://msdn.microsoft.com/ko-kr/library/hh567368.aspx


shared_ptr

https://msdn.microsoft.com/ko-kr/library/hh279669.aspx


- 여러곳에서 참조하는 개체의 수명을 관리하기 위한 C++ STL 스마트 포인터
- shared_ptr 를 초기화 한 후에 복사, 함수 인수를 값으로 전달 및 다른 shared_ptr 인스턴스로 할당 가능
- 참조 횟수가 0에 도달하면 참조개체와 내부 제어 블록을 삭제





    // Use make_shared function when possible.
    auto sp1 = make_shared<Song>(L"The Beatles", L"Im Happy Just to Dance With You");

    // Ok, but slightly less efficient. 
    // Note: Using new expression as constructor argument
    // creates no named variable for other code to access.
    shared_ptr<Song> sp2(new Song(L"Lady Gaga", L"Just Dance"));

    // When initialization must be separate from declaration, e.g. class members, 
    // initialize with nullptr to make your programming intent explicit.
    shared_ptr<Song> sp5(nullptr);
    //Equivalent to: shared_ptr<Song> sp5;
    //...
    sp5 = make_shared<Song>(L"Elton John", L"I'm Still Standing");

- 되도록이면 예외 발생 상황에서 문제 없는 make_shared를 사용하여 만들어라.

    vector<shared_ptr<MediaAsset>> assets;

    assets.push_back(shared_ptr<Song>(new Song(L"Himesh Reshammiya", L"Tera Surroor")));
    assets.push_back(shared_ptr<Song>(new Song(L"Penaz Masani", L"Tu Dil De De")));
    assets.push_back(shared_ptr<Photo>(new Photo(L"2011-04-06", L"Redmond, WA", L"Soccer field at Microsoft.")));

    vector<shared_ptr<MediaAsset>> photos;

    copy_if(assets.begin(), assets.end(), back_inserter(photos), [] (shared_ptr<MediaAsset> p) -> bool
    {
        // Use dynamic_pointer_cast to test whether
        // element is a shared_ptr<Photo>.
        shared_ptr<Photo> temp = dynamic_pointer_cast<Photo>(p);  
        return temp.get() != nullptr;
    });

    for (const auto&  p : photos)
    {
        // We know that the photos vector contains only 
        // shared_ptr<Photo> objects, so use static_cast.
        wcout << "Photo location: " << (static_pointer_cast<Photo>(p))->location_ << endl;
    }

- dynamic_pointer_cast, static_pointer_cast, const_pointer_cast를 사용하여 shared_ptr를 캐스팅할 수 있음.

- shared_ptr는 다음의 방법으로 다른 함수에 전달할 수 있음.
 : 값(value)으로 전달 (복사 생성자 호출 => 참조 횟수 증가, 약간 오버 헤드 있음)
 : 참조(reference), const 참조로 전달 (참조횟수 증가 안함.)
 : 내부 포인터 또는 내부 개체에 대한 참조를 전달 (개체 공유, 단 참조 횟수는 증가하지 않음, 좀 위험.)

- shared_ptr 전달 방법을 결정할 때 고려 해야 하는 것은 호출 수신자(callee)가 소유권을 공유할 수 있는지를 판단해야 함.
 : shared_ptr가 call이 완료 될 때 까지 caller, callee 외 다른 소유자로 인해 shared_ptr의 유효함이 보장되면 값으로 전달하고, 보장되지 않는 경우라면 참조를 넘겨 callee가 알아서 판단하도록 한다.
- std:vector<shared_ptr<T>>에서 람다 식 본문 또는 명명된 함수 개체로 전달할 경우 람다, 함수 개체가 포인터를 저장하지 않는다면 참조로 전달한다.


 // Initialize two separate raw pointers.
    // Note that they contain the same values.
    auto song1 = new Song(L"Village People", L"YMCA");
    auto song2 = new Song(L"Village People", L"YMCA");

    // Create two unrelated shared_ptrs.
    shared_ptr<Song> p1(song1);    
    shared_ptr<Song> p2(song2);

    // Unrelated shared_ptrs are never equal.
    wcout << "p1 < p2 = " << std::boolalpha << (p1 < p2) << endl;
    wcout << "p1 == p2 = " << std::boolalpha <<(p1 == p2) << endl;

    // Related shared_ptr instances are always equal.
    shared_ptr<Song> p3(p2);
    wcout << "p3 == p2 = " << std::boolalpha << (p3 == p2) << endl; 

- 가리키는 개체의 값을 비교하는 것이 아니라  shared_ptr이 가리키는 개체를 비교해야 함.


Modern Effective C++에서 관련된 chapter는 다음과 같고
더 자세한 내용을 원한다면 책을 꼭 읽는 것을 추천.
단 Modern Effective C++이 처음이라면 Effective C++을 먼저 읽는 것을 추천.

Effective Modern C++: 42 Specific Ways to Improve Your Use of C++11 and C++14
http://a.co/0MIIC9k

Item 19: Use std::shared_ptr for shared-ownership resource management.
Item 21: Prefer std::make_unique and std::make_shared to direct use of new.

- std::shared_ptr의 크기는 생 포인터의 두배
 : custom deleter를 지정해도 std::shared_ptr 객체의 크기가 변하지 않음.
- 제어 블럭에서 reference count, weak reference count, custom deleter 등을 저장함.
 : std::make_shared는 항상 제어 블럭을 생성
 : std::unique_ptr, std::auto_ptr로 부터 std:shared_ptr 을 생성하면 제어 블록이 생성
 : raw pointer로 std::shared_ptr 생성하면 제어 블록이 생성
   단 하나의 raw pointer에서 여러 std::shared_ptr을 생성하면 문제 발생.
- std::shared_ptr로 관리되는 클래스에서 클래스의 this로 부터 shared_ptr을 생성할 때는 shared_from_this()를 사용해야 순환 참조 문제가 없음.
- 참조 횟수의 증가와 감소가 반드시 원자적 연산이어야 함.

C++ 11/14 관련 내용 대충 정리, unique_ptr

최신 C++을 공부하려 책을 보긴 했었는데
내용이 기존 문법과 함께 여기저기 흩어져 있어 보기에 좀 어려워
MSDN을 참고하여 대충 정리하려함.

C++11/14/17 기능에 대한 지원(최신 C++)
https://msdn.microsoft.com/ko-kr/library/hh567368.aspx


unique_ptr

https://msdn.microsoft.com/ko-kr/library/hh279676.aspx

- 일반 C++ 개체에 대한 스마트 포인터가 필요할 경우 사용
- unique_ptr은 포인터를 공유 하지 않고 이동만 가능함.
 : 이동 시 메모리 리소스의 소유권이 이전되어 원래 unique_ptr는 더 이상 소유하지 않음.
- 다른 unique_ptr로 복사, 함수에 값으로 전달하거나 사본이 필요한 STL(표준 템플릿 라이브러리) 알고리즘에서는 사용 불가
- unique_ptr을 생성할 경우 되도록이면 make_unique 도우미 함수를 사용
 : c++ 14 지원을 위해 compile option(-std=c++14
- <memory> 헤더의 std namespace에 정의 되어 있음.





unique_ptr<Song> SongFactory(const std::wstring& artist, const std::wstring& title)
{
    // Implicit move operation into the variable that stores the result.
    return make_unique<Song>(artist, title);
}

void MakeSongs()
{
    // Create a new unique_ptr with a new object.
    auto song = make_unique<Song>(L"Mr. Children", L"Namonaki Uta");

    // Use the unique_ptr.
    vector<wstring> titles = { song->title };

    // Move raw pointer from one unique_ptr to another.
    unique_ptr<Song> song2 = std::move(song);

    // Obtain unique_ptr from function that returns by value.
    auto song3 = SongFactory(L"Michael Jackson", L"Beat It");
}

일반적인 사용 예제, song 변수가 가졌던 개체는 song2로 이전(move)되어 song의 member들은 nullptr이 됨.

void SongVector()
{
    vector<unique_ptr<Song>> songs;

    // Create a few new unique_ptr<Song> instances
    // and add them to vector using implicit move semantics.
    songs.push_back(make_unique<Song>(L"B'z", L"Juice"));
    songs.push_back(make_unique<Song>(L"Namie Amuro", L"Funky Town"));
    songs.push_back(make_unique<Song>(L"Kome Kome Club", L"Kimi ga Iru Dake de"));
    songs.push_back(make_unique<Song>(L"Ayumi Hamasaki", L"Poker Face"));

    // Pass by const reference when possible to avoid copying.
    for (const auto& song : songs)
    {
        wcout << L"Artist: " << song->artist << L"   Title: " << song->title << endl; 
    }    
}

이동이 불가하므로 vector 로 바로 생성된 개체를 전달함.
vector내 개체를 접근하기 위해 const auto& 로 reference를 참조함.
(const auto song : songs) 은 unique_ptr을 복사하려는 것이므로 컴파일 에러 발생


// Create a unique_ptr to an array of 5 integers.
 auto p = make_unique<int[]>(5);

 // Initialize the array.
 for (int i = 0; i < 5; ++i)
 {
  p[i] = i;
  wcout << p[i] << endl;
 }

배열에 대한 unique_ptr를 make_unique를 사용해서 생성할 수 있지만 초기화는 별도로..


Modern Effective C++에서 관련된 chapter는 다음과 같고
더 자세한 내용을 원한다면 책을 꼭 읽는 것을 추천.
단 Modern Effective C++이 처음이라면 Effective C++을 먼저 읽는 것을 추천.

Effective Modern C++: 42 Specific Ways to Improve Your Use of C++11 and C++14
: http://a.co/0MIIC9k

Item 18:Use std::unique_ptr for exclusive-ownership resource management.
Item 21:Prefer std::make_unique and std::make_shared to direct use of new.


참고할 만한 것들을 보면

아래와 같이 Investment를 상속하는 여러 class들이 있을 경우

class Investment { … };
class Stock:  public Investment { … };
class Bond:  public Investment { … };
class RealEstate:  public Investment { … };

template<typename... Ts>                // return std::unique_ptr std::unique_ptr<Investment>             // to an object created 
makeInvestment(Ts&&... params);       // from the given args

이렇게 factory 함수인 makeInvestment를 만들어 Investment를 가지는 unique_ptr를 제공할 수 있음.

{
   ...
   auto pInvestment =                // pInvestment is of type     
   makeInvestment( arguments );  // std::unique_ptr<Investment>
   ...
}

이렇게 사용을 하게 될 것이고 생성된 pInvestment는 변수의 scope을 벗어나게 되면 자동으로 소멸 되게 되는게 일반적인 사용 시나리오 일 것임.

함께 unique_ptr는 기본적으로 개체의 소멸자를 호출하겠지만 custom deleter를 직접 지정할 수 있음.

auto delInvmt = [](Investment* pInvestment)       // custom
                      {                                          // deleter
                         makeLogEntry(pInvestment);   // (a lambda
                         delete pInvestment;              // expression)
                      };
template<typename... Ts>                                // revised
std::unique_ptr<Investment, decltype(delInvmt)>   // return type
makeInvestment(Ts&&... params)


그리고 c++14의 auto를 사용하게 된다면.. 좀 더 간편할 것임.

template<typename... Ts>
auto makeInvestment(Ts&&... params)              // C++14

다만 일반적인 unique_ptr의 사이즈는 raw pointer와 동일하겠지만 custom deleter를 가진 unique_ptr의 사이즈는 한두 word의사이즈가 추가된다. 함께 custom deleter로 function object를 사용하는것 보다 stateless function object인 lambda를 사용하는 것이 unique_ptr의 사이즈를 늘리지 않는다고 함.

그리고 unique_ptr를 생성할 때는 new 대신 std::make_unique를 사용하는 것을 추천하고 있음.
다만 std::make_unique는 c++14에서 지원하고 있어 compile option 설정 필요.