반응형

Basler Camera acA2500-14gc 카메라를 리눅스 환경에서 다뤄보려고 한다.

 

해당 카메라는 GigE(Giga Ethernet)통신을 사용한다.

랜선을 통한 통신방법인데 나는 우분투를 듀얼부팅이 아닌 가상환경(VirtualBox)에 설치를 해두었기에

GigE통신을 사용하여 카메라를 연결하는데 어려움이 있었다.

 

우선 리눅스 환경에서 pylon에서 제공하는 패키지를 풀게되면

ipconfigrator 이라는 실행파일이 생기게 된다.

 

이를 실행시키면 위와 같은 창이 뜨게된다.

이 부분에 카메라의 정보가 떠야하는데 보다싶이 이더넷 정보만 있고 카메라에 대한 정보는

뜨지 않는걸 확인할 수 있다.(제대로 연결이 안됐기 때문)

 

그럼 제어판의 네트워크 환경으로 들어가 다음과 같이 설정해주도록 한다.

 

"VirtualBox Host-Only Network"의 IP주소를 192.168.137.1 로 고정해주고 서브넷 마스크는 255.255.255.0 으로

고정시켜주었다.

 

 

그럼 VirtualBox 프로그램 창의 좌측 상단의 "파일" 탭에서 "호스트 네트워크 관리자"를 클릭한다.

 

 

 

 

 

 

"수동으로 어뎁터 설정" 에서 IP주소와 서브넷 마스크를 Windows 네트워크 설정에서 지정해준 IP대로

맞게 되어있는지 확인하고 다르게 되어있다면 수정해준다.

이 때 우측 상단에 보이는 DHCP서버는 사용을 하지 않도록 체크박스를 해제해준다.

 

 VirtualBox 프로그램창의 "설정" "네트워크"에서 

 

"어뎁터에 브리지"로 다음과 같이 설정해 준 후 다시 Refresh를 눌러 새로고침을 하게 되면

 

이렇게 Not Reachable 이라는 문구와 함께 카메라가 인식은 된 듯 하지만 연결은 잘 되지 않는 상태가 된다.

 

이는 아마 해당 이더켓 포트에 대해서 virtualbox와 Windows에서 사용하는 IP가 다르기에 발생하는 오류가 아닐까 예상된다.

 

우분투의 네트워크 설정에서 아래와 같이 "옵션"에서 아래와 같이 설정

 

그 다음 우분투의 "설정"에서 "네트워크" 부분에 들어와 "옵션"을 선택한다

(이때 유선을 "켬"으로)

 

"일반" 탭에서는 위와 같이 설정한다.

 

"이더넷" 탭에서는 위와 같이 설정한다.

 

"IPv4 설정" 탭에서는 위와 같이 설정한다.

여기서 주소는 게이트웨이와 다름을 주의하자.

 

"IPv6 설정"탭은 위와 같이 설정한다.

 

이제 다시 "IPConfigurator"을 실행시킨다.

 

 

 

위와 같이 뜰 것인데 이때 좌측 하단의 "Static IP"를 선택한 후 아래와 같이 설정해준다.

 

 

 

그리고 새로고침을 누르게 되면 정상적으로 연결이 된다.

 

 

 

 

 

 

https://dbrang.tistory.com/1279

 

[VM] VirtualBox 가상머신에 고정IP 설정하기 - ver.dBRang

