회전 이미지를 직사각형으로 Labeling하는 방법 - roLabelImg

프로그래밍 팁 2024. 2. 25. 23:13

 

 최신 인공지능 기술이 고도로 발전하여 뚜렷한 성과들이 눈앞에 펼쳐지고 있지만, 현업에서 최신 기술을 적용하는 것은 결코 쉽지 않습니다. 데이터 별로 각각의 특성이 존재하고, 그 데이터에 적합한 인공지능 기술이 반드시 최신 기술이어야만 하는 것은 아닙니다. 즉, SOTA 모델이 특정 데이터에서 가장 좋은 성능을 내지 못할 수도 있다는 것입니다. 다시 말해, 기업에서 수익을 목적으로 데이터에 AI를 적용하기 위해 가장 좋은 AI 모델을 찾는 것이 매우 중요하다는 것입니다.

 

 현업에서 사용하는 데이터를 가공하다 보니, 회전된 이미지가 어느 정도 기울어져 있는지 확인할 수 있는 방법을 찾아야 하는 상황이 생겼습니다. 관련 연구가 있는지 확인해보니 영상에서 기울어진 Object를  Bounding Box를 기울여서 표시하는 연구들이 진행되고 있는 것을 알게 되었습니다. 

 

 AI모델을 찾았으니 이 모델에서 학습할 수 있는 데이터를 만들어야겠지요? 이번 포스팅에서는 기울어진 물체를 Labeling할 수 있는 roLabelImg를 사용하는 방법에 대해 다루어보도록 하겠습니다.

 

https://github.com/cgvict/roLabelImg

 

GitHub - cgvict/roLabelImg: Label Rotated Rect On Images for training

Label Rotated Rect On Images for training. Contribute to cgvict/roLabelImg development by creating an account on GitHub.

github.com

 

 

1. python을 설치합니다. roLabelImg는 python 3.9 이하의 버전에서 구동이 가능합니다.

 

> conda create -n python3.9 -c conda-forge python=3.9

 

2. roLabelImg 프로그램 실행시 필수 패키지인 lxml과 pyqt를 설치합니다.

 

> conda install -c conda-forge lxml pyqt

 

2. git으로 roLabelImg를 다운로드합니다.

 

> git clone https://github.com/cgvict/roLabelImg

 

3. 설치된 pyqt에 포함된 pyrcc로 roLabelImg를 설정합니다. 자신이 설치한 pyqt버전이 5일 경우 pyrcc5를 실행합니다.

 

> pyrcc5 -o resources.py resources.qrc

 

 

4. roLabelImg를 실행합니다.

 

> python roLabelImg.py

 

위 과정대로 진행하셨다면 roLabelImg 프로그램이 실행되는 것을 확인하실 수 있습니다. 자신이 Label을 하고자 하는 이미지룰 불러봅니다.

 

 

 위성으로 찍은 공항 사진에서 비행기가 향하는 방향대로 Label을 진행해보겠습니다. 'Create Rotated RBox'를 클릭하여 아래와 같이 비행기를 전체적으로 Bounding합니다.

 

 

 마우스를 Drag하여 Bounding Box를 만드는 작업이 완료되면 아래와 같이 방금 만든 Label의 속성을 설정할 수 있습니다.

 

 

 방금 만든 Rotated RBox를 회전시켜 원하는 방향으로 Bounding Box를 돌려보겠습니다. 방금 만든 Bounding Box의 모서리 중 하나에 마우스를 이동시킨 다음 마우스 우측 버튼을 클릭후 드래그를 하면 Bounding Box가 회전하는 것을 확인하실 수 있습니다.

 

 

 아래 화면과 같이 Bounding Box가 비행기가 향하는 방향으로 회전된 것을 확인하실 수 있습니다.

 

 

 위와 같은 과정대로 이미지에 있는 3개의 비행기에 Rotated RBox를 모두 적용된 것을 확인하실 수 있습니다.

 

300x250

Windows 환경에서 MMDeploy로 TensorRT 구동(Python, C++)

프로그래밍 팁 2023. 10. 31. 13:31

 

 대다수의 AI 개발은 Linux 환경에서 이루어지다 보니 Linux환경에서 개발된 오픈소스 라이브러리를 Windows에서 사용하기 위해서는 Windows의 환경에 맞추어 설정을 해야하는 번거로움이 발생하곤 합니다. 사내 자체 개발이 목적이라면 Linux를 사용하는 것이 큰 문제가 되지 않을 수 있으나 고객사에서 Windows 환경에서의 사용을 원한다면 사실상 소스코드를 처음부터 설계한다는 각오를 해야 하기 때문에 개발에 많은 시간이 소요되는 안타까운 사례들이 있습니다.

 

 OpenMMLab에서 공개된 오픈소스 라이브러리인 MMCV는 Linux 환경은 물론, Windows에서도 프로그램이 구동될 수 있도록 지원을 해주고 있습니다. 덕분에 Linux 천하의 Vision AI 개발 환경에서 Windows 운영체제 환경에 맞추어 사용할 수 있는 AI 모델을 개발할 수 있어 개발자의 입장에서 보았을 때 막대한 개발 시간이 소요되는 경우를 막을 수 있습니다. 

 

 이번 포스팅에서는 MMCV로 개발된 딥러닝 모델을 MMDeploy로 경량화한 다음, 개발한 딥러닝 모델이 Windows 환경에서 보다 빠르게 구동될 수 있도록 만드는 과정에 대해 다루어보도록 하겠습니다.

 

※MMDeploy는 OpenMMLab에서 공개한 라이브러리(MMDetection, MMSegmentation 등)를 실제 동작환경에서 경량화 및 가속화를 도와주는 라이브러리입니다. MMDeploy에 대해 자세한 내용은 아래의 포스팅을 참조 바랍니다.

 

인공지능 모델 최적화 배포 라이브러리 - MMDeploy

연구 단계에서의 인공지능 모델 설계는 일반적인 환경 내에서 개발하고 성능을 분석할 때는 별 문제가 없다가도 막상 실제 특정 환경에서 적용을 시도해보려 하면 모델 구동 시간이 상당히 오

elecs.tistory.com

 

 1. 버전 맞추기

 

 2023년 4월 6일 OpenMMLab 2.0 방식의 최신 소스코드 구조가 적용된 MMDeploy 1.0 버전이 공개었습니다. 자신이 개발한 버전에 따라 해당 버전의 MMDeploy를 설정합니다. 본 예제에서는 MMSegmentation 0.30.0, MMDeploy 0.14.0 버전을 기준으로 작성하였습니다.

 

 

git clone https://github.com/open-mmlab/mmdeploy.git
git fetch --all --tags
git checkout tags/v0.14.0

 

2. MMDeploy 설치

 

 

Github를 통해 MMDeploy 소스코드 다운로드를 수행한 다음 MMDeploy을 사용하기 위해 필요한 pip 패키지들을 설치합니다.

pip install mmdeploy==0.14.0 mmdeploy-runtime==0.14.0 mmdeploy-runtime-gpu==0.14.0


3. MMPretrain(구 MMClassification) 설치

설치하시는 MMDeploy 버전이 1.x일 경우 MMPretrain을 설치합니다.

pip install mmpratrain


설치하시는 MMDeploy 버전이 0x.일 경우 MMClassification을 설치해주세요

pip install mmcls



4. ONNX 설치



MMDeploy는 MMCV로 개발된 딥러닝 모델을 ONNX로 변환한 다음 TensorRT로 변환하는 방식으로 2단계 변환을 수행합니다. 다음과 같이 ONNX를 설치합니다. 먼저 pip로 ONNX 패키지를 설치한 다음

 

pip install onnxruntime==1.8.1


다음으로 아래의 Github 사이트를 통해 onnxruntime 소스코드를 다운로드 받습니다.
https://github.com/microsoft/onnxruntime/releases/

 

Releases · microsoft/onnxruntime

ONNX Runtime: cross-platform, high performance ML inferencing and training accelerator - microsoft/onnxruntime

github.com




5. Nvidia 라이브러리 설치(CUDA, cuDNN, TensorRT)



자신의 환경에 맞는 버전의 CUDA, cuDNN, TensorRT를 설치합니다. cuDNN과 TensorRT 설치를 위해 Nvidia 계정이 필요합니다.
 
CUDA Toolkit >= 11.1
https://developer.nvidia.com/cuda-toolkit-archive/

 

CUDA Toolkit Archive

Previous releases of the CUDA Toolkit, GPU Computing SDK, documentation and developer drivers can be found using the links below. Please select the release you want from the list below, and be sure to check www.nvidia.com/drivers for more recent production

developer.nvidia.com



cuDNN >= 8.2.1.0
https://developer.nvidia.com/cudnn/

 

CUDA Deep Neural Network

cuDNN provides researchers and developers with high-performance GPU acceleration.

developer.nvidia.com



TensorRT >= 8.2.3.0
https://developer.nvidia.com/tensorrt-getting-started/

 

TensorRT - Get Started

Learn more about NVIDIA TensorRT and check out the latest codes and tutorials.

developer.nvidia.com


6. OpenCV 설치


Image Processing 과정에서 주로 사용되는 OpenCV 라이브러리를 설치합니다.
Python만 사용하실 예정이신 분은 pip를 통해 설치합니다.
pip install opencv-python

C++ 환경에서 TensorRT를 사용하고자 하시는 분은 OpenCV 공식 사이트에서 Runtime 라이브러리를 설치해줍니다. Windows 환경에서 설치하기 위해서는 아래의 사이트를 참조하여 설치해주시기 바랍니다.

