336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

컨벌루션 신경망(커브넷)은 영상 인식에 특화된 심층 신경망입니다.


어떤 영상 인식 기술을 사용하든지 간에 원본 이미지를 바로 사용하면 인식 성능이 좋지 않기 때문에 원본 이미니의 고유한 특징(feature)이 잘 들어 나도록 가동된 이미지를 사용해야 하는데 이러한 특징을 추출하는 설계는 그동안 머신러닝과 별개로 진행 되었습니다.


그러나 커브넷에서는 이러한 특징 추출기를 수작업으로 설계하지 않고 신경망의 학습 과정에 포함시켜 일괄 처리 합니다.


커브넷은 특징 추출 신경망이 깊을수록, 즉 층이 더 많이 쌓을수록 대체로 영상 인식 성능도 좋아진다고 합니다.


먼저 입력된 원본 이미지는 앞쪽의 특징 추출 신경망을 먼저 통화 하고, 여기서 추출된 이미지는 다시 특징 신호의 튀쪽의 분류 신경망에 다시 입력됩니다.


커브넷의 특징 추출 신경망은 컨버루션 계층(Convolutional layer) 와 풀링 계층(Pooling layer)을 차례로 쌓은 형태로 일종의 디지털 필터를 모안 놓은 계층이라고 이해마년 됩니다.


풀링 계층은 주위의 픽셀을 묶어서 하나의 대표 픽셀로 바꾸며 이미지의 차원을 축소하는 역할을 합니다.



컨벌루션 계층 입력 이미지의 고유한 특징을 부각시킨 이미지를 새로 만들어내는 역할을 합니다. 이러한 이미지를 '특징 맵(feature map' 이라고 부릅니다.


일반 신경망의 계층 구조와는 다르게 계층의 노드들은 입력 이미지를 다른 이미지로 변환하는 필터(Kernel)인 '컨벌루션 필터'로 입력 이미지를 처리하면 특징 맵을 얻을 수 있습니다.


컨벌루션 필터로 처리된 특징 맵은 활성함수를 거쳐 최종 출력 됩니다. 활성함수로는 요즘엔 ReLU함수를 많이 사용되지만, 시그모이드 함수나 tanh 함수를 쓰는 경우도 있습니다.


* ReLU 활성화 함수 그래디언트 소실(vanishing gradient) 현상은 역전파 알고리즘으로 심층 신경망을 학습시키는 과정에서, 출력층에서 멀어질수록 신경망의 출력 오차가 반영되지 않는 현상을 말합니다. 이러한 문제에 대하여 대표적인 방안은 노드들의 활성함수를 ReLU(Rectified Linear Unit) 함수로 바꾸는 것입니다.

ReLU 함수는 입력이 음수면 0, 양수이면 입력값 그대로 출력하는 함수로. 이런 간단한 개선으로 심층 신경망의 학습 성능을 개선할 수 있습니다.



풀링 계층 이미지의 크기를 줄이는 역할을 합니다. 입력 이미지의 특정 영역에 있는 픽셀들을 묶어서 하나의 대표 값으로 축소합니다. 보통 픽셀들은 정방 행렬로 묶어서 하나의 대표 값을 계싼하기 위해 평균값이나 최대값을 많이 사용합니다.


플링 계층은 입력 이미지에서 인식 대상이 한 쪽으로 치우쳐 있거나 돌아가 있어도 어느 정도 보상해주는 역할을 합니다. 또한 이미지의 크기를 줄여주어, 계산량을 줄이고 과적합을 방지하는 데도 도움이 됩니다.



'ⓘⓣ > 인공지능' 카테고리의 다른 글

[딥러닝] 텐서플로 설치 (Installing with virtualenv)  (0) 2018.01.08
[AI] 텐서플로 (TensorFlow)  (0) 2017.12.16
블로그 이미지

뚱땡이 우주인

,
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

Sublime Text에는 subl 이라는 CLI(Command Line Interface)가 포함되어 있지만 기본 설치로는 활성화가 되지 않는다.

터미널에서 바로 사용하려면 subl 을 실행 가능한 심볼릭 링크를 추가 해야 한다.


1. 먼저 sublime이 제대로 설치 되어 있는지 확인해 보자

/Applications/Sublime\ Text.app/Contents/SharedSupport/bin/subl

SublimeText 가 정상적으로 열리면 OK. (SublimeText3 기준임)



2. subl을 실행 가능한 심볼릭 링크 (Symbolic link)를 추가 한다.

ln -s /Applications/Sublime\ Text.app/Contents/SharedSupport/bin/subl /usr/local/bin/subl

