반응형


본 내용은 딥러닝 부트캠프 with 케라스 라는 책의 내용을 따라해본 것을 정리한 것이다.

소프트웨어 개발 관련 중에서 특히 딥러닝 분야의 책들이 늘 그렇듯 출판된지 조금만 지나도 업데이트가 빠르게 이루어지다 보니 책의 내용이 최신 버전을 반영하지 못하는 부분이 있다. 

이 책 역시도 Keras 1 버전에 예전 Theano 버전을 기준으로 작성되다 보니 일부 코드가 실행되지 않는 문제가 발생하여 여러 삽질을 겪어야 했다.

특히 GPU를 활용하는 부분이 아직 사용하기 어렵다.


코드 다운로드 하기

해당 책에서 공식적으로 제공하는 소스코드는 https://github.com/gilbutITbook/006959 에서 받을 수 있다.

최신 버전을 반영하기 위해 수정한 코드는 https://github.com/kyuhyong/deep_learning_keras 에서 받으면 된다.

위 소스코드를 git clone 하여 다운로드 한다.


프로젝트 구성

폴더 구성은 다음과 같다.


/deep_learning_keras/pycode/classification <-- 이미지 분류 관련 코드

/deep_learning_keras/data/                          <-- 훈련, 테스트, 평가할 데이터 셋


데이터 셋 다운로드 하기

이미지 분류를 진행하기 위해 데이터 셋을 다운로드 한다.

여기에서는 Caltech 101 이라는 데이터셋을 사용한다.

http://www.vision.caltech.edu/Image_Datasets/Caltech101/ 에서 다운로드할 수 있다.



101_ObjectCategories.tar.gz 라는 파일을 다운로드 하고 프로젝트 폴더의 data 폴더에 압축 해재한다. data 폴더가 없으면 생성한다.

$ cd ~/deep_learning_keras/ $ mkdir data $ tar xvf ~/Download/101_ObjectCategories.tar.gz data/

데이터셋의 구성은 다음과 같다.

/deep_learning_keras/data/Caltech-101

. label.csv

/test            <--테스트셋 데이터 폴더

  /0            <-- 클래스 airplanes

  /1            <-- 클래스 Motorbikes

  /2            <-- 클래스 Faces_easy

  /3            <-- 클래스 watch

  /4            <-- 클래스 Leopards

  /5            <-- 클래스 bonsai

/train        <-- 트레이닝 데이터 폴더

  /0            <-- 홀드아웃 1

  /1            <-- 홀드아웃 2

/train_org    <--복사한 6개의 카테고리 데이터

  /0            <-- 클래스 airplanes

  /1            <-- 클래스 Motorbikes

  /2            <-- 클래스 Faces_easy

  /3            <-- 클래스 watch

  /4            <-- 클래스 Leopards

  /5            <-- 클래스 bonsai 

/valid           <-- 벨리데이션 데이터셋 폴더

  /0            <-- 홀드아웃 1

  /1            <-- 홀드아웃 2


데이터 셋에는 총 6가지의 클래스로 구분된 폴더가 각각 존재한다. 

데이터셋 확장하기

기본적인 데이터의 양이 많지 않기 때문에 이미지를 회전, 확대, 축소, 늘리기, 노이즈 추가 등의 작업을 통해 데이터를 늘리는 작업이 필요하다.

pycode/classification/의 data_augmentation.py 은 파이썬의 sckit-image 라이브러리를 사용하여 이러한 작업을 수행한다.

확장된 데이터는 다음과 같다.

/deep_learning_keras/data/Caltech-101

. label.csv

/test            <--테스트셋 데이터 폴더

  /0            

  /1            

  /2            

  /3            

  /4            

  /5            

/train        <-- 트레이닝 데이터 폴더

  /0            <-- 홀드아웃 1

     /0        <--확장된 데이터 클래스

     /1

     /2

     /3

     /4

     /5

  /1            <-- 홀드아웃 2

  /all           <-- 홀드아웃 1+2

/train_org   

/valid           



모델 만들기