https://hello-bryan.tistory.com/29

 

[OpenCV 설치] Windows OpenCv 설치

OpenCV 설치 Windows OpenCV OpenCV 공식 홈페이지로 갑니다. https://opencv.org 상단 메뉴의 RELEASES 를 클릭하고 원하는 버전의 Win Pack 을 클릭하여 다운로드 페이지로 이동합니다. 광고가 겁나많은 다운로드

hello-bryan.tistory.com



7. 환경변수 설정


위의 과정을 통해 설치하였던 onnxruntime, CUDA, cuDNN, TensorRT 라이브러리를 환경변수 Path에 등록합니다. 또한, CUDA_PATH의 환경변수 또한 다음과 같이 등록해주시기 바랍니다.



8. Pycuda 설치


Python에서 CUDA 병령 컴퓨팅 API를 수행할 수 있도록 해주는 pycuda를 설치합니다. 만약 설치 과정에서 실패하는 경우 위 6번 과정에서 설치한 라이브러리 환경변수 설정에서 잘못된 경우가 있을 수 있으므로 한 번 더 확인해보시기 바랍니다.

pip install pycuda

 


9. MMDeploy SDK 설치


Github에 공개된 MMDeploy의 release 라이브러리 탭에서 자신에게 맞는 버전을 선택 후 Assets에서 SDK를 다운로드 받습니다. 여기서는 "mmdeploy-0.14.0-windows-amd64-cuda11.3.zip"을 다운로드 합니다.

https://github.com/open-mmlab/mmdeploy/tags/

 

GitHub - open-mmlab/mmdeploy: OpenMMLab Model Deployment Framework

OpenMMLab Model Deployment Framework. Contribute to open-mmlab/mmdeploy development by creating an account on GitHub.

github.com


C++ 환경에서 사용하고자 하시는 경우 SDK를 폴더에 압축해제 하신 다음 Powershell을 실행하여 아래의 경로로 이동해주세요.
mmdeploy-0.14.0-windows-amd64-cuda11.3\example\cpp\build
위 경로로 이동한 다음 C++ SDK를 빌드합니다.

> cmake .. -DMMDeploy_DIR="mmdeploy-0.14.0-windows-amd64-cuda11.3\lib\cmake\mmdeploy" -DTENSORRT_DIR="TensorRT 설치 경로" -DONNXRUNTIME_DIR="onnxruntime 설치 경로" -DOpenCV_DIR="opencv\build\x64\vc15\lib"
> cmake --build . --config Release


10. Model 변환

지금까지 TensorRT를 사용하기 위해 구동 환경에서 MMDeploy를 적용하는 방법에 대해 설명드렸습니다. 이제 본격적으로 자신이 개발한 Model을 배포 환경에서 구동할 수 있도록 변환하는 단계를 진행해보도록 하겠습니다.

Python 소스코드를 아래와 같이 작성한 다음 실행합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from mmdeploy.apis import torch2onnx
from mmdeploy.apis .tensorrt import onnx2tensorrt
from mmdeploy.backend.sdk.expert_info import export2SDK
import os
 
img = '테스트하고자 하는 이미지 경로'
work_dir = 'TensorRT 변환 모델 저장 폴더 경로'
save_file = 'end2end.onnx'
deploy_cfg = 'mmdeploy/configs/mmseg/segmentation_tensorrt-fp16_static-512x512.py'
model_cfg = 'mmseg/자신이 학습한 모델의 설정.py'
model_checkpoint = '변환하고자 하는 모델.pth'
device = 'cuda'
 
# 1. convert model to IR(onnx)
torch2onnx(img, work_dir, save_file, deploy_cfg, model_cfg, model_checkpoint, device)
 
# 2. convert IR to tensorrt
onnx_model = os.path.join(work_dir, save_file)
save_file = 'end2end.engine'
model_id = 0
onnx2tensorrt(work_dir, save_file, model_id, deploy_cfg, onnx_model, device)
 
# 3. extract pipeline info for sdk use (dump-info)
export2SDK(deploy_cfg, model_cfg, work_dir, pth=model_checkpoint, device=device)
cs


위의 소스코드를 실행하시면 work_dir 폴더에 다음과 같은 파일들이 생성된 것을 확인하실 수 있습니다.

deploy.json
detail.json
end2end.engine
end2end.onnx
pipeline.json


11. Inference 코드 구현


이제 여러분들이 개발한 딥러닝 모델이 TensorRT로 변환된 것을 확인하였습니다. TensorRT 최적화 모델을 아래와 같이 실행할 수 있습니다.

- python
> python MMDEPLOY/mmdeploy/tools/deploy.py MMDEPLOY/mmdeploy/configs/mmseg/segmentation_tensorrt-int8_static-512x512.py MMSEGMENTATION/configs/모델 설정 파일.py 학습한 모델.engine "데모 이미지.jpg" --device cuda:0

> python MMDEPLOY/demo/python/image_segmentation.py cuda "work_dir 경로" "데모이미지 경로.jpg"

 

 

- C++
> MMDeployDIR/example/cpp/build/release/image_segmentation.exe cuda "work_dir 경로" "데모이미지 경로.jpg"

이제 여러분들도 MMDeploy를 통해 경량화돤 모델이 배포 환경에 맞추어 실행 속도가 굉장히 향상된 것을 확인하실 수 있습니다.


- 참고자료

https://mmdeploy.readthedocs.io/en/v0.14.0/get_started.html#installation 

 

Get Started — mmdeploy 0.14.0 documentation

Get Started MMDeploy provides useful tools for deploying OpenMMLab models to various platforms and devices. With the help of them, you can not only do model deployment using our pre-defined pipelines but also customize your own deployment pipeline. Introdu

mmdeploy.readthedocs.io

https://mmdeploy.readthedocs.io/en/v0.14.0/02-how-to-run/prebuilt_package_windows.html

 

How to use prebuilt package on Windows10 — mmdeploy 0.14.0 documentation

Docs > How to use prebuilt package on Windows10 以中文阅读 Shortcuts

mmdeploy.readthedocs.io

 

300x250

인공지능 모델 최적화 배포 라이브러리 - MMDeploy

프로그래밍 팁 2023. 4. 8. 22:41

 

 연구 단계에서의 인공지능 모델 설계는 일반적인 환경 내에서 개발하고 성능을 분석할 때는 별 문제가 없다가도 막상 실제 특정 환경에서 적용을 시도해보려 하면 모델 구동 시간이 상당히 오래 걸리는 경우가 있습니다. 이는 개발 단계에서 아무리 좋은 GPU를 사용한다 하더라도 해당 GPU에 모델이 최적화 되어있지 않은 경우 GPU의 성능 대비 좋은 성능을 기대하기 어려운 현상이 있습니다.

 개발 단계에서 만들어지는 모델은 다양한 환경에서도 실행될 수 있는 소스코드로 배포되어 어떤 환경에서도 구동될 수 있도록 할 수 있습니다. Nvidia에서 공개한 TensorRT와 같은 모델 최적화 라이브러리를 사용하면 특정 환경의 GPU에서 모델의 Inference 속도가 향상되는 것을 확인할 수 있습니다.

 

 

 그러므로 설계가 완료된 모델을 배포할 때, 모델이 배포되는 환경에서 최적화되어 좋은 성능을 발휘할 수 있도록 관리하는 과정 또한 매우 중요합니다.  OpenMMLab에서 공개한 MMDeploy는 지금까지 OpenMMLab에서 공개한 MMDetection, MMSegmentation등과 같은 딥러닝 라이브러리를 특정 환경에서 최적화 설계되어 배포할 수 있도록 해주는 라이브러리입니다. 

 

 

 MMDeploy를 사용하여 MMCV로 설계된 모델들을 범용 딥러닝 모델인 ONNX로 변환하여 다른 딥러닝 라이브러리로 변환하여 사용하거나 TensorRT를 사용해 자신이 사용하고자 하는 GPU에 모델을 최적화하여 사용할 수도 있습니다.   

 

 MMDeploy는 아래의 Github 사이트를 통해 소스코드를 다운로드 받으실 수 있습니다.  

 

https://github.com/open-mmlab/mmdeploy

 

GitHub - open-mmlab/mmdeploy: OpenMMLab Model Deployment Framework

OpenMMLab Model Deployment Framework. Contribute to open-mmlab/mmdeploy development by creating an account on GitHub.

github.com

 

 Github 공식 사이트를 통해 자신이 구현하고자 하는 환경의 운영체제(Linux, Windows, macOS 등)에서 직접 설치하실 수 있습니다.

 다만, 직접 설치하는 과정이 상당히 복잡하기 때문에 만약 Linux 환경에서 사용하고자 하시는 분은 Docker를 사용하여 설치하시는 것을 적극적으로 권장드립니다. Ubuntu에서 Docker를 설치하는 방법은 아래의 사이트를 참조해주시기 바랍니다.

 

https://dongle94.github.io/docker/docker-ubuntu-install/

 

[Docker] Ubuntu에 Docker 설치하기

리눅스 OS 중 우분투 OS에서 도커(Docker) 프로그램을 설치하는 방법을 알아본다.

dongle94.github.io

 

 Docker 환경에서 GPU 버전의 MMDeploy 설치를 시도하면 아래와 같은 에러가 발생하는 경우가 있습니다.

 

 docker: Error response from daemon: could not select device driver "" with capabilities: [gpu].

 

 이 경우 아래의 블로그에서 소개하는 방법과 같이 nvidia-container-toolkit을 설치해주면 쉽게 해결하실 수 있습니다. 

 