/******************************************************************************************************************* -- Title : [VM] VirtualBox 가상머신에 고정IP 설정하기 - ver.dBRang -- Reference :..

dbrang.tistory.com

 

 

 

 

*******************************************************************************

윈도우 환경에서도 

연결이 잘 안될때는 좌측 하단의 고정IP를 활용한다.

 

ipconfig를 통해 이더넷 어뎁터의 IP주로솨 서브넷마스크를 입력해준다.

 

 

 

IP를 변경했더니 잘 연결되는 것을 확인할 수 있다.

 

------------------------------------------------------------------------------------------------------------------------------

 

이 부분까지 되었으면 이제 와이파이까지 연결해보자.

 

 

VirtualBox에서

네트워크 어뎁터를 2개를 사용하는데 첫번째로는 NAT에 연결하고

어댑터2는 아래와 같이 연결한다.

 

(이 때 호스트 네트워크는 이 전 상태와 같이 유지한다.)

 

 

 

 

 

그리고 우분투의 실행창에서

WIFI에 관한 네트워크를 위와 같이 IP가 자동으로 설정되도록 하고 이더넷 부분에서 해당되는 이더넷을 선택해준다.

 

 

 

GigE 연결에 관련된 네트워크는 위와 같이 수동으로 IP를 설정해주고 이더넷 부분에서 해당되는 이더넷을 선택해준다.

반응형
반응형

바슬러 홈페이지에서 Linux용 파일을 다운받는다.

 

https://www.baslerweb.com/ko/sales-support/downloads/software-downloads/pylon-5-2-0-linux-arm-64-bit-debian/

 

pylon 5.2.0 카메라 소프트웨어 제품군 Linux ARM 64비트 - Debian 설치 패키지 | Basler

pylon 5.2.0 카메라 소프트웨어 제품군 Linux ARM 64비트는 사용하기 쉬운 SDK와 드라이버 및 툴로 구성된 소프트웨어 패키지로서 모든 종류의 Basler 카메라를 조작하는 데 이용할 수 있습니다.

www.baslerweb.com

 

위와 같이 패키지 파일이 받아진 것을 확인할 수 있다.

 

위의 패키지를 풀게되면

이렇게 에 디렉토리가 생성된 것을 확인할 수 있다.

여기에 샘플 예제가 있을 법 한데 이를 이용해서 출력해보자

반응형
반응형

카메라 영상을 출력하도록 하고자한다.

다만 일반적인 웹캠을 통해서가 아닌 Basler Camera(GigE)를 통해 출력해보자 한다.

 

 

 

https://www.baslerweb.com/ko/sales-support/downloads/software-downloads/#type=pylonsoftware;series=baslerace;os=windows64bit;version=all

 

소프트웨어 다운로드 | Basler

소프트웨어 다운로드 영역에는 pylon 카메라 소프트웨어 제품군, IP 카메라 펌웨어 및 BBPL을 포함해 귀하에게 필요한 모든 Basler 소프트웨어가 있습니다.

www.baslerweb.com

위의 링크를 통해 Basler 카메라의 소프트웨어를 다운받도록 한다.

 

 

 

 

해당 파일을 다운받게 되면

"Development" 파일의 "Samples", "C++" 파일에 다양한 예제파일이 있는 것을 확인할 수 있다.

 

카메라를 연결한 후 해당 예제샘플을 실행시키면서 영상이 출력되는 예제파일을 사용하여

이를 내가 원하는 스타일에 맞게 수정하는 방향으로 진행하겠다.

 

 

우선 다양한 예제들 중 Grab 이라는 예제를 실행시켜보면 카메라 영상을 출력하는 것을 확인할 수 있다.

 

그럼 비주얼스튜디오로 빈프로젝트를 생성하고 해당 코드를 그대로 복사-붙여넣기 하여 동일한 내용을 입력하여준다.

 

그리고 잘 실행되는 예제파일의 프로젝트 속성을 그대로 가져온다.

 

C/C++ 의 "추가 포함 디렉터리"를 위와 같이 맞춰주고

 

 

 

 

 

링커의 "추가 라이브러리 디렉터리" 또한 위와 같이 맞추어준다.

 

 

그리고 실행을 시키게되면

위와 같은 에러가 출력될 수 있는데 이는 위에서 진행하였던 프로젝트 설정 과정에서 x64와 x86을 맞춰주지 않았기에

발생된 것이다.

 

Visual Studio의 상단에 위와 같은 부분이 있는데 이 곳을 x64로 맞추어주면 된다.

 

"새로 만들기"를 클릭

그리고 실행시키면 원래 제공받았던 샘플파일처럼 제대로 작동하게 된다.

 

그럼 이제 OpenCV를 이용하여 해당 영상을 처리하는 과정을 진행하도록 하겠다.

반응형
반응형

https://webnautes.tistory.com/1030

 

Ubuntu 16.04에 opencv_contrib 포함하여 OpenCV 4.0.1 설치하는 방법

OpenCV 4.0.1과 opencv_contrib(extra modules)를 컴파일하여 Ubuntu 16.04에 설치하는 방법을 다룹니다. ps. Ubuntu 18.04에 OpenCV를 설치하는 방법은 다음 포스트를 참고하세요 [OpenCV/Ubuntu 개발 환경] - Ub..

webnautes.tistory.com

https://agiantmind.tistory.com/183

 

[Ubuntu] Ubuntu 16.04 + OpenCV 3.2 설치

※ 시스템 환경 - Ubuntu 16.04.2 LTS 64bit - OpenCV 3.2 - 설치일: 2017.06.12 ※ 참고자료 1. 멈춤보단 천천히라도 - Ubuntu 16.04에 opencv_contrib 포함하여 OpenCV 3.2 설치 위 블로그에 OpenCV 설치에 대한..

agiantmind.tistory.com

 

위의 두 블로그 글을 참고하였다.

 

우선 설치된 OpenCV가 있다면 새로 설치하는 과정에서 오류가 발생할 수 있으므로 기존의 OpenCV를 제거해준다.

 

$ pkg-config --modversion opencv

 

를 통해 기존의 openCV가 설치되어있는지 확인한다.

설치되어 있을 경우

위와 같이 설치된 OpenCV의 버전이 출력되게 되고

 

설치되어있지 않을 경우

 

위와 같은 내용이 출력되게 된다.

 

설치된 경우

$ sudo apt-get purge libope cv* python-opencv

$ sudo apt-get autoremove

 

과정을 통해 삭제하고 진행하도록 한다.

(설치되어있지 않은 경우 바로 진행하도록 한다.)

 

2. 기존 설치된 패키지 업그레이드

 

기존에 설치된 패키지들의 새로운 버전이 저장소에 있다면 리스트를 업데이트 하기 위해 실행한다.

또한 업그레이드를 진행하도록 한다.

 

$ sudo apt-get update

$ sudo apt-get upgrade

 

3. OpenCV 컴파일 전 필요한 패키지 설치

 

OpenCV를 컴파일하는데 사용하는 것들이 포함된 패키지들을 설치한다.

 

$ sudo apt-get install build-essential cmake

$ sudo apt-get install pkg-config

$ sudo apt-get install libjpeg-dev libtiff5-dev libjasper-dev libpng12-dev

$ sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libxvidcore-dev libx264-dev libxine2-dev

$ sudo apt-get install libv4l-dev v4l-utils

$ sudo apt-get install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev

$ sudo apt-get install libqt4-dev

$ sudo apt-get install mesa-utils libgl1-mesa-dri libqt4-opengl.dev

$ sudo apt-get install libatlas-base-dev gfortran libeigen3-dev

$ sudo apt-get install python2.7-dev python3-dev python-numpy python3-numpy

 

(각 코드에 대한 자세한 내용은 위의 블로그에 자세히 설명되어있다)

 

4. OpenCV 설정과 컴파일 및 설치

 

소스코드를 저장할 임시 디렉토리를 생성하여 이동한다.

$ mkdir opencv

$ cd opencv

 

OpenCV 3.2.0 소스코드를 다운로드 받아 압축을 풀어준다.

 

$ wget -O opencv.zip https://github.com/Itseez/opencv/archive/3.2.0.zip 

불러오는 중입니다...

$ unzip opencv.zip

$ wget -O opencv_contrib.zip https://github.com/Itseez/opencv_contrib/archive/3.2.0.zip 

불러오는 중입니다...

$ unzip opencv_contrib.zip

 

 

3.2) OpenCV 빌드

 

$ cd opencv-3.2.0/

$ mkdir build

$ cd build

 

$ cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D WITH_TBB=OFF -D WITH_IPP=OFF -D WITH_1394=OFF -D BUILD_WITH_DEBUG_INFO=OFF -D BUILD_DOCS=OFF -D INSTALL_C_EXAMPLES=ON -D INSTALL_PYTHON_EXAMPLES=ON -D BUILD_EXAMPLES=OFF -D BUILD_TESTS=OFF -D BUILD_PERF_TESTS=OFF -D ENABLE_NEON=ON -D WITH_QT=ON -D WITH_OPENGL=ON -D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib-3.2.0/modules -D WITH_V4L=ON -D WITH_FFMPEG=ON -D WITH_XINE=ON -D BUILD_NEW_PYTHON_SUPPORT=ON -D PYTHON_INCLUDE_DIR=/usr/include/python2.7 -D PYTHON_INCLUDE_DIR2=/usr/include/x86_64-linux-gnu/python2.7 -D PYTHON_LIBRARY=/usr/lib/x86_64-linux-gnu/libpython2.7.so ../

 

컴파일을 시작하기 전에 사용중인 컴퓨터의 CPU 코어수를 확인한다.

 

$ cat /proc/cpuinfo | grep processor | wc -l(알파벳 i가 아닌 l)

$ time make -j4(여기서 4는 코어수)

$ sudo make install

 

4. 설치확인

 

$ pkg-config --modversion opencv

$ pkg-config --libs --cflags opencv

 

 

 

5. 예제코드 실행

 

opencv디렉토리에

$ gedit Test.cpp

 

를 통해 코드를 입력한다.

 

 

#include <opencv/hughgui.h>

int main()
{
	IplImage *image = cvLoadImage("lena.jpeg");
    cvShowImage("Test", image);
    cvWaitKey(0);
    cvReleaseImage(&image);
}

 

 

 

 

$ g++ -o imgvoew Test.cpp $(pkg-config --libs --cflags opencv)

 

$ ./imgview

 

반응형
반응형

카메라는 Basler 사의 acA2500-14gc 카메라를 사용했고 전원케이블과 랜선을 이용하여

PC의 랜포트에 연결을 해봤는데 이 방법으로는 연결이 잘 되지 않았다.

 

그래서 NEXT-POE3008GF 의 Hub를 사용하여

카메라를 연결하였다.

 

우선 카메라를 작동시킬 소프트웨어는

https://www.baslerweb.com/ko/sales-support/downloads/software-downloads/

 

소프트웨어 다운로드 | Basler

소프트웨어 다운로드 영역에는 pylon 카메라 소프트웨어 제품군, IP 카메라 펌웨어 및 BBPL을 포함해 귀하에게 필요한 모든 Basler 소프트웨어가 있습니다.

www.baslerweb.com

 

 

위의 파일을 다운로드 해주었다.

 

 

 

다음과 같이 프로그램들이 설치된 것을 확인할 수 있다.

 

여기서 pylon IP Configurator  을 클릭하여 프로그램을 실행시키면

이더넷 부분이 추가되는 것을 확인할 수 있다.

 

만약 이 부분이 뜨지 않는다면 랜선을 통한 PC와의 연결이 원활하지 않은 것으로

장치 관리자의 GbE 관련 부분을 제거하고 다시 새로고침을 통해 드라이버를 설치하여준다.

 

그리고 아까 설치한 프로그램 중 "pylon Viewer" 을 실행시키면

 

 

위와 같이 카메라가 추가된 것을 확인할 수 있다.

반응형
반응형

https://darkpgmr.tistory.com/32

 

카메라 캘리브레이션 (Camera Calibration)

카메라 캘리브레이션 (camera calibration)은 영상처리, 컴퓨터 비전 분야에서 번거롭지만 꼭 필요한 과정중의 하나입니다. 본 포스팅에서는 카메라 캘리브레이션의 개념, 카메라 내부 파라미터, 외부 파라미터,..

darkpgmr.tistory.com

 

 

우리가 실제 눈으로 보는 세상은 3차원이다.

3차원 공간에 한 물체가 있다고 하자.

하지만 이를 카메라로 찍으면 2차원을 나타내어지게 되고

기하학적으로 보면 사진을 찍을 때 카메라의 위치 및 방향을 고려하면

해당 물체의 3차원에서의 위치를 알 수 있다.

 

하지만 실제 이미지는 사용되는 렌즈, 렌즈와 이미지센서와의 거리, 렌즈와 이미지 센서와의 각도 등

카메라의 내부적인 부분에 의해 크게 영향을 받게되고 이러한 내부적인 요인들을 제거해야

정확한 계산이 가능해진다.

 

이렇게 내부 파라미터 값을 구하는 과정을 카메라 캘리브레이션이라고 한다.

 

 

 

카메라 영상은 3차원 공간상의 점들을 2차원 이미지 평면에 투사함으로서 얻어지는데

핀홀(pinhole)카메라 모델에서 이러한 변환 관계는 다음과 같이 모델링됩니다.

 

여기서 (X, Y, Z)는 월드좌표계 에서의 3D상의 물체의 좌표, [R|t] 는 월드 좌표계를

카메라 좌표계로 변환시키기 위한 회전/이동변환 행렬(외부 파라미터)이며

A는 intrinsic camera matrix 즉 카메라의 내부 파라미터에 대한 행렬이다.

 

 

 

즉 3D의 공간좌표와 2D 영상좌표 사이의 변환관계를 나타내는 파라미터를 찾는 과정을

캘리브레이션 과정이라 할 수 있다.

 

내부 파라미터의 fx, fy 값들은 초점거리를 나타내고

cx, cy는 주점(principle point)

skew_x = tan(alpha) 로 비대칭계수를 나타내게 된다.

 

 

 

1.  초점거리(focal length)

          : 렌즈 중심과 이미지센서(CCD, CMOS 등)와의 거리를 의미하며 카메라 모델에서 초점거리(f)는

픽셀단위로 표현되게 된다.

컴퓨터 비전 분야에서 초점거리를 픽셀단위로 나타내는 이유는 이미지픽셀과 동일한 단위로 초점거리를

표현함으로서 영상에서의 기하학적 해석을 용이하게 하기 위함이다.

 

그럼 초점거리는 위의 그림과 같이 길이로 나타내어지는데 왜 값이 fx, fy로 표현되는 것일까

길이는 하나의 값만 갖게 되는데 왜 fx와 fy의 2개로 나뉘게 되는 것인가.

 

위에서 얘기하였듯 초점 거리는 이미지센서의 픽셀에 대하여 상대적으로 나타내기 위하여 단위를 픽셀로

나타내게 된다.

 

이는 이미지센서가 정확히 정사각형이 아닐 수 있기 때문이다.

따라서 이미지 센서의 픽셀 가로 세로 크기가 다르다면 이에 맞추어 상대적으로 초점거리를 나타내게 된다.

(아직 확실하진 않지만 fx는 이미지 픽셀의 가로에 대하여 초점거리가 몇 픽셀인지

fy는 이미지 센서 픽셀의 세로에 대하여 초점거리가 몇 픽셀인지 나타내어지는 것 같다.)

하지만 요즘 카메라는 정사각형의 픽셀을 갖기 떄문에 f=fx=fy로 볼 수 있다고 한다.

 

 

추가적으로 카메라 좌표예 위의 한 점 (Xc, Yc, Zc)를 영상좌표에 투영해주게 되는 과정에서

 

위의 그림과 같이 초점에서 부터 길이가 1인(이때의 단위는 상대적인 것이다) normalized image plane을 생성하게 되면

(이떄의 normalized image plane은 실제로 존재하는 것이 아닌 계산을 위한 가상의 면이다)

카메라 좌표계에서의 좌표 (Xc, Yc) 를 Zc의 값으로 나눠주게 된다.

 

따라서 x와 y의 비율은 동일하지만 더 작아진 값이 투영되게 된다.

그리고 여기에 초점거리 f를 곱해주게 되면 우리가 원하는 이미지 평면에서의 영상좌표가 나오게 된다.

 

그런데 이미지에서 픽셀의 좌표는 이미지 중심이 아닌 이미지의 좌상단 모서리를 기준(원점)으로 하기 때문에 최종적인

영상 좌표는 여기에 (cx, cy)값을 더해주게 된다.

 

동일한 장면을 동일한 위치에서 동일한 각도로 찍더라도 사용한 카메라, 카메라의 셋팅에 따라서 서로 다른 영상을

얻게 된다. 이러한 카메라간의 차이는 일관적인 기하학적(geometry) 해석을 하는데 불필요한 요소가 되고 따라서

이러한 요소들을 제거하여 정규화된 이미지 평면에서 공통된 기하학적 특성을 분석하기 위해 카메라의 내부 파라미터들의 영향을 없애주기 위해 위와 같은 normalized plane을 통해 작업을 진행한다.

 

 

 

 

2. 주점(principle point)

 

        주점 cx와 cy는 카메라 렌즈의 중심 즉, 핀홀에서 이미지 센서에 내린 수선의 발의 영상좌표로서 일반적으로 

얘기하는 영상의 중심점(image center)과는 다른 의미입니다.

 

 

 

3. 비대칭 계수(skew coefficient)

 

      비대친계수 skew_c  는 이미지 센서의 cell array의 y축이 기울어진 정도를 나타낸다.

 

 

 

위의 사진에서 alpha값에 해당하고 (skew_c = tan(alpha) 가 된다.

 

하지만 요즘의 카메라는 비대칭계수가 거의 없기 떄문에 카메라 모델에서 보통 비대칭 계수까지 고려하지 않는다고 한다.(skew_c=0)

 

 

 

캘리브레이션 결과

반응형
반응형

가상머신을 통해 우분투에 접속하게되면

데스크탑의 경우 보통 랜선을 사용하기에 자동으로 이더넷 연결이 잡히게 된다.

 

따라서 USB동글을 통해 데스크탑에서 우분투의 와이파이에 접속하기 위한 방법을 간단히 정리하겠다.

 

처음 이더넷만 연결된 상태로 가상머신을 통해 우분투에 접속하게 되면

$ sudo lshw -C Network

를 입력할 경우 이더넷에 관련된 정보만 확인됨을 볼 수 있다.

 

따라서 가상머신의 환경설정을 통해 와이파이 연결이 잡힐 수 있도록 해주어야 한다.

 

위의 실행 화면 상단에 위치한 "설정"을 들어가 준다.

 

 

그 후 USB 탭에서 우측에 조그만하게 보이는  USB필터를 만드는 아이콘을 클릭하여 준다.

그럼 USB로 연결되어 있는 디바이스들의 목록이 확인되는데

여기서 USB 무선랜을 클릭하여 추가하여 준다.

 

마지막으로 "네트워크" 탭에서 위와 같이 무선랜을 설정하여 주면

 

우분투 실행시 와이파이가 잡히게 된다.

 

 

우분투를 실행하여 터미널창을 실행시키고

 

$ sudo lshw -C Network

위의 코드를 입력해보자.

 

무선랜에 대한 정보가 확인되는것을 볼 수 있다.

위의 결과에서

logical name: wlxe..... 부분이 인터페이스 이름이다.

 

 

 

또한 우측 상단의 인터넷 연결을 위한 아이콘을 클릭하면 위와 같이 와이파이 목록이 확인되는 것을 볼 수 있다.

 

 

 

$ iw <인터페이스 이름> link

을 입력하면 위의 결과와 같이 연결된 와이파이 정보가 확인되는 것을 알 수 있다.

 

 

반응형
반응형

[그림.1] 신경망의 예

신경망을 그림으로 나타내면 위의 그림과 같고 입력층, 은닉층, 출력층으로 이루어진 것을 볼 수 있다.

 

[그림.2] 

x1과 x2 의 신호를 입력으로 받아 y를 출력하는 퍼셉트론은 위의 [그림.2] 와 같이 표현될 수 있고

이를 식으로 표현하면 아래와 같다.

 

[식.1]

여기서 b는 편향을 나타내는 매개변수로 뉴런이 얼마나 쉽게 활성화되느냐를 제어하게 되고

w1과 w2는 각 신호의 가중치를 나타내는 매개변수로 각 신호의 영향력을 제어하게 된다.

 

그리고 이 식을 변형시켜서 아래와 같이 표현할 수 있다.

 

[식.2]

 

[식.3]

 

즉 (b+w1x1+w2x2) 가 0보다 작거나 같으면 0, 0보다 크면 1 이므로

[식.1] 은 [식.2]와 [식.3] 으로 표현될 수 있다.

 

이 때, 함수 h(x)를 활성화함수 라 하고 입력신호의 총 합을 출력신호로 변환시키는 작업을 하게 되는 함수이다.

 

따라서 위 [식.2], [식.3] 은

[식.2] -> 가중치가 곱해진 입력신호의 총 합을 계산함

[식.3] -> 그 합을 활성화함수에 입력해 결과를 나타냄

위의 2가지 과정으로 진행이 되고 따라서 아래와 같이 표현이 가능하다.

 

[그림.3]
[식.4]
[식.5]

 

즉 a는 입력신호와 가중치를 합한 값

h(a) 는 a의 값에따라 결과적으로 1인지 0인지를 판별하는 과정을 진행하는 함수

로 정리할 수 있다.

 

 

위의 [식.2], [식.3] 을 확인하여보면 x값에 따른 결과(h(x))가 0 아니면 1을 갖게 되고 이를 그래프로 표시하면

계단함수형태를 나타내게 된다.

 

 

[그림.4]

 

여기까지의 내용은 퍼셉트론에서 다룬 내용과 비슷하다.

 

퍼셉트론과 신경망의 가장 큰 차이는 활성화 함수 h(x)이고 h(x)의 형태가 퍼셉트론의 경우 위와같은 계단함수 형태,

신경망의 경우 부드러운 곡선형의 시그모이드 함수의 형태를 갖게 된다.

 

시그모이드 함수란

[식.6]

활성화 함수 h(x)의 값이 다음과 같이 표시되고 그래프로 나타내게 되면

[그림.5]

위의 [그림.5]와 같이 부드러운 곡선 형태로 그려지게 된다.

 

한가지 짚고 넘어갈 것은 계단함수와 시그모이드 함수 모두 비선형 함수라는 것이다.

선형함수는 층을 아무리 깊게해도 은닉층이 없는 네트워크로 표현되기 때문에 비선형함수이어야 한다.

 

 

* 참고 *

시그모이드 함수는 신경망 분야에서 오래전부터 사용되었으나 최근에는 ReLU함수를 주로 사용하고 있다.

[식.7] ReLU함수
[그림.6] ReLU함수

 

 

 

그럼 이제 신경망을 구현하여 보자.

[그림.7] 입력층에서 1층으로 신호 전달

위의 그림을 보면 편향과 입력값(x1, x2)을 이용하여 1층의 a1 값을 구하게 된다.

이와같은 방식으로 1층의 a2, a3를 구할 수 있을 것이고 여기서 구한 a값을 이용하여

그 다음 2층의 a1, a2값을 구할 수 있게 된다.

 

즉 위와 같이 a1이 표현될 수 있고 이 과정을 계속 진행하여 1층의 a원소들은 행렬 A로 아래와 같이 표현된다.

 

 

 

2층, 3층의 계산 과정은 아래의 그림을 참고하도록 하자.

[그림.8](좌) 1층에서 2층으로의 과정                                               [그림.9](우) 2층에서 출력층으로의 과정

### 입력층에서 1층으로까지의 과정
X = np.array([1.0, 0.5])
S1 = np.array([[0.1, 0.3, 0.5], [0.2, 0.4, 0.6]])
B1 = np.array([0.1, 0.2, 0.3])

print(W1.shape)
print(X.shape)
print(B1.shape)

A1 = np.dot(X, W1) + B1
Z1 = sigmoid(A1)

print(A1)
print(Z1)



### 1층에서 2층으로까지의 과정
W2 = np.array([[0.1, 0.4], [0.2, 0.5], [0.3, 0.6]])
B2 = np.array([0.1, 0.2])

print(Z1.shape)
print(W2.shape)
print(B2.shape)

A2 = np.dot(Z1, W2) + B2
Z2 = sigmoid(A2)



### 2층에서 출력층으로까지의 과정
def identity_function(x):   ## 여기서 identity 함수는 입력값을 그대로 출력하게 되는 함수
    return x

W3 = np.array([[0.1, 0.3], [0.2, 0.4]])
B3 = np.array([0.1, 0.2])

A3 = np.dot(Z2, W3) + B3
Y = identity_function(A3)

 

 

 

 

 

 

 

 

 

 

그 다음 등장하는 개념은 분류에서 사용되는 소프트맥스 함수(Softmax function) 이다.

 

[식.8] 소프트맥스 함수

위의 식에서 n은 출력층의 뉴런 수, y_k 는 그 중 k번째 출력임을 뜻하고 있다.

이를 그림으로 나타내면 아래와 같다.

[그림.10] 소프트맥스

이를 보면 소프트맥스 함수의 출력은 모든 입력 신호로부터 화살표를 받게 된다.

즉 출력층의 각 뉴런이 모든 입력신호에서 영향을 받는다는 것을 확인할 수 있다.

 

하지만 위의 소프트맥스 함수[식.8]은 지수함수로 이루어져 k의 값이 굉장히 커지게 되면 오버플로우가 발생하게 된다.

(컴퓨터는 수를 4바이트나 8바이트와 같이 크기가 유한한 데이터로 다루기에 표현할 수 있는 수의 범위가 한정적이다)

 

이를 확인하기 위해 프롬프트창에서 다음과 같이 실행시켜보자.

 

>>> a = np.array([1010, 1000, 990])
np.exp(a) / np.sum(np.exp(a))

 

이를 실행시키면

array([ nan, nan, nan])

과 같이 출력될 것이다.

 

그럼

위의 내용에 이어서

>>> c=np.max(a)

>>> a-c

를 입력하면

 

array([0, -10, -20])

이 출력되는 것을 확인할 수 있고 계속 이어서

 

>>> np.exp(a-c) / np.sum(np.exp(a-c))

를 입력하여 확인하여보면

array([ 9.99954600e-01,   4.53978686e-05,   2.06106005e-09  ])

의 값이 출력되는 것을 확인할 수 있다.

 

즉 간단하게 표현하여

def softmax(a):
    c=np.max(a)
    exp_a = np.exp(a-c)
    sum_exp_a = np.sum(exp_a)
    y = exp_a / sum_exp_a
    
    return y

 

위와 같이 구현할 수 있다.

 

소프트맥스 함수의 큰 특징은 이를 이용하여 소프트맥스 함수의 결과값을 확률로 해석할 수 있다는 것이다.

소프트맥스 함수의 결과값은 0에서 1.0 사이의 실수이다.

또한 출력의 총합이 1이 되고 출력값이 모든 입력값의 영향을 받기때문에 확률로 해석이 가능하다.

 

또한 소프트맥스 함수를 적용해도  y=exp(x)의 함수는 단조증가함수이기에

각 원소의 대소관계는 변하지 않는다.

 

 

반응형

'Deep Learning' 카테고리의 다른 글

선형회귀  (0) 2021.01.11
퍼셉트론(Perceptron)  (0) 2020.02.04

+ Recent posts