keras 에서 지원하는 9층 합성곱 모델을 작성한다. 책의 내용은 keras 1 버전의 내용을 담고 있어서 keras 2 를 지원하기 위해 일부 호출되는 함수 명, 계층 명칭을 수정하였다.

def layer_9_model(): # Keras의 Sequential을 기초 모델로 사용 ---① model = Sequential() if kerasVersion > 1: # 합성층(Convolution)을 모델에 추가 ---② model.add(Conv2D(32, (3, 3), padding='same', activation='linear', input_shape=(img_rows, img_cols, 3))) model.add(LeakyReLU(alpha=0.3)) model.add(Conv2D(32, (3, 3), padding='same', activation='linear')) model.add(LeakyReLU(alpha=0.3)) # 풀링층(MaxPooling)을 모델에 추가 ---③ model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2))) model.add(Conv2D(64, (3, 3), padding='same', activation='linear')) model.add(LeakyReLU(alpha=0.3)) model.add(Conv2D(64, (3, 3), padding='same', activation='linear')) model.add(LeakyReLU(alpha=0.3)) model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2))) model.add(Conv2D(128, (3, 3), padding='same', activation='linear')) model.add(LeakyReLU(alpha=0.3)) model.add(Conv2D(128, (3, 3), padding='same', activation='linear')) model.add(LeakyReLU(alpha=0.3)) model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2))) else : # 합성층(Convolution)을 모델에 추가 ---② model.add(Convolution2D(32, 3, 3, border_mode='same', activation='linear', input_shape=(3, img_rows, img_cols))) model.add(LeakyReLU(alpha=0.3)) model.add(Convolution2D(32, 3, 3, border_mode='same', activation='linear')) model.add(LeakyReLU(alpha=0.3)) # 풀링층(MaxPooling)을 모델에 추가 ---③ model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2), dim_ordering='th')) model.add(Convolution2D(64, 3, 3, border_mode='same', activation='linear')) model.add(LeakyReLU(alpha=0.3)) model.add(Convolution2D(64, 3, 3, border_mode='same', activation='linear')) model.add(LeakyReLU(alpha=0.3)) model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2), dim_ordering='th')) model.add(Convolution2D(128, 3, 3, border_mode='same', activation='linear')) model.add(LeakyReLU(alpha=0.3)) model.add(Convolution2D(128, 3, 3, border_mode='same', activation='linear')) model.add(LeakyReLU(alpha=0.3)) model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2), dim_ordering='th')) # Flatten층을 모델에 추가 -- ④ model.add(Flatten()) # 전결합층(Dense)을 모델에 추가 --- ⑤ model.add(Dense(1024, activation='linear')) model.add(LeakyReLU(alpha=0.3)) # Dropout층을 모델에 추가 --- ⑥ model.add(Dropout(0.5)) model.add(Dense(1024, activation='linear')) model.add(LeakyReLU(alpha=0.3)) model.add(Dropout(0.5)) # 최종 아웃풋을 구축 --- ⑦ model.add(Dense(6, activation='softmax')) # 손실 함수와 기울기의 계산에 사용하는 식을 정의한다. -- ⑧ sgd = SGD(lr=1e-3, decay=1e-6, momentum=0.9, nesterov=True) model.compile(optimizer=sgd, loss='categorical_crossentropy', metrics=["accuracy"]) return model

학습 실행

이제 모델에 데이터셋을 넣고 훈련을 수행한다. 

원래 Theano에서도 GPU를 사용하여 훈련을 하면 빠르게 진행되는데 어쩐일인지 자꾸 메모리 오류가 발생하여 일단은 CPU만 사용하여 훈련을 진행한다.

문제 해결 방안이 있으면 알려주세요.