# Add the package repositories
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list

sudo apt-get update && sudo apt-get install -y nvidia-container-toolkit
sudo systemctl restart docker

 

 

 

https://bluecolorsky.tistory.com/110

 

[정보] docker: Error response from daemon: could not select device driver with capabilities: [[gpu]] 문제 해결하기

도커를 사용하다 보면 다양한 문제에 맞닥뜨리게 된다. 해결하기 쉬운 문제부터 어려운 문제까지 수많은 문제들이 존재하는데 사용할때마다 항상 다른 오류가 발생하여 문제가 발생할때마다

bluecolorsky.tistory.com

 

300x250

MMCV에서 직접 만든 데이터셋 학습 시키기(COCO, Pascal VOC Custom Dataset 만들기)

프로그래밍 팁 2023. 3. 27. 22:58

 

 제가 인공지능에 대해 한창 공부를 할때마다 가장 아쉬웠던 점 중 하나는 자신이 구현하고자 하는 모델에 적합한 데이터를 구하는 것이 어려웠던 것이었습니다. 단지 사람을 감지해내는 기술이 필요한 것이라면 SOTA 알고리즘을 찾은 다음 고성능의 기학습된 모델을 적용하는 것이 가장 좋고 실제로도 제가 다시 재학습 해서 만든 모델보다도 성능이 뛰어나기 때문에 굳이 데이터셋을 직접 만드는 고생을 할 이유가 없기도 합니다.

 

 그러나 내가 구현하고자 하는 물체가 기존의 모델들에 구현되어 있지 않는 경우에는 어쩔수없이 데이터를 수집하여 나만의 데이터셋을 만들어야만합니다. 그러나 기존의 모델들의 성능에 준하는 새로운 모델을 만들기 위해서는 무려 수십만장의 데이터를 수집해야 하는데 이를 개인이 직접 수집하기에는 시간과 비용이 만만치 않습니다. 

 

 그렇다면, 내가 원하는 데이터셋을 만들어 이를 테스트해 볼 수 있는 방법은 없는걸까요? 이번 포스팅에서는 Custom Dataset을 본인이 직접 제작하는 방법과 이 데이터셋을 사용하여 MMCV 기반 딥러닝 모델(MMDetection, MMSegmentation)에서 Custom Dataset을 학습해보고자 합니다.

 

 

1. 데이터 수집 및 Labeling

 원하는 모델 설계에 앞서 자신이 감지하고자 하는 물체가 실제 학습이 가능한지 우선 확인해 볼 필요가 있습니다. 우선 자신이 학습하고자 하는 이미지를 100장 정도 수집한 후 Labeling 작업을 수행합니다. 최근에는 Labeling 작업을 쉽고 효율적으로 수행할 수 있는 Tool들이 많아졌지만 Tutorial 목적으로 작업을 하고자 하시는 분들께서는 추가 비용을 요구하지 않는 오픈소스인 LableMe를 사용해보는 것을 추천 드립니다.

 

 LabelMe를 사용하는 방법에 대해 제가 이전에 정리하였던 자료가 있으니 아래의 포스팅을 참조해주시길 바랍니다.

https://elecs.tistory.com/430

 

Lableme로 Coco Dataset과 VOC Dataset 만들기

고성능의 인공지능을 만들기 위한 가장 중요한 작업 중 하나는 최대한 많은 양질의 데이터를 확보하는 것입니다. 상상을 뛰어넘는 인공지능의 놀라운 발전을 보았을 때 마치 AI를 연구하는 사람

elecs.tistory.com

2. 보편적으로 사용되는 Custom Dataset 양식으로 변환

 

 지금까지 공개된 인공지능 모델들의 대부분은 많은 사람들이 자신들이 개발한 소스코드를 쉽게 사용할 수 있도록 설계되어 있습니다. 특히 기존에 공개된 COCO 데이터셋과 PascalVOC는 대중적으로 공개된 퍼블릭 데이터셋으로 누구가 쉽게 접할 수 있어 인공지능에 입문하는 사람들이 처음으로 사용하게 되는 데이터셋이기도 합니다. 

 

 위에서 언급한 제 이전의 포스팅 자료에서 소개드렸던 LabelMe로 Labeling 작업을 수행한 다음 COCO 혹은 PascalVOC 데이터셋 양식으로 변경하는 내용에 대해 다루었으니 해당 부분을 참조해주시길 바랍니다.

 

3. MMCV에서 사용하기

 

 위의 과정을 통해 Custom 데이터셋을 만드셨다면 이를 가지고 OpenMMLab에서 제작한 MMCV에서 바로 사용하실 수 있습니다. LableMe를 통해 제작한 Custom Dataset으로 MMDetection과 MMSegmentation에서의 동작을 확인하였습니다. 각 프로젝트에 바로 사용할 수 있는 데이터셋 양식은 다음과 같습니다. 나머지 데이터셋 양식의 경우 추가적인 설정을 해주시면 사용하실 수 있습니다.

 

MMDetection: COCO Dataset

 

 LabelMe를 기준으로 Custom Dataset을 Coco 방식으로 변활할 때 Label을 수행한 Json 파일을 Train 용도와 Test 용도로 구분한 다음 각 용도별 Dataset을 Coco로 변환하면 Train 그리고 Test 수행을 위한 Annotation.json 파일을 생성할 수 있습니다. 

 위의 과정을 통해 생성된 Coco Dataset은 MMDetection에서 제공되는 config 파일에 있는 기본 dataset을 수정하여 자신의 환경에 맞도록 고쳐주시면 바로 사용하실 수 있습니다. 

 

/mmdetection/configs/_base_/datasets/coco*.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# dataset settings
dataset_type = 'CocoDataset'
data_root = 'data/coco/' #Custon Coco Dataset의 폴더 위치
....
#Train, Val, Test 데이터의 Json 및 이미지 파일 경로 
data = dict(
    samples_per_gpu=2,
    workers_per_gpu=2,
    train=dict(
        type=dataset_type,
        ann_file=data_root + 'annotations/train.json',
        img_prefix=data_root + 'train/',
        pipeline=train_pipeline),
    val=dict(
        type=dataset_type,
        ann_file=data_root + 'annotations/val.json',
        img_prefix=data_root + 'val/',
        pipeline=test_pipeline),
    test=dict(
        type=dataset_type,
        ann_file=data_root + 'annotations/test.json',
        img_prefix=data_root + 'test/',
        pipeline=test_pipeline))
....
cs

 

MMSegmentation: PascalVOC

 

 LableMe에서 labelme2voc로 변환한 데이터들은 MMSegmentation에서 바로 사용하실 수 있습니다. 여기서 만들어진 Segmentation 이미지들 중에서 train.txt, val.txt, test.txt로 사용하고자 하는 파일들의 제목들을 작성해주시고 아래와 같이 Custom Dataset으로 구성하실 수 있습니다.

 

/mmsegmentation/configs/_base_/datasets/custom_voc12.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# dataset settings
dataset_type = 'PascalVOCDataset'
data_root = 'data/VOCdevkit/VOC2012' # Custom Voc 데이터셋의 폴더 위치
img_norm_cfg = dict(
    mean=[123.675116.28103.53], std=[58.39557.1257.375], to_rgb=True)
crop_size = (512512)
train_pipeline = [
    dict(type='LoadImageFromFile'),
    dict(type='LoadAnnotations'),
    dict(type='Resize', img_scale=(2048512), ratio_range=(0.52.0)),
    dict(type='RandomCrop', crop_size=crop_size, cat_max_ratio=0.75),
    dict(type='RandomFlip', prob=0.5),
    dict(type='PhotoMetricDistortion'),
    dict(type='Normalize'**img_norm_cfg),
    dict(type='Pad', size=crop_size, pad_val=0, seg_pad_val=255),
    dict(type='DefaultFormatBundle'),
    dict(type='Collect', keys=['img''gt_semantic_seg']),
]
test_pipeline = [
    dict(type='LoadImageFromFile'),
    dict(
        type='MultiScaleFlipAug',
        img_scale=(2048512),
        # img_ratios=[0.5, 0.75, 1.0, 1.25, 1.5, 1.75],
        flip=False,
        transforms=[
            dict(type='Resize', keep_ratio=True),
            dict(type='RandomFlip'),
            dict(type='Normalize'**img_norm_cfg),
            dict(type='ImageToTensor', keys=['img']),
            dict(type='Collect', keys=['img']),
        ])
]
data = dict(
    samples_per_gpu=4,
    workers_per_gpu=4,
    train=dict(
        type=dataset_type,
        data_root=data_root,
        img_dir='JPEGImages',
        ann_dir='SegmentationClassPNG',
        split='train.txt',
        pipeline=train_pipeline),
    val=dict(
        type=dataset_type,
        data_root=data_root,
        img_dir='JPEGImages',
        ann_dir='SegmentationClassPNG',
        split='val.txt',
        pipeline=test_pipeline),
    test=dict(
        type=dataset_type,
        data_root=data_root,
        img_dir='JPEGImages',
        ann_dir='SegmentationClassPNG',
        split='test.txt',
        pipeline=test_pipeline))
cs

 

300x250

복합 이벤트 처리 라이브러리 Esper를 VScode에서 실행해보기