작동이 제대로 되는지 확인하려면 수정하려는 파일을 subl 파일명을 입력해서 해당 파일이 sublimetext로 열리는지 확인해 보자

subl test.text

만약 제대로 동작을 하지 않는다면 새로운 심볼릭 링크가 포함된 폴더를 환경설정에 추가 해야 한다.

먼저 echo &PATH 명령어를 통해서 본인이 심볼릭 링크를 생선한 디렉토리가 등록되어 있는지 확인하자.

subl test.tex
$ echo $PATH
/Library/Frameworks/Python.framework/Versions/3.5/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/share/dotnet:/Library/Frameworks/Mono.framework/Versions/Current/Commands:/Applications/Wireshark.app/Contents/MacOS

/usr/local/bin 이 제대로 PATH에 등록 되어 있는것을 확인할 수 있다.

만약 PATH가 등록되어 있지 않다면 .bash_profile을 수정하여 PATH를 추가하도록 하자


open ~/.bash_profile


bash_profile 에 아래 경로를 추가한다.

export PATH=/usr/local/bin


저장 후 .bash_profile을 아래 명령어를 통해 다시 로드 하도록 하자

source ./bash_profile


이제 터미널에서 subl 을 입력하면 서브라임 텍스트가 성공적으로 열릴 것이다^^



블로그 이미지

뚱땡이 우주인

,
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

Threads allow you to execute multiple functions at the same time but it is often necessary that these functions access shared resources. Access to shared resources must be synchronized so that at time, only one thread would be able to read or write from or to the shared resource.


  • std::mutex is the most commonly used mutex type; it is illustrated in the preceding code snippet. It provides methods to acquire and release the mutex. lock() tries to acquire the mutex and blocks it if it is not available, try_lock() tries to acquire the mutex and returns it without blocking if the mutex is not available, and unlock() releases the mutex.
  • std::timed_mutex is similar to std::mutex but provides two more methods to acquire the mutex using a timeout: try_lock_for() tries to acquire the mutex and returns it if the mutex is not made available during the specified duration, and try_lock_until() tries to acquire the mutex and returns it if the mutex is not made available until a specified time point.
  • std::recursive_mutex is similar to std::mutex, but the mutex can be acquired multiple times from the same thread without being blocked.
  • std::recursive_timed_mutex is a combination of a recursive mutex and a timed mutex.




try_lock Example

#include 
#include 
#include 
#include  // std::cout

std::chrono::milliseconds interval(1000);

std::mutex mutex;
int job_shared = 0; // both threads can modify 'job_shared',
					// mutex will protect this variable

int job_exclusive = 0; // only one thread can modify 'job_exclusive'
					   // no protection needed

					   // this thread can modify both 'job_shared' and 'job_exclusive'
void job_1()
{
	std::this_thread::sleep_for(interval); // let 'job_2' take a lock

	while (true) {
		// try to lock mutex to modify 'job_shared'
		if (mutex.try_lock()) {
			std::cout << "job shared (" << job_shared << ")\n";
			mutex.unlock();
			return;
		}
		else {
			// can't get lock to modify 'job_shared'
			// but there is some other work to do
			++job_exclusive;
			std::cout << "job exclusive (" << job_exclusive << ")\n";
			std::this_thread::sleep_for(interval);
		}
	}
}

// this thread can modify only 'job_shared'
void job_2()
{
	mutex.lock();
	std::this_thread::sleep_for(5 * interval);
	++job_shared;
	mutex.unlock();
}

int main()
{
	std::thread thread_1(job_1);
	std::thread thread_2(job_2);

	thread_1.join();
	thread_2.join();
}

job exclusive (1)
job exclusive (2)
job exclusive (3)
job exclusive (4)
job shared (1)


std::lock_guard is the locking mechanism seen earlier; it represents a mutex wrapper implemented in an RAII manner. it attempts to acquire the mutex at the time of it's construction and release it upon destruction.


        template <class M>

        class lock_guard

        {

        public:

          typedef M mutex_type;


          explicit lock_guard(M& Mtx) : mtx(Mtx)

          {

            mtx.lock();

          }


          lock_guard(M& Mtx, std::adopt_lock_t) : mtx(Mtx)

          { }


          ~lock_guard() noexcept

          {

            mtx.unlock();

          }


          lock_guard(const lock_guard&) = delete;

          lock_guard& operator=(const lock_guard&) = delete;

        private:

          M& mtx;

        }; 



unique_lockstd::unique_lock is a mutex ownership wrapper that provides support for deferred locking, time locking, recursive locking, transfer of ownership, and using it with condition variables. This is available in C++11.


#include 
#include 
#include 
 
struct Box {
    explicit Box(int num) : num_things{num} {}
 
    int num_things;
    std::mutex m;
};
 