$ python 9_Layer_CNN.py train Using Theano backend. /usr/local/lib/python2.7/dist-packages/keras/models.py:944: UserWarning: The `nb_epoch` argument in `fit` has been renamed `epochs`. warnings.warn('The `nb_epoch` argument in `fit` ' WARNING (theano.tensor.blas): We did not find a dynamic library in the library_dir of the library we use for blas. If you use ATLAS, make sure to compile it with dynamics library. Train on 261 samples, validate on 260 samples Epoch 1/40 64/261 [======>.......................] - ETA: 1:17 - loss: 1.7578 - acc: 0.234

128/261 [=============>................] - ETA: 52s - loss: 1.7659 - acc: 0.2422

261/261 [==============================] - 142s 543ms/step

- loss: 1.7369 - acc: 0.2797 - val_loss: 1.6112 - val_acc: 0.3077

Epoch 2/40 64/261 [======>.......................] - ETA: 1:16 - loss: 1.6483 - acc: 0.375

128/261 [=============>................] - ETA: 53s - loss: 1.6038 - acc: 0.3828

261/261 [==============================] - 141s 539ms/step

- loss: 1.5719 - acc: 0.3333 - val_loss: 1.3997 - val_acc: 0.3577 Epoch 3/40 64/261 [======>.......................] - ETA: 1:16 - loss: 1.5285 - acc: 0.234

128/261 [=============>................] - ETA: 53s - loss: 1.4486 - acc: 0.3047

261/261 [==============================] - 141s 539ms/step

- loss: 1.3584 - acc: 0.4023 - val_loss: 1.1560 - val_acc: 0.5038 Epoch 4/40 64/261 [======>.......................] - ETA: 1:23 - loss: 1.0000 - acc: 0.625

128/261 [=============>................] - ETA: 55s - loss: 1.2680 - acc: 0.5391

261/261 [==============================] - 144s 551ms/step

- loss: 1.1099 - acc: 0.5862 - val_loss: 0.9709 - val_acc: 0.6615 Epoch 5/40 64/261 [======>.......................] - ETA: 1:19 - loss: 1.0750 - acc: 0.625

128/261 [=============>................] - ETA: 54s - loss: 1.0243 - acc: 0.6094

261/261 [==============================] - 142s 543ms/step

- loss: 0.9588 - acc: 0.6322 - val_loss: 0.7666 - val_acc: 0.7269 Epoch 6/40 64/261 [======>.......................] - ETA: 1:20 - loss: 0.8764 - acc: 0.687

128/261 [=============>................] - ETA: 53s - loss: 0.7606 - acc: 0.7344

261/261 [==============================] - 142s 545ms/step

- loss: 0.7319 - acc: 0.7701 - val_loss: 0.5926 - val_acc: 0.8231Epoch 34/40

...

Epoch 35/40 64/261 [======>.......................] - ETA: 1:23 - loss: 0.0206 - acc: 0.984

128/261 [=============>................] - ETA: 54s - loss: 0.0359 - acc: 0.9922

261/261 [==============================] - 144s 550ms/step

- loss: 0.0288 - acc: 0.9923 - val_loss: 0.3863 - val_acc: 0.9269 Epoch 36/40 64/261 [======>.......................] - ETA: 1:21 - loss: 0.0442 - acc: 0.968

128/261 [=============>................] - ETA: 54s - loss: 0.0636 - acc: 0.9688

261/261 [==============================] - 144s 550ms/step

- loss: 0.0698 - acc: 0.9655 - val_loss: 0.3531 - val_acc: 0.9269 Epoch 37/40 64/261 [======>.......................] - ETA: 1:17 - loss: 0.0032 - acc: 1.000

128/261 [=============>................] - ETA: 53s - loss: 0.0138 - acc: 0.9922

261/261 [==============================] - 140s 537ms/step

- loss: 0.0165 - acc: 0.9923 - val_loss: 0.3281 - val_acc: 0.9269 Epoch 38/40 64/261 [======>.......................] - ETA: 1:17 - loss: 0.0427 - acc: 0.984

128/261 [=============>................] - ETA: 53s - loss: 0.0244 - acc: 0.9922

261/261 [==============================] - 141s 541ms/step

- loss: 0.0145 - acc: 0.9962 - val_loss: 0.3111 - val_acc: 0.9385 Epoch 39/40 64/261 [======>.......................] - ETA: 1:20 - loss: 0.0261 - acc: 0.984

128/261 [=============>................] - ETA: 54s - loss: 0.0285 - acc: 0.9844

261/261 [==============================] - 142s 542ms/step

- loss: 0.0201 - acc: 0.9923 - val_loss: 0.2992 - val_acc: 0.9308 Epoch 40/40 64/261 [======>.......................] - ETA: 1:17 - loss: 0.0225 - acc: 1.000

128/261 [=============>................] - ETA: 52s - loss: 0.0157 - acc: 1.0000

261/261 [==============================] - 142s 544ms/step

- loss: 0.0116 - acc: 1.0000 - val_loss: 0.2997 - val_acc: 0.9308

Train on 261 samples, validate on 260 samples Epoch 1/40 64/261 [======>.......................] - ETA: 1:15 - loss: 1.8016 - acc: 0.078

128/261 [=============>................] - ETA: 52s - loss: 1.7970 - acc: 0.1094

261/261 [==============================] - 141s 540ms/step

- loss: 1.7858 - acc: 0.1686 - val_loss: 1.7285 - val_acc: 0.4769 Epoch 2/40 64/261 [======>.......................] - ETA: 1:23 - loss: 1.7652 - acc: 0.265

128/261 [=============>................] - ETA: 54s - loss: 1.7264 - acc: 0.3828

261/261 [==============================] - 142s 543ms/step - loss: 1.7048 - acc: 0.3602 - val_loss: 1.6120 - val_acc: 0.4308Epoch 33/40

64/261 [======>.......................] - ETA: 1:16

- loss: 0.0544 - acc: 0.968128/261 [=============>................] - ETA: 51s - loss: 0.0576 - acc: 0.9688261/261 [==============================] - 137s 527ms/step - loss: 0.0333 - acc: 0.9847 - val_loss: 0.6902 - val_acc: 0.8846 ...


Epoch 34/40 64/261 [======>.......................] - ETA: 1:18 - loss: 0.1083 - acc: 0.953

128/261 [=============>................] - ETA: 53s - loss: 0.0852 - acc: 0.9688

261/261 [==============================] - 141s 541ms/step

- loss: 0.0944 - acc: 0.9617 - val_loss: 0.6737 - val_acc: 0.8808 Epoch 35/40 64/261 [======>.......................] - ETA: 1:19 - loss: 0.0593 - acc: 0.984

128/261 [=============>................] - ETA: 53s - loss: 0.0404 - acc: 0.9844

261/261 [==============================] - 141s 541ms/step

- loss: 0.0380 - acc: 0.9885 - val_loss: 0.6246 - val_acc: 0.8846 Epoch 36/40 64/261 [======>.......................] - ETA: 1:15 - loss: 0.0090 - acc: 1.000

128/261 [=============>................] - ETA: 52s - loss: 0.0220 - acc: 0.9922

261/261 [==============================] - 140s 537ms/step

- loss: 0.0462 - acc: 0.9885 - val_loss: 0.5759 - val_acc: 0.8885 Epoch 37/40 64/261 [======>.......................] - ETA: 1:15 - loss: 0.0260 - acc: 0.984

128/261 [=============>................] - ETA: 52s - loss: 0.0265 - acc: 0.9844

261/261 [==============================] - 142s 542ms/step

- loss: 0.0229 - acc: 0.9923 - val_loss: 0.5629 - val_acc: 0.8923 Epoch 38/40 64/261 [======>.......................] - ETA: 1:21 - loss: 0.0346 - acc: 0.984

128/261 [=============>................] - ETA: 53s - loss: 0.0333 - acc: 0.9844

261/261 [==============================] - 141s 538ms/step

- loss: 0.0282 - acc: 0.9885 - val_loss: 0.5665 - val_acc: 0.9000 Epoch 39/40 64/261 [======>.......................] - ETA: 1:21 - loss: 0.0107 - acc: 1.000

128/261 [=============>................] - ETA: 53s - loss: 0.0089 - acc: 1.0000

261/261 [==============================] - 140s 535ms/step

- loss: 0.0189 - acc: 0.9923 - val_loss: 0.5851 - val_acc: 0.8962 Epoch 40/40 64/261 [======>.......................] - ETA: 1:16 - loss: 0.0290 - acc: 0.984

128/261 [=============>................] - ETA: 51s - loss: 0.0478 - acc: 0.9766

261/261 [==============================] - 139s 532ms/step

- loss: 0.0536 - acc: 0.9770 - val_loss: 0.6973 - val_acc: 0.8885


예측 실행하기 

예측을 수행하여 훈련된 모델이 잘 동작하는지 확인한다. 

실행속도를 높이기 위해 이번에는 GPU를 사용하도록 환경 변수를 등록한다.

다행히 예측하는 과정에는 메모리를 적게 사용하기 때문인지 잘 동작한다.

주의. Theano 2 에서는 device 의 이름이 gpu0 가 아니고 cuda0 로 변경되었다.

$ export THEANO_FLAGS='mode=FAST_RUN,device=cuda0, floatX=float32, optimizer_excluding=conv_dnn'

$ python 9_Layer_CNN.py test 38 27 Using Theano backend. Using cuDNN version 7005 on context None Mapped name None to device cuda0: GeForce GTX 980M (0000:01:00.0) airplanes 640/640 [==============================] - 3s 5ms/step ... 640/640 [==============================] - 3s 5ms/step 정답수  566 오답수 74 Motorbikes 638/638 [==============================] - 3s 5ms/step ... 638/638 [==============================] - 3s 5ms/step 정답수  607 오답수 31 Faces_easy 348/348 [==============================] - 2s 5ms/step ... 348/348 [==============================] - 2s 5ms/step 정답수  322 오답수 26 watch 191/191 [==============================] - 1s 5ms/step ... 191/191 [==============================] - 1s 5ms/step 정답수  119 오답수 72 Leopards 160/160 [==============================] - 1s 5ms/step ... 160/160 [==============================] - 1s 5ms/step 정답수  151 오답수 9 bonsai 102/102 [==============================] - 0s 5ms/step ... 102/102 [==============================] - 0s 5ms/step 정답수  53 오답수 49



반응형
반응형

Keras 를 사용하게 되면 Tensorflow 혹은 Theano를 Backend로 활용하는 경우가 있다.

이번에는 Ubuntu 16.04에 Theano를 설치하는 과정을 정리해 보았다.


설치 과정은 http://deeplearning.net/software/theano/install_ubuntu.html 에 자세히 설명되어 있으나

GPU를 활용하기 위해서는 약간의 삽질이 동반될 수 있으므로 따로 정리하였다.


Conda로 설치하는 것을 권장하고 있는데 conda 설정의 복잡함과 개인 pc 에서 궂이 라는 생각으로 그냥 설치하기로 진행한다.


1. PIP 를 통해 Theano 설치


간단히 pip 명령어를 사용하여 Theano를 설치한다.

$ sudo pip install Theano


2. libgpuarray 설치


GPU를 지원하기 위해서는 libgpuarray 라는 패키지가 필요하다.

git 명령어로 해당 패키지를 홈 디렉토리에 다운로드한다.

git clone https://github.com/Theano/libgpuarray.git cd libgpuarray

2.1 libgpuarray 설치는 다음과 같이 빌드 후 설치를 진행하면 된다.

cd <dir> mkdir Build cd Build # you can pass -DCMAKE_INSTALL_PREFIX=/path/to/somewhere to install to an alternate location cmake .. -DCMAKE_BUILD_TYPE=Release # or Debug if you are investigating a crash make sudo make install cd ..

2.2 pygpu 설치

# 이 작업은 반드시 위 방법대로 libgpuarray 가 설치된 후에 진행해야 한다. python setup.py build python setup.py install

2.3 Cython 최신버전 설치하기 (pygpu설치 실패하는 경우)

경우에 따라 아래와 같이 Cython 버전이 낮거나 설치되지 않아서 에러가 발생하는 경우가 있다.

python setup.py Traceback (most recent call last): File "setup.py", line 12, in <module> raise Exception('cython is too old or not installed ' Exception: cython is too old or not installed (at least 0.25 required)

sudo apt-get install 명령으로 cython을 설치해 보아도 아직 업데이트가 안된건지 0.23 이상으로 업그레이드가 되지 않으므로 
홈페이지에서 소스에서 빌드하여 설치하도록 한다. 2018년 4월 11일 현재 최신 버전은 0.28.1 이다.
먼저 기존에 설치된 cython을 삭제하기 위해 다음을 수행한다.

$ sudo apt-get remove cython

https://pypi.python.org/pypi/Cython/ 페이지에서 Cython-0.28.1.tar.gz 파일을 다운로드 한다. 

압축 해재 후 폴더로 이동하여 다음을 수행한다.

cd ~/Downloads/Cython-0.28.1/ sudo python setup.py install

이제 다시 2.2 로 돌아가서 pygpu를 설치해본다.


3. Theano 실행 테스트 (GPU)


이제 Theano가 GPU를 잘 활용하는지 확인해보기 위해 간단한 파이썬 스크립트를 실행해보자.

메모장을 열고 아래 코드를 붙여넣기 한 다음 test.py로 저장한다.

 from theano import function, config, shared, tensor

import numpy
import time

vlen = 10 * 30 * 768  # 10 x #cores x # threads per core
iters = 1000

rng = numpy.random.RandomState(22)
x = shared(numpy.asarray(rng.rand(vlen), config.floatX))
f = function([], tensor.exp(x))
print(f.maker.fgraph.toposort())
t0 = time.time()
for i in range(iters):
    r = f()
t1 = time.time()
print("Looping %d times took %f seconds" % (iters, t1 - t0))
print("Result is %s" % (r,))
if numpy.any([isinstance(x.op, tensor.Elemwise) and
              ('Gpu' not in type(x.op).__name__)
              for x in f.maker.fgraph.toposort()]):
    print('Used the cpu')
else:
    print('Used the gpu')

그냥 이 프로그램을 실행하면 cpu 기반으로 동작하고 다음과 같은 결과가 나온다. 대략 29초가 걸리는 작업이다.

$ python testgpu.py [Elemwise{exp,no_inplace}(<TensorType(float64, vector)>)] Looping 1000 times took 29.441501 seconds Result is [ 1.23178032 1.61879341 1.52278065 ..., 2.20771815 2.29967753 1.62323285] Used the cpu

이제 Theano가 gpu를 사용하도록 하기 위해 아래와 같이 환경변수를 등록한다.

$ export THEANO_FLAGS='device=cuda, floatX=float32'

동일한 프로그램을 다시 실행해보면 아래와 같은 결과가 나온다.

$ python testgpu.py Using cuDNN version 7005 on context None Mapped name None to device cuda: GeForce GTX 980M (0000:01:00.0) [GpuElemwise{exp,no_inplace}(<GpuArrayType<None>(float32, vector)>), HostFromGpu(gpuarray)(GpuElemwise{exp,no_inplace}.0)] Looping 1000 times took 0.219304 seconds Result is [ 1.23178029 1.61879349 1.52278066 ..., 2.20771813 2.29967761 1.62323296] Used the gpu

현재 컴퓨터에는 GTX 980M 이 탑재되어 있고 결과는 0.2초 무려 1/100 넘게 단축되었다.



2018/4/11 최초문서 발행

반응형
반응형

git 를 사용하여 원격 프로젝트를 생성한 다음

업데이트를 위해서 git push 할때마다 매번 사용자 정보를 입력해야 하는 번거로움이 있다. 

이럴때는 다음과 같이 입력하면 된다.


$ git 

$ git config remote.origin.url https://{사용자ID}@github.com/{사용자ID}/{프로젝트 이름}.git


예를 들어 사용자 이름이 name 이고 프로젝트 이름이 my_project 이면

$ git config remote.origin.url https://name@github.com/my_project.git

라고 입력하면 된다.

저장된 정보를 확인하려면


$ git config -l


반응형

'Computer > git' 카테고리의 다른 글

git Submodule 사용하기  (0) 2019.01.16
git 디렉토리 복사 후 복구  (0) 2018.10.10
git 에서 새로운 브랜치 만들기  (0) 2018.02.02
git 의 오래된 항목 삭제하기  (0) 2018.01.22

+ Recent posts