프로그래밍 팁 2022. 10. 9. 11:20

 

 업무 목적으로 EsperTech사의 Esper를 개발하게 되면서 오랜만에 Java를 사용하게 되었습니다. 학생때 Android 프로그래밍을 하면서 Java를 애용했던 기억이 있고, 그 당시 안드로이드 애플리케이션 개발을 열정적으로 했던 경험이 생생합니다.

 어느샌가 안드로이드 앱 개발 환경은 Kotlin으로 재편되면서 자바의 입지는 예전보다 줄어든 경향이 있어보입니다. 그러나 운영체제와 상관 없이 자바 가상머신(JVM)만 설치되어 있으면 그 어떤 기기에서도 Java를 사용할 수 있다는 매력 만큼은 무시할 수 없기에 Java는 2022년 현재에도 애용되는 언어입니다. Espertech의 Esper는 Java로 설계되어 있으며 그 덕에 운영체제를 가리지 않고 손쉽게 사용할 수 있다는 점은 개발자의 관점에서는 편하다고 할 수 있지요.

 Espertech사의 esper는 복합 이벤트 처리(Complex Event Processing)를 위한 라이브러리로, 영상, 센서 등에서 복합적으로 발생하는 데이터를 수신하여 이벤트가 발생하였을 때, 각 센서에서 수신되는 데이터 값을 esper가 수신하였을 때 각 센서의 값들을 복합적으로 판단하여 해당 이벤트의 속성을 분석하여 이를 올바르게 판단하는 것을 목표료 합니다.

 예를 들어, 공사 현장에 카메라와 마이크가 설치되어 있을 때, 현장에서 작업자가 쓰러지는 모습과 그 과정에서 발생하는 소음들을 카메라와 마이크가 해당 영상 및 소리를 데이터화 하여 esper에 전달하였을 때, esper는 이 이벤트를 위급한 상황이라 판단하고 이를 조치하기 위한 요청을 발생하는 것을 목표로 한다고 생각하시면 되겠습니다.

 

 

 복합 이벤트 처리 라이브러리인 esper를 Visual Studio code에서 실행해보도록 합니다. 먼저 esper 공식사이트 혹은 공식 github 사이트를 통해 esper 라이브러리를 다운로드 받습니다.

https://www.espertech.com/esper/esper-downloads/

 

Downloads - EsperTech

Esper is distributed in several packaged formats for your convenience. […]

www.espertech.com

 

https://github.com/espertechinc/esper

 

GitHub - espertechinc/esper: Esper Complex Event Processing, Streaming SQL and Event Series Analysis

Esper Complex Event Processing, Streaming SQL and Event Series Analysis - GitHub - espertechinc/esper: Esper Complex Event Processing, Streaming SQL and Event Series Analysis

github.com

 

 다음으로 자신이 esper를 사용하고자 하는 환경에 맞추어 Java, Maven, Visual Studio Code를 설치합니다.

 VS Code를 설치한 다음 확장 탭에서 Debugger for Java를 설치해주세요.

 

 

 이어서 EsperEPL 확장 프로그램을 추가로 설치합니다.

 

 

 다음으로 설정 탭에서 Maven for Java 탭을 선택한 후 Maven > Executable: Path 메뉴에서 설치된 maven의 bin 경로를 입력해줍니다.

 

 

 다음으로 esper 소스의 example 폴더를 엽니다.

 

 

 이제 Example 소스코드들을 컴파일 해봅니다. test모드를 적용하기 위해 탐색기의 maven 탭에서 Lifecycle > test-compile 버튼을 클릭하여 아래와 같이 예제 코드가 컴파일 되는 것을 확인합니다.

 

 

 이제 컴파일된 esper 예제 코드를 실행해봅니다. Ctrl+F5를 누르면 실행하고자 하는 메인함수를 선택할 수 있으며 선택된 예제 코드가 실행되는 것을 확인하실 수 있습니다.

 

300x250

VScode 확장 원격 설치가 진행되지 않을때 직접 설치하기

프로그래밍 팁 2022. 8. 4. 23:22

 

 Visual Studio code를 사용함에 있어 가장 큰 강점은 확장(Extension) 기능을 설치하여 단지 소스코드를 열람하거나 수정하는 것에서 끝나는 것이 아니라 C++, Java, Python 등 자신이 사용하고자 하는 언어를 컴파일 하고 실행까지 직접 해볼 수 있다는 점입니다.

 

 그렇기에 저의 경우 프로그래밍을 하고자 할 때 해당 환경이 VScode에서 지원이 되는지를 먼저 확인하고 결정하는데 중요한 역할을 합니다. 심지어는 SSH를 지원하여 원격 환경에 있는 서버에 접속해 마치 자신의 컴퓨터에서 작업을 하는 것과 같이 편하게 프로그래밍을 진행할 수 있다는 점이 좋습니다.

 

 특히 SSH 환경에서도 확장 기능을 사용할 수 있어 SSH 접속을 통해 원격 서버에 확장을 설치하면 Local에서 사용하는 것과 같이 프로그래밍을 할 수 있는데요. 이번에는 희안하게도 설정이 제대로 되지 않았는지 원격 서버에 확장 설치를 시도하려 하였으나 아래와 같은 에러가 발생하며 더이상 진행이 되지 않는 현상이 발생했습니다.

 

 

This extension is disabled in this workspace because it is defined to run in the Remote Extension Host.

이 확장은 원격 확장 호스트에서 실행되도록 정의되었기 때문에 이 작업 영역에서 사용하지 않도록 설정되어 있습니다.

 

 

 

 정황상 모종의 사유로 인하여 원격 컴퓨터에 vscode 확장 설치가 진행되지 못한 것으로 추측됩니다. 이 경우 확장 프로그램을 서버에 직접 설치하여 문제를 해결해봅니다.

 

 먼저 자신이 설치하고자 하는 vscode 확장 프로그램을 visual studio makret place에서 검색하신 다음 직접 다운로드 받도록 합니다. 

 

 

Visual Studio Marketplace

Extensions for Visual Studio family of products on Visual Studio Marketplace

marketplace.visualstudio.com

 

 위 링크의 웹사이트에 접속하신 다음 Visual Studio Code 탭을 선택한 다음 검색창에 자신이 원하는 확장 프로그램의 이름을 입력후 검색합니다.

 

 

 원하시는 확장 프로그램을 찾으신 다음 해당 페이지 우측에서 'Download Extension'을 클릭하여 확장 프로그램을 다운로드 받습니다.

 

 

  다운로드를 완료하시면 확장명 .vsix인 설치 파일이 다운로드 된 것을 확인하실 수 있습니다.

  다시 vscode를 실행한 다음  소스코드가 저장되어 있는 서버에 ssh 원격 접속하여 다운로드 받은 .vsix 파일을 서버에 전송하신 다음 vscode의 extension 탭에서 아래의 그림과 같이 클릭한 다음 'install from VSIX...' 버튼을 클릭합니다 

 

 

 그 다음 .vsix를 저장한 폴더의 위치로 이동한 다음 .vsix를 선택하여 설치를 진행하면 서버에 확장 프로그램이 설치된 것을 확인하실 수 있습니다.

 

300x250

Anaconda 사설 로컬 저장소 채널 만들기

프로그래밍 팁 2022. 7. 27. 23:07

 지금 이순간에도 등장하는 새로운 인공지능 알고리즘을 테스트해보고자 라이브러리를 맞추어서 설치해야 하는데 라이브러리 종속성 충돌로 인해 상당히 골치아픈 일이 많을 것입니다. 이 때 라이브러리를 가상 환경에 만들어 제공하는 Anaconda는 굳이 컴퓨터를 리셋하지 않더라도 간단하게 독립된 가상 환경에서 다른 인공지능 알고리즘의 종속성에 구애받지 않아도 되기 때문에 인공지능 라이브러리 관리 프로그램으로 널리 사용되고 있습니다.

 Anaconda는 딥러닝에 필요한 라이브러리를 인터넷을 통해 제공하고 있습니다. 특히 conda-forge 채널은 상당히 많은 라이브러리들을 제공하고 있어 사실상 Anaconda에서 가장 많이 사용되는 저장소이기도 합니다.

 

 그러나 pytorch와 같이 가장 주요한 딥러닝 라이브러리의 경우 용량이 큰데다가 다운로드 받는데에만 상당한 시간이 소요됩니다. 또한 기업 혹은 국가 기관과 같이 보안을 요구하는 곳에서 혹여나 해커에 의해 악성코드가 숨겨진 라이브러리가 유입될 경우 무형 자산의 심각한 손실이 발생하기도 합니다.

 이러한 환경에서는 자주 사용되는 라이브러리를 로컬 공간에 저장해두고 사용하는 방법이 요구됩니다. 같은 망 내에 있는 컴퓨터를 통해 자료를 받기 때문에 다운로드 속도 향상은 물론 검증된 자료만 사설망 내에 활용함으로서 외부로부터 악성 공격의 유입을 막을 수 있습니다.

 이러한 환경을 만들기 위해 Anaconda의 라이브러리 채널을 저장하여 사설 저장소를 구축하는지에 대해 알아보도록 하겠습니다.

 

기본 개념

 

Python - 프로그래밍 언어 中 하나로서 PIP(파이피)를 통해 수많은 라이브러리를 사용할 수 있습니다.

PIP - Python의 라이브러리 설치를 도와주는 패키지 인스톨러로서 명령어만으로 저장소에서 다운로드 하여 설치할 수 있습니다.