void transfer(Box &from, Box &to, int num)
{
    // don't actually take the locks yet
    std::unique_lock lock1(from.m, std::defer_lock);
    std::unique_lock lock2(to.m, std::defer_lock);
 
    // lock both unique_locks without deadlock
    std::lock(lock1, lock2);
 
    from.num_things -= num;
    to.num_things += num;
 
    // 'from.m' and 'to.m' mutexes unlocked in 'unique_lock' dtors
}
 
int main()
{
    Box acc1(100);
    Box acc2(50);
 
    std::thread t1(transfer, std::ref(acc1), std::ref(acc2), 10);
    std::thread t2(transfer, std::ref(acc2), std::ref(acc1), 5);
 
    t1.join();
    t2.join();
}


.

shared_lock std::shared_lock is a mutex-shared ownership wrapper that provides support for deferred locking, time locking, and transfer of ownership. This is available in C++14.

#include 
#include 
#include 
#include 

std::shared_timed_mutex m;
int i = 10;

void read()
{
	// both the threads get access to the integer i
	std::shared_lock slk(m);
	std::cout << "read i as " << i << "...\n"; // this is not synchronized
	std::this_thread::sleep_for(std::chrono::milliseconds(10));
	std::cout << "woke up...\n";
}

int main()
{
	std::thread r1(read);
	std::thread r2(read);

	r1.join();
	r2.join();
	return 0;
}
read i as read i as 10...
10...
woke up...
woke up...
#include 
#include 
#include 
#include 

std::mutex g_mutex;

template 
struct container
{
	std::mutex     mutex;
	std::vector data;
};

void thread_func()
{
	using namespace std::chrono_literals;
	{
		std::lock_guard lock(g_mutex);
		std::cout << "running thread "
			<< std::this_thread::get_id() << std::endl;
	}

	// Provides a hint to the implementation to reschedule the execution of threads, allowing other threads to run.
	std::this_thread::yield();

	std::this_thread::sleep_for(2s);

	{
		std::lock_guard lock(g_mutex);
		std::cout << "done in thread "
			<< std::this_thread::get_id() << std::endl;
	}
}

// Lock the mutexes at the same time using a deadlock avoidance algorithm with std::lock():
template 
void move_between(container & c1, container & c2, T const value)
{
	std::lock_guard l1(c1.mutex);
	std::lock_guard l2(c2.mutex);

	c1.data.erase(
		std::remove(c1.data.begin(), c1.data.end(), value),
		c1.data.end());
	c2.data.push_back(value);
}

int main()
{
	std::thread t0(thread_func);
	t0.join();

	container c1;
	c1.data.push_back(1);
	c1.data.push_back(2);
	c1.data.push_back(3);

	container c2;
	c2.data.push_back(4);
	c2.data.push_back(5);
	c2.data.push_back(6);

	std::thread t1(move_between, std::ref(c1), std::ref(c2), 3);
	std::thread t2(move_between, std::ref(c2), std::ref(c1), 6);

	t1.join();
	t2.join();

	return 0;
}



condition_variable Mutexes are synchronization primitives that can be used to protect access to shared data. However, the standard library provides a synchronization primitive called a condition variable that enables a thread to signal to others that a certain condition has occurred. The thread or the threads that are waiting on the condition variable are blocked until the condition variable is signaled or until a timeout or a spurious wakeup occurs




#include 
#include 
#include 
#include 

std::condition_variable cv;
std::mutex cv_mutex;
std::mutex io_mutex;
int data = 0;


int main() {

	std::thread p([&]() {
		// simulate long running operation
		{
			using namespace std::chrono_literals;
			std::this_thread::sleep_for(2s);
		}

		// produce
		{
			std::unique_lock lock(cv_mutex);
			data = 42;
		}

		// print message
		{
			std::lock_guard l(io_mutex);
			std::cout << "produced " << data << std::endl;
		}

		// continued from 4.
		cv.notify_one();
	});


	std::thread c([&]() {
		// wait for notification
		{
			std::unique_lock lock(cv_mutex);
			cv.wait(lock);
		}

		// continued from 6.
		{
			std::lock_guard lock(io_mutex);
			std::cout << "consumed " << data << std::endl;
		}
	});

	p.join();
	c.join();
	return 0;
}


'ⓟrogramming > C++' 카테고리의 다른 글

Reverse Sentesces  (0) 2018.01.16
스트림 연산  (0) 2018.01.16
[Thread] Working with threads  (0) 2018.01.04
[Thread] Handling exceptions from thread functions  (0) 2018.01.03
Visual Studio 에서 Boost 사용법  (0) 2016.07.28
블로그 이미지

뚱땡이 우주인

,