ANACONDA - PIP의 최대 단점인 root 호환성 문제 및 서로 다른 버전의 패키지를 요구하는 인공지능 알고리즘들을 별개의 가상환경을 생성하여 관리해주는 사설 패키지 저장소입니다. 단지 원하는 환경을 명령어로 부르는 것 만으로 다른 라이브러리와의 의존성 충돌을 피하는 것 만으로도 개발자들의 생산성 향상에 큰 기여를 하고 있습니다.

CHANNEL - Anaconda의 저장소를 이루는 기본 단위로서, 자신이 원하는 저장소를 선택하여 패키지를 설치할 수 있습니다.

conda-forge - Anaconda의 channel중 하나로서 상당히 많은 패키지들을 제공합니다. 패키지를 설치하고자 할 때는 다음과 같은 명령어를 사용합니다.

 

$ conda install -c conda-forge 패키지명

 

위 명령어에서 -c는 원하는 채널을 설정하는 명령어로 conda-forge 채널에 있는 패키지를 받아오겠다는 명령어입니다.

 

 지금까지 Anaconda 및 채널의 개념에 대해 설명드렸습니다.  이제부터 우리가 직접 Anaconda의 채널을 만들고 이를 외부에 공개하는 방법에 대해 살펴보도록 하겠습니다.

 

1. Channel 저장소를 미러링 하여 가져오기

 자신만을 위한 Channel 저장소를 만들기 위해 저장소에 다운받았던 나의 환경에 있는 패키지를 그대로 사용하는 방법이 있습니다만, 다른 환경에서 설치할 때 의존성 문제가 발생할 수 있으므로 인터넷 상에 공개되어 있는 Channel 저장소를 미러링하여 가져오는 방법에 대해 설명 드리겠습니다.

 

 먼저 Channel 저장소의 패키지들을 로컬 저장소로 복사해주는 패키지인 conda-mirror를 설치합니다.

$ pip install conda-mirror

혹은

$ conda install -c conda-forge conda-mirror

혹은

$ git clone https://github.com/conda-incubator/conda-mirror

 

 다음으로 로컬 저장소로 복사하고자 하는 채널을 미러링 합니다. 이를 위해 사용되는 conda-mirror의 사용 옵션에에 대해 간단히 살펴보도록 합시다.

-h, --help
conda-mirror의 옵션들을 확인하실 수 있습니다.
--upstream-channel UPSTREAM_CHANNEL
로컬 저장소에 복사하고자 하는 채널명 혹은 주소를 입력합니다.
--target-directory TARGET_DIRECTORY
upstream channel에서 미러링할 로컬 저장소의 경로를 설정합니다.
--temp-directory TEMP_DIRECTORY
로컬 저장소의 경로에 저장하기 전 임시로 저장하고자 하는 폴더 경로를 입력합니다.
Windows의 경우 사용자 계정의 Temp 내에 임의로 생성됩니다. 이 경우 폴더 관리가 어려울 수 있습니다.
--platform PLATFORM
미러링 하고자 하는 운영체제의 종류를 선택합니다. {'linux-64', 'linux-32','osx-64', 'win-32', 'win-64'}
-D, --include-depends
받고자 하는 패키지의 조건을 설정할 수 있습니다. 일종의 화의트리스트 기능을 합니다.
--config CONFIG
blacklist 및 whitelist를 설정한 yaml 파일을 불러옵니다.
--num-threads NUM_THREADS
다운로드를 위해 사용할 스레드의 갯수를 입력합니다. 0을 입력할 경우 사용가능한 모든 스레드를 설정합니다.
--minimum-free-space MINIMUM_FREE_SPACE
로컬 저장소의 용량이 제한되어있을 경우 해당 용량이 초과하지 않도록 mb 단위로 설정합니다.
-k, --insecure
SSL 에러 이슈로 에러가 발생할 경우 SSL을 무시하고 사용합니다.

만약 conda-forge에서 linux 64비트 라이브러리 전체를 다운로드 받고자 한다면 다음과 같이 입력합니다.

 

$ conda-mirror --upstream-channel conda-forge --target-directory local_mirror --platform linux-64

 

 conda-forge는 Python의 거의 모든 패키지를 제공한다 해도 무방할 만큼 모두 미러링을 하게 될 경우 상당한 용량을 감당해야 하는 부담감이 있습니다. 우리들이 사용하고자 하는 라이브러리 패키지가 일부이기에 용량만 차지하는 패키지까지 저장해야할 이유가 없지요. 이를 위해 config를 통해 blacklist와 whitelist를 설정하여 원하는 패키지만 설치할 수 있습니다. blacklist란 다운로드를 원치 않는 패키지가 있는 경우 이를 특정고자 할 때 사용하며, whitelist는 특정한 패키지만 다운로드 하고자 할 때 해당 패키지의 상세 내용을 적어 이외의 패키지를 받지 않기 위해 사용합니다. 이를 위해  config에 적용하고자 하는 yaml 파일을 생성합니다.

 

 만약 여러분들이 botocore라는 라이브러리만 얻고자 하고 특정 버전 및 사용하고자 하는 파이썬 버전을 한정하고자 한다면 다음과 같이 내용을 입력합니다.

blacklist:
- name: "*"
whitelist:
- name: botocore
  version: 1.4.10
  build: py34_0

 

 반면, 특정 패키지중 패키지명에 'agpl'이라는 이름이 들어간 패키지를 제외한 모든 패키지를 설치하고자 한다면 다음과 같은 명령어를 입력합니다.

blacklist:
- license: "*agpl*"

 

 다음으로 예제를 실행해봅시다. 이 예제에서는 특정 버전의 git 패키지만 다운로드할 것입니다.

example.yaml

blacklist:
    - name: "*"
whitelist:
  - name: git
    version: ">=2.32"

 

 다음으로 config를 적용하여 원하는 라이브러리를 conda-forge로부터 가져옵니다.

$ conda-mirror --upstream-channel conda-forge --target-directory 로컬폴더 --temp-directory 임시폴더 --platform win-64 --config .\example.yaml

 

  이 명령어를 실행하면 아래의 그림과 같이 2.32버전 이상의 git 라이브러리 패키지가 다운로도 된 것을 확인하실 수 있습니다.

 

2. 사설 로컬 저장소 채널 지정하기

  이번에는 자신이 갖고 있는 패키지 라이브러리를 사설 저장소 채널로 만드는 작업을 진행합니다. 먼저 conda-build 패키지를 설치합니다.

$ conda install conda-build

 

 로컬 저장소 채널로 만들고자 하는 폴더가 들어있는 디렉토리에 위치한 다음 다음과 같은 명령어를 입력합니다.

 

$ conda index 채널명

 

 실행 후 잠시 기다리면 다음과 같이 채널 디랙토리 내에 index 웹페이지 폴더가 생성된 것을 확인하실 수 있습니다.

 

 

3. 웹서버 구축 및 등록하기

 

 custom 채널 디렉토리에 생성된 index 웹페이지를 열면 다음과 같이 미러링 하였던 저장소 목록이 나타나는 것을 확인하실 수 있습니다.

 

 다음으로 외부에서 미러 서버에 접속할 수 있도록 웹 서버를 설치합니다. 웹서버는 Apache를 보편적으로 사용되고 있습니다.

 자신의 운영체제에 맞는 Apache를 설치하여 웹서버를 구축하도록 합니다.

 

https://mainia.tistory.com/5572

 

윈도우10 아파치 웹 서버 설치하기

아파치 Apache 는 아파치 재단에서 만든 웹 서버 입니다. 윈도우뿐만 아니라 Unix, Linux 등의 운영체제에서 쉽게 운영할 수 있도록 만든 소프트웨어 입니다. 웹 어플리케이션을 만들기 위한 가장 기

mainia.tistory.com

https://askforyou.tistory.com/120

 

[linux] 우분투(ubuntu) 아파치(apache) 웹서버 설치 구축(ufw 방화벽 설정)

아파치 웹서버 설치하기 1. 패키지 목록 업데이트 $ sudo apt-get update 2. 아파치 설치 $ sudo apt-get install apache2 3. 설치 진행 화면에서 "y" 입력 후 진행 3. 설치 완료 후 확인 $ sudo service apache2..

askforyou.tistory.com

 

 Apache httpd를 다운로드하신 후 압축을 풀어 원하는 위치에 설치를 진행합니다. 그 다음 httpd.conf 파일을 열어 4군데를 수정하여 자신의 환경에 맞추어 설정합니다. 

 

 

 위의 절차대로 수행한 다음 설정한 주소를 입력하면 Anaconda Repository 사이트 웹페이지가 나타나는것을 확인하실 수 있습니다.

 

 

4. 구축된 Anaconda custom 저장소 접속하기

 지금까지의 과정을 통해 만든 Anaconda custom 저장소의 Library 패키지를 다운로드해봅니다.

 

> conda install -c http://127.0.0.1/custom-cf git

 

 

 축하합니다! 여러분들만의 Anaconda custom 사설 저장소가 완성되었습니다.

 

 

 

 

 

300x250

IP 주소를 통해 위치 정보 얻기(IP-API.com)

프로그래밍 팁 2016. 11. 9. 01:54

 보통 위치 정보를 얻는 방법으로 GPS를 통해 위도 및 경도 값을 구하는 방법과 연결된 Network 정보를 통해 현위치를 짐작해 보는 방법이 있습니다.

 GPS를 사용할 때 현위치를 비교적 정확하게 알 수 있으나 실내에 있을 경우 GPS 위성 신호를 수신하는 데에 장애요소가 발생하여 이를 활용하기 어려운 경우가 있습니다. 이 경우 Network 정보를 통해 위치 정보를 얻는 방법이 있습니다. 비록 Network 방식을 통하여 얻게 되는 위치 정보는 GPS에 비하면 신뢰하기 어려우나 GPS를 사용하지 못하는 상황일 경우 위치 정보를 얻는 경우에 쓸 만하다고 볼 수 있겠습니다.


 구글 지도를 통해 자신이 알아보고자 하는 위치의 위도 및 경도를 얻는 것은 쉽습니다. 그러나 위치정보 서비스를 제공해야 하는 프로그램의 경우 GPS와 Network를 통해 위치 정보를 얻게 되는데 이를 위해 위치 정보를 얻을 수 있는 방법을 모색해야 할 필요가 있습니다. Network가 연결되어 인터넷을 할 수 있는 환경의 경우 아래 사이트를 접속하면 위치 정보를 얻을 수 있습니다.


http://ip-api.com/



 위 사이트를 이용할 경우 위와 같이 기기가 Network에 접속하기 위해 사용중인 IP주소를 검색함으로서 위와 같은 정보를 얻을 수 있습니다.


 IP-API.com에서는 애플리케이션에서 위 정보를 사용자가 쉽게 이용할 수 있도록 XML과 JSON등을 통해 가공하여 정보를 제공합니다. 프로그램 개발자 자신의 입맛에 맞는 방식을 사용하여 위치 정보를 얻는 것이 다소 쉬워질 것입니다.


XML

http://ip-api.com/xml


JSON

http://ip-api.com/json


CSV

http://ip-api.com/csv


new line

http://ip-api.com/line


 위 주소를 입력하자 마자 사용자의 기기에서 사용중인 IP 주소를 기준으로 위치정보를 제공하게 됩니다. 자신이 다루기 쉬운 방식을 사용하여 원하는 위치 정보를 사용해 보도록 합니다!

300x250

[Hadoop]분산 행렬곱 연산 하둡 예제로 맵리듀스 이해하기(Matrix Multiplication with Hadoop)

프로그래밍 팁/Hadoop 2015. 12. 29. 15:35

 보통 거의 대부분의 프로그램들의 경우 입문자들을 위한 'Hello, World!' 예제들이 제공되어서 해당 프로그램의 이용 방법들을 이해하는 것이 용이한 편인데 이번에 공부하게 된 하둡의 경우 맵리듀스의 특성 때문에 Hello World 예제를 제공하는 것이 애매하지 않았나 싶습니다. 그 만큼 하둡 입문자들에게 있어서 맵리듀스의 원리를 체감하는게 힘들것이라 생각합니다.


 마침 하둡 예제를 찾아보던 도중 맵리듀스의 원리를 쉽게 이해할 수 있는 예제를 알게 되어 이렇게 소개합니다. 여러분들도 열심히 보시면서 이해할 수 있는 기회가 되었으면 합니다!


- 개발 환경

언어 : Java

IDE : VI

JDK 버전 : 1.7.0_91

운영체제 : Ubuntu 14.04

Hadoop 버전 : 2.6.0

Protoc 버전 : 2.5.0

실행 환경 : Terminal(우분투)


 1. Hadoop의 분산 실행 방식인 Map Reduce



 위 그림은 Hadoop의 Map Reduce 방식을 이미지로 도식화한 모습입니다. 먼저 Hadoop을 통해 빅데이터가 입력되면 데이텨의 내부는 입력 Split으로 잘게 분리가 된 후 Mapper를 통해 (Key, Value) 쌍으로 묶여서 각 노드로 보내집니다. 이 때 노드로 분배되는 과정은 각 Key의 Hash값을 기준으로 하여 각 Node 내에 있는 Task Container에게 전송됩니다. 이 때 각 Container는 같은 값을 가진 Key끼리 보내지므로 각 Key별로 같은 값을 계산하는 값을 전송할 수 있는 것입니다.

 (Key, Value)쌍은 각 같은 Key 끼리 Reduce로 전송되어지며 Reduce를 통해 설정이 완료되면 Result로 보내지면서 Hadoop의 hdfs 파일시스템에 저장됩니다.


 2. 행렬곱(Matrix Multiplication)의 원리

 행렬곱이란 이름 그대로 두 개의 행렬을 곱해 하나의 새로운 행렬을 구하는 것을 의미합니다. 행렬곱은 선행하는 행렬의 Row와 후행하는 행렬의 Column 내의 각 성분들의 곱을 합하는 것으로 값을 구합니다. 쉬운 예를 구하기 위해 아래와 같이 행렬 AB가 있다고 합시다.



  행렬 A는 i×j 행렬이며 행렬 B는 j×k 행렬입니다. 두 행렬의 행렬곱은 A×B로 나타낼 수 있으며 A의 Row와 B의 Column에 해당하는 요소 각각의 곱의 덧셈을 구하는 것이 행렬곱을 구하는 공식입니다. 이 때, A의 j에 해당하는 Row의 개수와 B의 j에 해당하는 Column의 개수가 일치해야 행렬곱이 성립됩니다..

 위의 행렬 A×B의 결과 값은 아래와 같이 표현할 수 있겠습니다.

 행렬곱 A×B의 최종 결과는 A의 Column 개수인 i와 B의 Row 개수인 k의 조합인 i×k 행렬로 나타납니다.


참고자료 : 위키백과

https://ko.wikipedia.org/wiki/%ED%96%89%EB%A0%AC_%EA%B3%B1%EC%85%88


 3. 행렬곱의 Map Reduce 구현

  Hadoop의 분산 방식을 활용하여 행렬곱의 결과로 나오는 행렬의 각 요소에 대한 계산을 Map Reduce로 분산하여 계산해보도록 합니다.입력값은 아래와 같이 주어졌다고 가정합니다.


/hadoop-matrix-multiplication/MapInput.txt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
A,0,1,1.0
A,0,2,2.0
A,0,3,3.0
A,0,4,4.0
A,1,0,5.0
A,1,1,6.0
A,1,2,7.0
A,1,3,8.0
A,1,4,9.0
B,0,1,1.0
B,0,2,2.0
B,1,0,3.0
B,1,1,4.0
B,1,2,5.0
B,2,0,6.0
B,2,1,7.0
B,2,2,8.0
B,3,0,9.0
B,3,1,10.0
B,3,2,11.0
B,4,0,12.0
B,4,1,13.0
B,4,2,14.0
cs


 주어진 입력값의 각 줄을 살펴보았을 때 첫 번째 값은 해당 행렬값이 A인지 B인지를 알려주는 값이고 두 번째는 column값, 세 번째는 row값, 네 번째는 해당 요소의 값을 나타냅니다. 즉 A는 2×5 행렬이고 B는 5×3 행렬이며 행렬곱 A×B은 2×3 행렬이 됩니다. 즉, 행렬곱 A×B를 구하기 위해 필요한 Key의 개수는 행렬곱 A×B의 요소의 개수인 2×3=6이라 할 수 있겠습니다.

 행렬곱 연산이 적용된 Map Reduce는 아래와 같이 그림으로 나타낼 수 있겠습니다.


Hadoop으로 입력된 행렬 데이터는 Map을 거치기 전에 입력 split으로 분리되어 각각의 Mapping 과정을 거치게 됩니다. 여기서 빨갛게 표시한 부분이 Key이고 그 뒤의 값이 Value입니다. Map을 거친 행렬의 각 요소는 각 노드 내의 Task Container에 들어가게 되어 Reduce 단계에서 행렬곱 연산을 수행하게 됩니다. 이 때 Map 단계에서 밑줄친 4개의 (Key, Value) 쌍이 Reduce에 넘어와서 서로의 값이 계산되고 있는 것을 보실 수 있습니다. 연산을 마치게 되면 hdfs 파일시스템에 지정된 폴더에 결과를 저장합니다.


 4. 프로그램 구현

 이제 행렬곱을 구현한 Hadoop 예제를 보도록 하겠습니다. 이 과정에 들어가기 앞서 Terminal 환경에서 Hadoop 프로그램을 컴파일 하는 환경을 구축하는 방법을 알아야 합니다. 아래 그 간단한 예제를 포스팅한 내용을 참조해 주시기 바랍니다.


[Hadoop] pom.xml로 maven 컴파일하기

http://elecs.tistory.com/163


 위의 예제를 참고하시면서 아래 행렬곱 분산 처리 프로그램 소스코드를 보시면 대략적인 동작 원리를 이해하실 수 있을 것입니다.


/hadoop-matrix-multiplication/src/main/java/elecs/tistory/com/MatrixMultiplication.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package elecs.tistory.com
 
import java.io.IOException;
import java.util.*;
 
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.conf.*;
import org.apache.hadoop.io.*;
import org.apache.hadoop.mapreduce.*;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
 
public class MatrixMultiplication {
 
    public static class Map extends Mapper<LongWritable, Text, Text, Text> {
        public void map(LongWritable key, Text value, Context context)
          throws IOException, InterruptedException {
            Configuration conf = context.getConfiguration();
            //행렬 A와 B의 크기를 정의한다.
            int m = Integer.parseInt(conf.get("m"));
            int n = Integer.parseInt(conf.get("n"));
            int p = Integer.parseInt(conf.get("p"));
 
            String line = value.toString();
            String[] indicesAndValue = line.split(",");
            Text outputKey = new Text();
            //Key와 Value를 저장할 값을 정의한다.
            Text outputValue = new Text();
            //Split의 각 줄을 , 단위로 나눈다.
 
            //Key는 행렬곱의 결과로 출력되는 행렬의 위치이다.
            //Value는 해당 행렬의 이름과 위치, 값을 정의한다.
            if (indicesAndValue[0].equals("A")) {
                for (int k = 0; k < p; k++) {
                    outputKey.set(indicesAndValue[1+ "," + k);
                    outputValue.set("A," + indicesAndValue[2+ "," + indicesAndValue[3]);
                    context.write(outputKey, outputValue);
                }
            } else {
                for (int i = 0; i < m; i++) {
                    outputKey.set(i + "," + indicesAndValue[2]);
                    outputValue.set("B," + indicesAndValue[1+ "," + indicesAndValue[3]);
                    context.write(outputKey, outputValue);
                }
            }
        }
    }
 
    public static class Reduce extends Reducer<Text, Text, Text, Text> {
        public void reduce(Text key, Iterable<Text> values, Context context)
          throws IOException, InterruptedException {
            Configuration conf = context.getConfiguration();
            String[] value;
 
            //각 행렬의 위치와 값을 저장할 수 있는 Map을 생성한다.
            HashMap<Integer, Float> hashA = new HashMap<Integer, Float>();
            HashMap<Integer, Float> hashB = new HashMap<Integer, Float>();
            for (Text val : values) {
                value = val.toString().split(",");
                if (value[0].equals("A")) {
                    hashA.put(Integer.parseInt(value[1]), Float.parseFloat(value[2]));
                } else {
                    hashB.put(Integer.parseInt(value[1]), Float.parseFloat(value[2]));
                }
            }
            //행렬 A와 B의 크기를 정의한다.
            int m = Integer.parseInt(conf.get("m"));
            int n = Integer.parseInt(conf.get("n"));
            int p = Integer.parseInt(conf.get("p"));
 
            float result = 0.0f;
            float a_ij;
            float b_jk;
 
            //각 행렬의 요소들과 비교하여 일치하면 서로 곱한 후 더한다.   
            for (int j = 0; j < n; j++) {
                a_ij = hashA.containsKey(j) ? hashA.get(j) : 0.0f;
                b_jk = hashB.containsKey(j) ? hashB.get(j) : 0.0f;
                result += a_ij * b_jk;
            }
            if (result != 0.0f) {
                context.write( key, new IntWritable(sum) );
            }
        }
    }
 
    public static void main(String[] args) throws Exception {
        Configuration conf = new Configuration();
        //행렬의 크기를 설정해줍니다.
        conf.set("m""2");
        conf.set("n""5");
        conf.set("p""3");
 
        Job job = new Job(conf, "MatrixMultiplication");
        job.setJarByClass(MatrixMultiplication.class);
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(Text.class);
 
        job.setMapperClass(Map.class);
        job.setReducerClass(Reduce.class);
 
        job.setInputFormatClass(TextInputFormat.class);
        job.setOutputFormatClass(TextOutputFormat.class);
 
        FileInputFormat.addInputPath(job, new Path(args[0]));
        FileOutputFormat.setOutputPath(job, new Path(args[1]));
 
        //하둡 분산 프로그램을 실행한다.
        job.waitForCompletion(true);
    }
}
cs

 위 행렬곱 분산 연산 예제를 실행하면 아래와 같은 결과값이 나옵니다. 각 행렬값 요소의 위치는 변경될 수 있습니다.





출저 : http://magpiehall.com/one-step-matrix-multiplication-with-hadoop/

300x250

Fedora에 이전 버전의 OpenJDK 설치하기(Install OpenJDK 7 in Fedora 23)

프로그래밍 팁 2015. 12. 22. 18:11

 Ubuntu의 경우 각 버전의 OpenJDK를 apt-get를 통해 제공하고 있습니다만 Fedora의 경우 최신 버전의 OpenJDK만이 dnf를 통해 제공되고 있습니다. AOSP(안드로이드 오픈소스 프로젝트)에서 안드로이드 운영체제를 컴파일하기 위해서는 특정 버전의 OpenJDK를 사용하여야 하는데 이게 아무리 최신 버전의 안드로이드 운영체제라 하더라도 항상 최신버전의 OpenJDK를 지원하지 않는 경우가 있습니다. 2015년 후반기에 등장한 최신 버전인 Marshmellow의 경우도 OpenJDK 1.7.0 버전을 요구하고 있기 때문에 현재 최신 버전인 OpenJDK 1.8.0에서는 컴파일을 진행할 수 없습니다.


 이번 포스팅에서는 2015년 후반기 최신 운영체제인 Fedora 23에 OpenJDK 1.7.0 버전을 설치해보도록 하겠습니다.


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

 2015년 12월 현재 최신버전인 Fedora 23에는 기본적으로 최신버전인 1.8.0이 설치되어 있는 것을 확인할 수 있습니다.


$ java -version



Fedora 23 부터는 기존부터 사용되었던 설치 관리자인 yum이 새로운 설치 관리자인 dnf로 변경되었습니다. 이 과정 때문이지는 모르겠습니다만 Fedora 23에서는 OpenJDK 1.8.0 이전의 버전들은 dnf를 통해 제공을 하고 있지 않습니다. 우리는 이제 이전 버전의 OpenJDK를 직접 찾아 설치해보도록 하겠습니다. rpm 패키지들을 검색해주는 사이트인 rpmfind에 접속합니다.


https://www.rpmfind.net



 사이트에 접속한 후 검색창에 다음 단어들을 검색해줍니다.


java-1.7.0-openjdk-headless

java-1.7.0-openjdk

java-1.7.0-openjdk-devel


 위 단어를 검핵해보면 아래와 같이 해당 rpm의 최신버전이 가장 윗부분에 노출됩니다. 그 중 자신의 운영체제에 맞는 패키지를 선택해 다운로드 받습니다. 본 포스팅에서는 64비트의 Fedora를 사용중이므로 x86-64 버전을 다운로드 받았습니다.



 다운로드 받은 패키지의 설정에 따라 의존성이 달라질 수 있으며 이에 해당하는 부분들에 대한 설치가 진행되어야 합니다. 이 포스팅에서 진행하는 대로 설치하시는 것을 원하시는 분은 아래 rpm을 다운로드 해주시길 바랍니다.


java-1.7.0-openjdk-headless

ftp://195.220.108.108/linux/centos/7.2.1511/os/x86_64/Packages/java-1.7.0-openjdk-headless-1.7.0.91-2.6.2.3.el7.x86_64.rpm


java-1.7.0-openjdk

ftp://195.220.108.108/linux/centos/7.2.1511/os/x86_64/Packages/java-1.7.0-openjdk-1.7.0.91-2.6.2.3.el7.x86_64.rpm


java-1.7.0-openjdk-devel

ftp://195.220.108.108/linux/centos/7.2.1511/os/x86_64/Packages/java-1.7.0-openjdk-devel-1.7.0.91-2.6.2.3.el7.x86_64.rpm


 위 과정까지 진행하셨다면 패키지를 설치하기 전 의존성 충돌을 피하기 위해 아래의 패키지를 설치해줍니다.


# dnf install xorg-x11-fonts-Type1 libpng15


 만약 위와 같은 과정을 진행하지 않을 경우 아래와 같이 Failed dependencies Error가 발생하면서 의존성에 문제가 발생하는 경우가 있습니다. 이 경우 해당 dependency에 대해 설치를 해주어야 하는데 이는 위에서 알려드린 사이트 rpmfind에서 검색하면 관련 설치 패키지를 확인하실 수 있습니다.




 다음으로 다운로드 받은 패키지른 다음과 같이 순서대로 설치해줍니다.


# rpm -i --force --nodeps java-1.7.0-openjdk-headless-1.7.0.91-2.6.2.3.el7.x86_64.rpm

# rpm -i --force --nodeps java-1.7.0-openjdk-1.7.0.91-2.6.2.3.el7.x86_64.rpm

# rpm -i java-1.7.0-openjdk-devel-1.7.0.91-2.6.2.3.el7.x86_64.rpm


 아래의 명령어를 입력하시면 설치된 OpenJDK가 1.7.0 으로 변경된 것을 확인하실 수 있습니다.

$ java -version



300x250

[Hadoop] pom.xml로 maven 컴파일하기

프로그래밍 팁/Hadoop 2015. 11. 28. 11:18

 Hadoop을 설치하였을 때 사용자의 이해를 돕기 위해 별도로 예제를 마련해 두고 있습니다. maven을 사용해 Hadoop 소스코드를 컴파일 하기 위해서는 pom.xml을 사용해야 하는데 간단한 Hadoop 예제를 pom.xml로 컴파일 하는 방법을 알아보도록 하겠습니다.


1. 먼저 실행하고자 하는 Hadoop 소스코드를 구현합니다. 본 예제는 하둡의 예제 소스코드인 WordCount를 사용하였습니다.


/hadoop-example/src/main/java/elecs/tistory/com/WordCount.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package elecs.tistory.com;
 
import java.io.IOException;
import java.util.StringTokenizer;
 
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.GenericOptionsParser;
 
public class WordCount {
 
  public static class TokenizerMapper 
       extends Mapper<Object, Text, Text, IntWritable>{
    
    private final static IntWritable one = new IntWritable(1);
    private Text word = new Text();
      
    public void map(Object key, Text value, Context context
                    ) throws IOException, InterruptedException {
      StringTokenizer itr = new StringTokenizer(value.toString());
      while (itr.hasMoreTokens()) {
        word.set(itr.nextToken());
        context.write(word, one);
      }
    }
  }
  
  public static class IntSumReducer 
       extends Reducer<Text,IntWritable,Text,IntWritable> {
    private IntWritable result = new IntWritable();
 
    public void reduce(Text key, Iterable<IntWritable> values, 
                       Context context
                       ) throws IOException, InterruptedException {
      int sum = 0;
      for (IntWritable val : values) {
        sum += val.get();
      }
      result.set(sum);
      context.write(key, result);
    }
  }
 
  public static void main(String[] args) throws Exception {
    Configuration conf = new Configuration();
    String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();
    if (otherArgs.length < 2) {
      System.err.println("Usage: <in> [<in>...] <out>");
      System.exit(2);
    }
    Job job = new Job(conf, "word count");
    job.setJarByClass(WordCount.class);
    job.setMapperClass(TokenizerMapper.class);
    job.setCombinerClass(IntSumReducer.class);
    job.setReducerClass(IntSumReducer.class);
    job.setOutputKeyClass(Text.class);
    job.setOutputValueClass(IntWritable.class);
    for (int i = 0; i < otherArgs.length - 1++i) {
      FileInputFormat.addInputPath(job, new Path(otherArgs[i]));
    }
    FileOutputFormat.setOutputPath(job,
      new Path(otherArgs[otherArgs.length - 1]));
    System.exit(job.waitForCompletion(true) ? 0 : 1);
  }
}
cs


2. 다음으로 소스코드를 컴파일 하기 위한 pom.xml을 만듭니다.


/hadoop-example/pom.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                      http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.apache.hadoop</groupId>
    <artifactId>hadoop-project</artifactId>
    <version>2.6.0</version>
  </parent>
  <groupId>elecs.tistory.com</groupId>
  <artifactId>hadoop-wordcount-example</artifactId>
  <version>2.6.0</version>
  <description>Apache Hadoop Wordcount Example</description>
  <name>Apache Hadoop Wordcount Example</name>
  <packaging>jar</packaging>
 
  <dependencies>
    <dependency>
      <groupId>commons-cli</groupId>
      <artifactId>commons-cli</artifactId>
    </dependency>
    <dependency>
      <groupId>commons-logging</groupId>
      <artifactId>commons-logging</artifactId>
    </dependency>
    <dependency>
      <groupId>org.apache.hadoop</groupId>
      <artifactId>hadoop-mapreduce-client-jobclient</artifactId>
      <version>${project.version}</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.apache.hadoop</groupId>
      <artifactId>hadoop-mapreduce-client-jobclient</artifactId>
      <scope>test</scope>
      <type>test-jar</type>
    </dependency>
    <dependency>
      <groupId>org.apache.hadoop</groupId>
      <artifactId>hadoop-common</artifactId>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.apache.hadoop</groupId>
      <artifactId>hadoop-common</artifactId>
      <scope>test</scope>
      <type>test-jar</type>
    </dependency>
    <dependency>
      <groupId>org.apache.hadoop</groupId>
      <artifactId>hadoop-hdfs</artifactId>
      <scope>runtime</scope>
    </dependency>
    <dependency>
       <groupId>org.apache.hadoop</groupId>
       <artifactId>hadoop-hdfs</artifactId>
       <scope>test</scope>
       <type>test-jar</type>
     </dependency>
     <dependency>
       <groupId>org.apache.hadoop</groupId>
       <artifactId>hadoop-yarn-server-tests</artifactId>
       <scope>test</scope>
       <type>test-jar</type>
     </dependency>
     <dependency>
       <groupId>org.apache.hadoop</groupId>
       <artifactId>hadoop-mapreduce-client-app</artifactId>
       <scope>provided</scope>
     </dependency>
     <dependency>
       <groupId>org.apache.hadoop</groupId>
       <artifactId>hadoop-mapreduce-client-app</artifactId>
       <type>test-jar</type>
       <scope>test</scope>
     </dependency>
    <dependency>
      <groupId>com.sun.jersey.jersey-test-framework</groupId>
      <artifactId>jersey-test-framework-grizzly2</artifactId>
      <scope>test</scope>
    </dependency>
     <dependency>
       <groupId>org.apache.hadoop</groupId>
       <artifactId>hadoop-mapreduce-client-hs</artifactId>
       <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>org.hsqldb</groupId>
       <artifactId>hsqldb</artifactId>
       <scope>provided</scope>
     </dependency>
     <dependency>
      <groupId>com.google.guava</groupId>
      <artifactId>guava</artifactId>
      <scope>provided</scope>
     </dependency>
  </dependencies>
 
  <!--
  자신이 main으로 설정하고자 하는 class의 이름을 package경로와 함께 표기합니다.
  -->
  <build>
   <plugins>
    <plugin>
    <groupId>org.apache.maven.plugins</groupId>
     <artifactId>maven-jar-plugin</artifactId>
      <configuration>
       <archive>
         <manifest>
           <mainClass>elecs.tistory.com.WordCount</mainClass>
         </manifest>
       </archive>
     </configuration>
    </plugin>
   </plugins>
   </build>
</project>
cs


3. 위 과정까지 진행하였다면 다음으로 maven을 사용해 Hadoop 소스코드를 컴파일합니다.


# mvn clean

 명령어 수행 후 target폴더가 생성되고 그 안에 jar 파일이 생성되었다면 컴파일에 성공한 것입니다.



 4. 다음으로 WordCount를 수행하기 위한 예제를 만듭니다.


# vi hello.txt




 5. hello.txt 예제 파일을 만든 후 hdfs에 파일을 전송합니다.


# hdfs dfs -mkdir /input

# hdfs dfs -copyFromLocal hello.txt /input


 6. hadoop 명령어를 실행하여 예제를 실행합니다.


# hadoop jar target/hadoop-wordcount-example-2.6.0.jar /input/hello.txt /output



7. 완성된 결과물을 Local 폴더에 저장합니다.


# hdfs dfs -getmerge /output result.txt

# cat result.txt


 아래와 같은 결과가 출력되면 Hadoop이 정상적으로 동작한 것입니다.




300x250

[Hadoop]Fedora 23 버전에서 Hadoop 2.7.1 설치하기(Install Hadoop 2.7.1 in Fedora 23)

프로그래밍 팁/Hadoop 2015. 11. 21. 10:37

 Fedora가 yum을 버리고 dnf를 사용하는 등 세세한 변화가 있어 이러한 환경에서 Hadoop을 설치하는 자세한 방법을 찾으면서 포스팅 해 보았습니다.


- 개발환경

운영체제 : Fedora 23

하둡 : Hadoop 2.7.1

ProtoBuffer : Protoc 2.5.0

JAVA : Java Development Kit 8


1. 시작하기에 앞서 dnf를 통해 아래의 프로그램드을 설치해주세요.


# dnf update

# dnf install gcc gcc-c++ automake kernel-devel openssl-devel cmake


2. 1.7+ 버전 이상의 Java를 설치합니다. 본 포스팅에서는 최신 버전의 JDK 8을 설치하였으며 Fedora 23의 경우 기본 설치된 JDK를 사용하시면 됩니다.


$ java -version



3. Maven 3.0 이상의 버전을 설치합니다. 본 포스팅에서는 Maven 3.3.9를 설치합니다.


# wget http://apache.tt.co.kr/maven/maven-3/3.3.9/binaries/apache-maven-3.3.9-bin.tar.gz

# tar -xzf apache-maven-3.3.9-bin.tar.gz

# mv apache-maven-3.3.9 /usr/local


4. ProtocolBuffer를 설치합니다. Hadoop 2.7.1의 경우 ProtocolBuffer 2.6.1을 설치해야 합니다.


# wget https://protobuf.googlecode.com/files/protobuf-2.5.0.tar.gz

# tar -xzf protobuf-2.5.0.tar.gz

# mv protobuf-2.5.0 /usr/local/lib

# cd /usr/local/lib/protobuf-2.5.0

# ./configure

# make -j4

# make check

# make install

# make ldconfig


 5. Fedora에 기본으로 깔려있는ProtocolBuffer가 있다면 삭제 후 새로 설치한 ProtocolBuffer을 설정해줍니다.


# rm /usr/bin/protoc

# update-alternatives --install "/usr/bin/protoc" "protoc" "/usr/local/bin/protoc" 1

# protoc --version



6. bashrc 파일을 수정하여 설치한 Maven과 ProtocolBuffer를 사용할 수 있도록 설정합니다.


# vi ~/.bashrc


export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib

export M2_HOME=/usr/local/apache-maven-3.3.9

export PATH=$M2_HOME/bin:$PATH


 

7. Hadoop 2.7.1을 다운로드 받은 후 압축을 풀어줍니다.


$ wget http://apache.mirror.cdnetworks.com/hadoop/common/hadoop-2.7.1/hadoop-2.7.1-src.tar.gz

$ tar -xzf hadoop-2.7.1-src.tar.gz

$ mv hadoop-2.7.1-src ~/

$ cd ~/hadoop-2.7.1-src


8. 이제 Hadoop을 컴파일 합니다. 컴파일 명령어는 아래와 같이 입력해줍니다.


# mvn clean package -Pdist,native -DskipTests -Dtar -Dmaven.javadoc.skip=true



 위의 화면과 같이 끝까지 수행하게 되면 Hadoop의 컴파일이 완료된 것입니다. 이제 Hadoop-dist 폴더를 확인하시면 컴파일된 Hadoop이 있는 것을 확인하실 수 있습니다.




 이제 컴파일된 Hadoop을 자신이 원하는 환경대로 구현을 하면 되겠습니다.

300x250