분류 전체보기 (336)

반응형


R 랜덤포레스트 사용하기


머신러닝 분야에서 많이 쓰이는 예제 데이터셋 Pima Diabetes 자료를 통해 간단한 Random Forest를 사용하는 방법을 알아보겠습니다.


라이브러리 로드

library(MASS) library(randomForest) library(caret)

MASS : 예제 데이터셋이 있는 라이브러리

randomForest : randomForest 이용을 위한 라이브러리

caret : 성능 평가시 confusion matrix를 그리기 위한 라이브러리


데이터 불러오기

data("Pima.tr")
data("Pima.te")

R에서 데이터 불러오는 방법은 라이브러리가 로드된 상태에서 data("데이터이름")이라고 실행하면, 작업공간상에 데이터가 생성됩니다.


> head(Pima.tr)
  npreg glu bp skin  bmi   ped age type
1     5  86 68   28 30.2 0.364  24   No
2     7 195 70   33 25.1 0.163  55  Yes
3     5  77 82   41 35.8 0.156  35   No
4     0 165 76   43 47.9 0.259  26   No
5     0 107 60   25 26.4 0.133  23   No
6     5  97 76   27 35.6 0.378  52  Yes

RandomForest 모형 만들기

set.seed(10)
rf.fit = randomForest(type ~ npreg + glu + bp + skin + bmi + ped + age
                      , data=Pima.tr, mtry = floor(sqrt(7)), ntree = 500, importance = T)
rf.fit

randomForest 모형을 만드는 문법은 위와 같습니다. hyper parameter로 이 모형에서는 mtry와 ntree를 사용하였습니다. mtry는 각각의 tree마다 몇 개의 feature를 사용할 것인지를 정하는 것입니다. 골드스탠다다는 보통, regression의 경우 변수갯수/3, classification의 경우 sqrt(변수갯수)를 사용합니다. 이 데이터셋은 classification 문제이므로, sqrt를 사용하였습니다. ntree는 tree의 총 갯수를 의미합니다.


테스트 데이터 생성

test_x = Pima.te[c("npreg", "glu", "bp", "skin", "bmi", "ped", "age")]
test_y = Pima.te$type

test_y를 불러올 때는 $로 불러와야지 vector로 불러와지므로 아래 confusionMatrix가 잘 실행됩니다.


성능 평가

y_pred = predict(rf.fit, test_x)

confusionMatrix(y_pred, test_y)
Confusion Matrix and Statistics

          Reference
Prediction  No Yes
       No  192  46
       Yes  31  63
                                          
               Accuracy : 0.7681          
                 95% CI : (0.7189, 0.8124)
    No Information Rate : 0.6717          
    P-Value [Acc > NIR] : 7.678e-05       
                                          
                  Kappa : 0.455           
 Mcnemar's Test P-Value : 0.1106          
                                          
            Sensitivity : 0.8610          
            Specificity : 0.5780          
         Pos Pred Value : 0.8067          
         Neg Pred Value : 0.6702          
             Prevalence : 0.6717          
         Detection Rate : 0.5783          
   Detection Prevalence : 0.7169          
      Balanced Accuracy : 0.7195          
                                          
       'Positive' Class : No    


변수 중요도

> importance(rf.fit)
             No       Yes MeanDecreaseAccuracy MeanDecreaseGini
npreg  9.467923  1.762747             9.098049         9.308814
glu   14.543787 16.760373            20.263701        21.771324
bp     4.210273 -8.185459            -1.740227         7.920807
skin   1.370477  1.662921             2.029630         9.350372
bmi    3.431359  7.500978             7.200368        13.322145
ped    4.957824  4.666885             6.778956        13.479470
age   12.162707  6.341079            13.414806        14.528669

변수 중요도 플롯




17페이지에 random forest hyper-parameter 관련한 설명들이 나온다.

https://cran.r-project.org/web/packages/randomForest/randomForest.pdf


Random Forest 관련 튜토리얼

https://machinelearningmastery.com/tune-machine-learning-algorithms-in-r/

반응형
반응형

Segmentation


classification이 사진에서 어떠한 물체가 '존재하는지' 를 판단하는 것이라면 Segmentation은 이미지에서 픽셀단위로 해당 픽셀이 어떤 Class에 속하는지를 예측하는 태스크로 볼 수 있다.


Input


Output


예를 들어, 위 그림을 보자. 오토바이를 타고 있는 사람이 보인다. 이 데이터를 Input으로 주면 아래와 같은 Output을 주는 것이 Segmentation의 태스크이다. 이를 트레이닝하기 위해서는 픽셀레벨로 해당 픽셀이 어디에 속하는지 label을 달은 데이터가 필요하다. 이는 사람이 직접 label을 하는 경우가많다. 위 pascal challenge에서도 사람이 직접 label한 데이터를 제공하였다.


Object Segmentation과 Class Segmentation


pascal voc2011 challenge에서는 segmentation을 object segmentation과 class segmentation으로 나누었다. object segmentation은 이미지에서 '어떤 물체가 있다는 사실' 을 픽셀단위로 예측하는 것이고, class segmentation은 어떤 물체가 '어떤 클래스에 속하는 지'까지 예측하는 것이다. 예를 들어 아래 그림을 보면, object segmentation에서는 어떤 object별로 모두 다른 색깔로 표현하고 있지만, class segmentation에서는 object들 중에서 같은 class인 경우 같은 색깔로, 표시하고 있다. (예를 들어 같은 '화분' 이라는 class를 갖고 있는 object는 같은 색깔로 표시하였다.) 



Dilated Convolution


Dilated Convolution은 필터 내부에 zero padding을 추가해 강제로 receptive field를 늘리는 방법이다. 위 그림은 파란색이 인풋, 초록색이 아웃풋인데, 진한 파랑 부분에만 weight가 있고 나머지 부분은 0으로 채워진다. receptive field란 필터가 한 번의 보는 영영으로 볼 수 있는데, 결국 필터를 통해 어떤 사진의 전체적인 특징을 잡아내기 위해서는 receptive field는 높으면 높을 수록 좋다. 그렇다고 필터의 크기를 크게하면 연산의 양이 크게 늘어나고, 오버피팅의 우려가있다. 그래서 일반적인 CNN에서는 이를 conv-pooling의 결합으로 해결한다. pooling을 통해 dimension을 줄이고 다시 작은 크기의 filter로 conv를 하면, 전체적인 특징을 잡아낼 수 있다. 하지만 pooling을 수행하면 기존 정보의 손실이 일어난다. 이를 해결하기 위한것이 Dilated Convolution으로 Pooling을 수행하지 않고도 receptive field의 크기를 크게 가져갈 수 있기 때문에 spatial dimension의 손실이 적고, 대부분의 weight가 0이기 때문에 연산의 효율도 좋다. 공간적 특징을 유지하는 특성 때문에 Dilated Convolution은 특히 Segmentation에 많이 사용된다.


이 그림을 통해 pooling-conv후 upsampling을 하는 것과 dilated convolution(astrous convolution)을 하는 것의 차이를 볼 수 있다. 위 그림에서 볼 수 있듯 공간적 정보의 손실이 있는 것을 upsampling 하면 해상도가 떨어진다. 하지만 dilated convolution의 그림을 보면 receptive field를 크게 가져가면서 convolution을 하면 정보의 손실을 최대화하면서 해상도는 큰 output을 얻을 수 있다.



Dilated Convolution을 어떻게 Segmentation에 활용할까?


출처-http://blog.naver.com/sogangori/220952339643


첫번째 그림은 classification을 위한 CNN VGG-16의 아키텍쳐이다. conv-pooling을 반복적으로 수행한 후, 마지막으로 Fully Connected Layer에 통과하여 최종 classification 결과를 얻는 과정을 보여주고있다. 그 아래의 그림은 Dilated Convolution을 통하여 이미지를 segmentation하는 예를 보여주고 있다. 이 아키텍쳐의 아웃풋의 사이즈는 28x28xN 이며, (N은 segmentation 원하는 클래스의 수) 이를 다시 upsampling하여 원래의 크기로 복원한다. (이부분에서 공간적 정보의 손실이 있다.)


이 아키텍쳐와 classification 아키텍쳐의 다른점은 우선 다이아몬드 모양으로 표시한 dilated convolution으 통해 공간적 정보의 손실을 최소화하였다. 그리고 dilated convolution 2번을 적용한 뒤 나온 28x28x4096 에 대하여 1x1 convolution으로 channel의 dimension reduction을 수행한다. 최종적으로 28x28xN이 나오고 이를 8x upsampling하여 최종적인 segmention 결과를 output으로 내놓는다. 이 때 1x1 convolution 은 공간적인 정보를 잃지 않기 위해 사용되며, classifiction의 Fully Connected Layer(FC)와 비슷한 역할을 한다. 하지만 classification에서는 공간적인 정보는 중요하지 않기 때문에 Flatten하여 사용하는 것이다.


반응형
반응형


Keras 멀티 GPU 이용하기


keras 2.0.9 버전부터 멀티 GPU를 손쉽게 활용할 수 있게 업데이트되었습니다. 이번 포스팅은 기존 모델을 멀티 GPU를 사용하여 트레이닝하는 예제입니다.


1. keras 2.0.9 이상에서 지원하므로 2.0.9 이상으로 업데이트

pip install --upgrade keras

2. keras 모델 생성


일반적인 keras CNN을 예로 들어 설명하겠습니다. 대략 이런 cnn model이 있다고 합시다. (패키지 임포트문 생략)

def cnn_model(): # create model model = Sequential() model.add(Convolution2D(16, 3, 3, border_mode='same', activation='relu', input_shape=(256,256,1))) model.add(BatchNormalization()) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Convolution2D(32, 3, 3, border_mode='same', activation='relu')) model.add(BatchNormalization()) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Convolution2D(32, 3, 3, border_mode='same', activation='relu')) model.add(BatchNormalization()) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Convolution2D(64, 3, 3, border_mode='same', activation='relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Convolution2D(64, 3, 3, border_mode='same', activation='relu')) model.add(BatchNormalization()) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Flatten()) model.add(Dense(64, activation='relu')) model.add(Dropout(0.5)) model.add(Dense(64, activation='relu')) model.add(Dropout(0.5)) model.add(Dense(3, activation='softmax')) return model


2.0.9 버전 이후부터 제공하는 multi_gpu_model을 임포트

from keras.utils.training_utils import multi_gpu_model

모델을 만들고 multi_gpu_model을 통해서 multi gpu를 활용한다는 선언을 합니다. gpus 파라미터에 사용하고 싶은 gpu 수를 설정합니다. 모델을 compile하고 fit하면 트레이닝이 됩니다.

model = cnn_model()
model = multi_gpu_model(model, gpus=4)
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
model.fit(train_x, train_y, validation_data=(test_x, test_y), nb_epoch=20, batch_size=32, verbose=1)

트레이닝이 잘됩니다.

Train on 215 samples, validate on 107 samples
Epoch 1/20
215/215 [==============================] - 1s - loss: 2.0448 - acc: 0.4465 - val_loss: 1.0884 - val_acc: 0.2710
Epoch 2/20
215/215 [==============================] - 0s - loss: 1.5974 - acc: 0.4791 - val_loss: 1.1431 - val_acc: 0.1963
Epoch 3/20
215/215 [==============================] - 0s - loss: 1.2704 - acc: 0.5302 - val_loss: 1.2524 - val_acc: 0.4486
Epoch 4/20
215/215 [==============================] - 0s - loss: 1.1777 - acc: 0.4512 - val_loss: 1.3994 - val_acc: 0.5327
Epoch 5/20
215/215 [==============================] - 0s - loss: 1.0600 - acc: 0.5953 - val_loss: 1.4960 - val_acc: 0.5888
Epoch 6/20
215/215 [==============================] - 0s - loss: 1.0486 - acc: 0.6512 - val_loss: 1.5189 - val_acc: 0.5888
Epoch 7/20
215/215 [==============================] - 0s - loss: 0.9968 - acc: 0.6186 - val_loss: 1.5151 - val_acc: 0.5888
Epoch 8/20
215/215 [==============================] - 0s - loss: 1.0375 - acc: 0.6000 - val_loss: 1.4286 - val_acc: 0.5888
Epoch 9/20
215/215 [==============================] - 0s - loss: 0.9987 - acc: 0.6093 - val_loss: 1.3102 - val_acc: 0.5701
Epoch 10/20


서버에서 nvidia-smi를 쳐보면 이렇게 모든 gpu가 모두 활용되는 것을 볼 수 있습니다.




참고


https://www.pyimagesearch.com/2017/10/30/how-to-multi-gpu-training-with-keras-python-and-deep-learning/

반응형
반응형

우분투에 R과 Rstudio Server 설치



1. R 설치

sudo apt-get install r-base



2. R studio 설치


아래 링크에서 보고 따라하면 됨

https://www.rstudio.com/products/rstudio/download-server/


이건 1.1.383 version 기준


sudo apt-get install gdebi-core

wget https://download2.rstudio.org/rstudio-server-1.1.383-amd64.deb

sudo gdebi rstudio-server-1.1.383-amd64.deb



3. 웹브라우저 접속

http://<server-ip>:8787


위 처럼 접속해서 운영체제 아이디/패스워드를 통해 로그인

반응형
반응형


Deconvolution

CNN에서 convolution layer는 convolution을 통해서 feature map의 크기를 줄인다. 하지만 Deconvolution은 이와 반대로 feature map의 크기를 증가시키는 방식으로 동작한다.


Deconvolution은 아래와 같은 방식으로 동작한다.


1 각각의 픽셀 주위에 zero-padding을 추가한다. 

2. 이렇게 padding이된 것에 convolution 연산을 한다.


위 그림에서 아래쪽의 파란색 픽셀이 input 초록색이 output이다. 이 파란색 픽셀 주위로 흰색 zero-padding을 수행하고, 회색 filter를 통해 convolution 연산을 수행하여 초록색 output을 만들어낸다.


Deconvolution은 일반 cnn의 최종 결과물을 다시 반대로 되돌려 input과 같은 사이즈를 만들어내고 싶을 때 쓰인다. 주로 semantic segmentation등에 활용할 수 있다. Deconvolution은 Upsampling 등으로도 불린다.


반응형
반응형

Python - sklearn LabelEncoder, OnehotEncoder 사용


python에서 범주형 변수를 인코딩 하기 위하여 더미변수를 만들거나, one hot encoding을 합니다. 선형회귀 같은 기본적인 통계 모형에서는 더미변수를 많이 쓰지만, 일반적인 머신러닝/딥러닝 접근법에서는 one hot encoding을 많이합니다. one hot encoding을 하기위해서는 직접 함수를 만들어 할 수도 있지만 패키지를 사용하면 편합니다. 가장 편하다고 생각하는 방법이 바로 sklearn 패키지를 통한 one hot encoding 인데요. 예를 들어 아래와 같은 info라는 이름의 pandas dataframe 이 있을 때, class2를 예측변수 y라고 생각하여 one hot encoding 하는 방법을 알아보겠습니다.



id tissue class class2 x y r
0 mdb001 G CIRC B 535 425 197.0
1 mdb002 G CIRC B 522 280 69.0
2 mdb003 D NORM N NaN NaN NaN
3 mdb004 D NORM N NaN NaN NaN
4 mdb005 F CIRC B 477 133 30.0
5 mdb005 F CIRC B 500 168 26.0


Code

from sklearn import preprocessing label_encoder = preprocessing.LabelEncoder() onehot_encoder = preprocessing.OneHotEncoder() train_y = label_encoder.fit_transform(info['class2']) train_y = train_y.reshape(len(train_y), 1) train_y = onehot_encoder.fit_transform(train_y)

LabelEncoder 결과


[0 0 2 2 0 0 2 2 2 2 0 2 0 0 2 0 2 0 2 0 2 0 2 1 2 0 2 2 1 2 0 2 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 0 2 2 2 0 2 2 2 2 2 0 2 2 1 2 2 1 2 2 2 2 0 0 2 0 2 2 2 2 2


OnehotEncoder 결과 - 최종 train_y

(0, 0) 1.0 (1, 0) 1.0 (2, 2) 1.0 (3, 2) 1.0 (4, 0) 1.0 (5, 0) 1.0 (6, 2) 1.0 (7, 2) 1.0 (8, 2) 1.0 (9, 2) 1.0 (10, 0) 1.0 (11, 2) 1.0 (12, 0) 1.0 (13, 0) 1.0

몇 줄 되지 않는 코드로 이처럼 one hot encoding을 구현할 수 있습니다. one hot encoding을 하기 전에 label encoding을 하는 이유는 one hot encoder의 인풋으로 숫자형만 올 수 있기 때문입니다. label encoder의 결과로 문자형 변수가 숫자형 변수 범주형으로 변경되게 되고 이를 one hot encoder에 fit_transform 해주면, 이와 같이 one hot encoding된 결과를 얻을 수 있습니다. 이 때, train_y 변수는 sparse matrix가되어 프린트하면 위와같이 나타납니다. 이는 matrix의 인덱스와 그에 해당하는 value를 나타낸건데 매트릭스에 값을 대입해보면 labelencoder 결과에 onehot encoding이 적용된 것을 확인할 수 있습니다.





반응형

'Tools > Python' 카테고리의 다른 글

Python - SSL 에러 해결  (1) 2018.03.04
Python - Pandas isin 구문  (0) 2018.02.25
Python - 폴더 파일 리스트 가져오기  (4) 2017.10.31
Python - Pandas 변수 정렬하기  (0) 2017.10.24
Python - Pandas 그룹별 평균 구하기  (2) 2017.10.24
반응형

Keras- Tensorflow Backend에서 특정 디바이스 사용법


Keras에 tensorflow backend를 사용할 때, 기본적으로 gpu를 사용하여 돌아갑니다. gpu가 있는데 cpu를 사용할 필요는 없겠지만, gpu의 성능을 측정하거나 하는 목적을 위해 강제로 cpu를 사용하도록 하는 방법에 대해 알아보겠습니다.


keras + tensorflow에서 사용가능한 하드웨어 자원보기


아래와 같이 tensorflow의 device_lib이라는 함수를 통해 현재 사용가능한 하드웨어 디바이스들의 리스트를 볼 수 있습니다. 여기서 name을 통해 해당 하드웨어에 접근할 수 있습니다. 제가 사용하는 환경의 경우 1080ti 4개를 사용하는데, 이 디바이스들의 리스트가 나오는 것을 볼 수 있습니다.

from tensorflow.python.client import device_lib
print(device_lib.list_local_devices())
[name: "/cpu:0"
device_type: "CPU"
memory_limit: 268435456
locality {
}
incarnation: ....
, name: "/gpu:0"
device_type: "GPU"
memory_limit: 295043072
locality {
  bus_id: 1
}
incarnation: .....
physical_device_desc: "device: 0, name: GeForce GTX 1080 Ti, pci bus id: 0000:02:00.0"
, name: "/gpu:1"
device_type: "GPU"
memory_limit: 366346240
locality {
  bus_id: 1
}
...

특정 device 사용하여 모델 구축, 트레이닝하기


아래와 같이 keras.backend.tensorflow_backend를 K 라는 이름으로 불러오고 with 문을 통해 해당 환경에서 모델을 구축후, fitting을 하면 해당 디바이스 환경에서 모델을 트레이닝 할 수 있습니다. 주의할 점은 model = Sequential()을 통해 모델을 생성할 때부터 with문을 통해 해당 device를 사용한다는 것을 알려줘야 한다는 것입니다. 단순히 model.fit 만 with 아래에서 돌리면 with 문이 먹히지 않더군요..

import keras.backend.tensorflow_backend as K
with K.tf.device('/gpu:0'):
    model = Sequential()
    model.add(Dense(512, input_dim=28*28, activation='relu'))
    model.add(Dense(256, activation='relu'))
    model.add(Dense(128, activation='relu'))
    model.add(Dense(32, activation='relu'))
    model.add(Dense(10, activation='softmax'))

    model.compile(loss='categorical_crossentropy',
                  optimizer='rmsprop',
                  metrics=['accuracy'])
    h = model.fit(X_train, y_train_cat, batch_size=128*4, epochs=10, verbose=1, validation_split=0.3)
Train on 42000 samples, validate on 18000 samples
Epoch 1/10
42000/42000 [==============================] - 0s - loss: 0.5832 - acc: 0.8240 - val_loss: 0.4741 - val_acc: 0.8254
Epoch 2/10
42000/42000 [==============================] - 0s - loss: 0.2057 - acc: 0.9379 - val_loss: 0.1414 - val_acc: 0.9566
Epoch 3/10
42000/42000 [==============================] - 0s - loss: 0.1359 - acc: 0.9585 - val_loss: 0.1454 - val_acc: 0.9548
Epoch 4/10
42000/42000 [==============================] - 0s - loss: 0.0919 - acc: 0.9717 - val_loss: 0.0964 - val_acc: 0.9716
Epoch 5/10

gpu를 사용하면 아래와 같이 한 epoch 당 1초도 안되어서 트레이닝이되는 것을 볼 수 있습니다. 이번엔 cpu로 한 번 모델을 구축해보겠습니다. 아래와 같이 device 이름을 /cpu:0으로 변경한 후 모델을 구축, fitting을 하면, 한 epoch 당 2초가 걸리는 것을 확인할 수 있습니다.

import keras.backend.tensorflow_backend as K
with K.tf.device('/cpu:0'):
    model = Sequential()
    model.add(Dense(512, input_dim=28*28, activation='relu'))
    model.add(Dense(256, activation='relu'))
    model.add(Dense(128, activation='relu'))
    model.add(Dense(32, activation='relu'))
    model.add(Dense(10, activation='softmax'))

    model.compile(loss='categorical_crossentropy',
                  optimizer='rmsprop',
                  metrics=['accuracy'])
    h = model.fit(X_train, y_train_cat, batch_size=128*4, epochs=10, verbose=1, validation_split=0.3)
Train on 42000 samples, validate on 18000 samples
Epoch 1/10
42000/42000 [==============================] - 2s - loss: 0.6009 - acc: 0.8115 - val_loss: 0.3323 - val_acc: 0.8966
Epoch 2/10
42000/42000 [==============================] - 2s - loss: 0.2008 - acc: 0.9404 - val_loss: 0.3604 - val_acc: 0.8832
Epoch 3/10
42000/42000 [==============================] - 2s - loss: 0.1293 - acc: 0.9605 - val_loss: 0.1384 - val_acc: 0.9578
Epoch 4/10
42000/42000 [==============================] - 2s - loss: 0.0914 - acc: 0.9716 - val_loss: 0.1376 - val_acc: 0.9590
Epoch 5/10
42000/42000 [==============================] - 2s - loss: 0.0676 - acc: 0.9796 - val_loss: 0.1145 - val_acc: 0.9674
Epoch 6/10
42000/42000 [==============================] - 2s - loss: 0.0494 - acc: 0.9842 - val_loss: 0.0903 - val_acc: 0.9742


반응형
반응형

Medical Image 분야에서의 Deep Learning 응용


약 100여년 전, 의학분야에 처음 Medical Image가 도입되었을 때 그것은 의학 분야의 패러다임을 바꾸었습니다. X-RAY와 같은 의영상 기술을 통해 비침습적으로 내부 장기들을 볼 수 있고, 이를 통해 병을 진단할 수 있고, 암환자의 경우 자신의 남은 수명 또한 알 수 있었습니다. 최근, Deep Learning 기술의 발전이 이 분야에 적용됨으로써 의영상 분야에 다시 한 번 새로운 가능성을 만들어나가고 있습니다.


CBInsigt에서 제시한 이 HeatMap을 보시면 Medical Image분야에 대한 투자가 2015년에 정점을 찍고 계속해서 높은 관심을 받고 있는 것을 볼 수 있습니다. 그만큼 이 분야에 많은 가능성이 있다는 것을 알 수 있습니다. IBM 연구자에 따르면 Medical Image 데이터가 전체 Medical 데이터의 90%를 차지한다고 합니다. 용량만 놓고 말하면 소위 말하는 "헬스케어 데이터" 의 대부분이 Medical Image 데이터 인 것입니다. 데이터의 양만 보더라도 이 분야가 헬스케어 산업에서 차지하는 비중이 매우 높다는 것을 알 수 있습니다. 영상의학 전문의들은 병원에서 하루에 수많은 영상 데이터를 본다고 합니다. 그러므로 그러한 의사들이 마주치는 데이터로부터 어떤 특징을 추출해서 정보를 효율적으로 보여주는 방식이 진단의 속도와 정확성을 높이고 병원이 더 많은 환자를 처리할 수 있게 되어 사회적 문제 해결에도 도움이 될 수 있는 것이죠.


현재 Medical Image 분야에서 Machine Learning, Deep Learning이 응용되는 부분


Tumor Detection


미국에서는 년간 500만건의 피부암의 발생이 보고된다합니다. 피부암은 미국에서 가장 흔하게 진단되는 암이며, 미국의 헬스케어 시스템에서 80억달러가 매년 피부암 치료에 사용된다고 합니다. 이중에서 악성흑색종(Melanoma)의 경우 치명적인 종양인데, 빠른 진단과 치료가 이루어진다면 높은 확률로 이를 치료할 수 있습니다. 피부암은 언제 진단되느냐에 따라 생존률이 15%~65%로 달라지며, 빠른 진단과 치료가 이루어진다면 5년 생존률은 무려 98%에 달한다고 합니다. 피부암을 진단하기 위해서는 피부암을 영상이미지에서 찾아내는 것(Detection)이 중요합니다. Deep Learning을 통해 피부암과 관련된 특징들을 학습하고 이를 통해 피부암을 찾아내는 것이 응용되는 부분 중 하나입니다.


피부 병변의 양성/악성 분류하는 CNN (출처 - https://web.stanford.edu/~kalouche/cs229.html)


다음으로 폐암(Lung Cancer) Detection에도 DeepLearning이 많이 사용됩니다. 주로 폐의 CT scan 데이터를 통해 암을 Detection 하는 알고리즘이 많이 사용되고 있습니다. (Enlitic 이라는 Medical Image 관련 호주 회사) 이 회사에 보고에 따르면 이미지로부터 폐암의 특성을 찾아내는 정확도가 영상의학 전문의보다 높다고합니다.


Medical Image 분야에서는 데이터를 어떻게 획득하냐는 문제가 있습니다. 데이터가 있어야 이를 통해 학습하는 알고리즘을 만들 수 있기 때문입니다. IBM은 2015년 8월 Merge Health Care라는 의영상업체를 인수함으로써 이러한 문제를 해결하고자 하였습니다. Merge의 홈페이지에 가보면 이제 IBM Watson HealthCare라는 이름이 붙어있습니다. IBM은 Merge의 약 300억개의 Medical 이미지 데이터를 통해 Watson을 학습시켜 의사의 진단을 보조할 수 있도록 하는 방법을 꾸준히 연구해나가고 있습니다.



간암 Segmentation하는 논문의 Groud Truth 데이터 Deep Learning은 이러한 CT 데이터를 학습하여 테스트 데이터가 들어왔을 때,

간의 위치와 종양의 위치를 Segmentation 할 수 있다.


암 전이 Tracking


Medical Image는 non-invasive로 질병을 모니터링함으로써 의학적인 중재에 활용할 수 있습니다. Deep Learning은 시간의 흐름에 따른 영상 데이터를 통해 암의 전이 과정을 추적하는데 활용되기도 합니다. 이 논문은 유방암의 Historical 데이터를 통해 암 전이 과정을 평가한 논문입니다. Fraunhofer Institute for Medical Image Computing 은 2013년도에 딥러닝을 통해 암 이미지의 변화를 추적하는 새로운 툴을 공개하였습니다. 이를 통해 임상의들이 암 치료를 어떻게 할지를 결정할 수 있습니다. 이러한 기술들이 더욱 발전된다면 암의 Progress 모니터링을 자동화할 수 있는 가능성이 있습니다.



Tumor Detection & Classification 사례


병변이 의심되는 지점을 찾더라도 그것이 양성인지 악성인지 분류하는 것이 필요한데 삼성은 초음파 이미지에 딥러닝을 활용하여 유방의 병변을 분석하는데 활용하고 있습니다. 삼성의 시스템은 수많은 유방의 케이스를 학습함으로써, 해당 병변의 특성과 그것이 양성인지 악성인지를 분류해 냅니다. 특히 의영상 분야에서는 한국 스타트업의 활약이 두드러지는데 대표적으로 LunitVuno가 있습니다. Lunit은 유방암 Detection 대회에서 마이크로소프트와 IBM을 제치고 1위에 올라 CB Insight 선정 100대 AI 스타트업에 그 이름을 올린 것으로 유명합니다. 삼성 연구원들이 퇴사후 2014년에 설립한 Vuno의 경우 Medical Image Interpretation분야에서 의사를 보조하는 기술을 개발하고 있습니다. 여기에 머신러닝/딥러닝 기술이 들어가며, 이를 통해 의사의 진단 과정을 더욱 빠르고 정확하게 보조하는 역할을 합니다. 

Vuno의 데모영상(https://youtu.be/i7CS05WvOLE)을 보면 Medical Image 데이터를 통해 DILD(Diffuse Interstitial Lung Disease)를 Detection하는 시스템의 데모를 볼 수 있습니다.



참고

https://www.techemergence.com/deep-learning-applications-in-medical-imaging/


반응형
반응형

Python - 폴더 파일 리스트 가져오기


python에서 운영체제 폴더 아래의 파일들을 불러올 때는 os 패키지를 이용한다. 아래 코드에서 filepath 부분에 운영체제 상에 폴더 path를 적으면 폴더 내부의 파일 이름을 가져올 수 있다.

from os import listdir
from os.path import isfile, join
files = [f for f in listdir('filepath') if isfile(join('filepath', f))]
['Info.txt',
 'Licence.txt',
 'mdb001.pgm',
 'mdb002.pgm',
 'mdb003.pgm',
 'mdb004.pgm',
 'mdb005.pgm',
 'mdb006.pgm',
 'mdb007.pgm',
 'mdb008.pgm',


코드를 실행하면 폴더 내부의 파일들의 이름이 files 리스트에 저장된다. 만약 여기서 특정 문자열을 포함한 파일들만 남기고 싶으면 아래와 같이 문자열의 기본함수인 find함수를 이용한다. -1을 리턴하면 해당 문자열이 없는 것이기 때문에 아래의 if문은 해당 문자열을 포함한 원소만 가져오게 한다.

files = [x for x in files if x.find("mdb") != -1] files

['mdb001.pgm',
 'mdb002.pgm',
 'mdb003.pgm',
 'mdb004.pgm',
 'mdb005.pgm',
 'mdb006.pgm',
 'mdb007.pgm',
 'mdb008.pgm'


반응형
반응형

Keras - CNN ImageDataGenerator 활용하기


keras에서는 이미지데이터 학습을 쉽게하도록 하기위해 다양한 패키지를 제공한다. 그 중 하나가 ImageDataGenerator 클래스이다. ImageDataGenerator 클래스를 통해 객체를 생성할 때 파라미터를 전달해주는 것을 통해 데이터의 전처리를 쉽게할 수 있고, 또 이 객체의 flow_from_directory 메소드를 활용하면 폴더 형태로된 데이터 구조를 바로 가져와서 사용할 수 있다. 이 과정은 매우 직관적이고 코드도 ImageDataGenerator를 사용하지 않는 방법에 비해 상당히 짧아진다. 환경은 keras tensorflow backend를 이용하였다.



1. 라이브러리 임포트

# Part 1 - Building the CNN # Importing the Keras libraries and packages from keras.models import Sequential from keras.layers import Conv2D from keras.layers import MaxPooling2D from keras.layers import Flatten from keras.layers import Dense

2. 모델 작성


ImageDataGenerator 클래스를 이용하는 것과 독립적으로 CNN 네트워크를 만들어준다. Input Image의 크기는 64x64이며, Conv-Pool-Conv-Pool-Fully Connected Layer로 이어지는 아주 간단한 구조의 CNN 모델이다. 데이터는 binary 데이터이기 때문에 activation function은 sigmoid함수 이며 손실 함수로 binary_crossentropy, 최적화 함수로는 adam을 사용한다.

# Initialising the CNN
classifier = Sequential()

# Step 1 - Convolution
classifier.add(Conv2D(32, (3, 3), input_shape = (64, 64, 3), activation = 'relu'))

# Step 2 - Pooling
classifier.add(MaxPooling2D(pool_size = (2, 2)))

# Adding a second convolutional layer
classifier.add(Conv2D(32, (3, 3), activation = 'relu'))
classifier.add(MaxPooling2D(pool_size = (2, 2)))

# Step 3 - Flattening
classifier.add(Flatten())

# Step 4 - Full connection
classifier.add(Dense(units = 128, activation = 'relu'))
classifier.add(Dense(units = 1, activation = 'sigmoid'))

# Compiling the CNN
classifier.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy'])

3. ImageDataGenerator를 통한 트레이닝, 테스트 데이터 만들기


ImageDataGenerator를 만들 때 아래와 같이 rescale, shear_range, zoom_range, horizontal_flip을 설정해줌으로써 해당 데이터의 전처리를 어떻게 할지를 정해준다. 이 때 파라미터가 무엇을 뜻하는지를 정리하면 아래와 같다. (https://keras.io/preprocessing/image/)

  • shear_range: Float. Shear Intensity (Shear angle in counter-clockwise direction as radians)
  • zoom_range: Float or [lower, upper]. Range for random zoom. If a float,
  • horizontal_flip: Boolean. Randomly flip inputs horizontally.
  • rescale: rescaling factor. Defaults to None. If None or 0, no rescaling is applied, otherwise we multiply the data by the value provided (before applying any other transformation).
# Part 2 - Fitting the CNN to the images
from keras.preprocessing.image import ImageDataGenerator

train_datagen = ImageDataGenerator(rescale = 1./255,
                                   shear_range = 0.2,
                                   zoom_range = 0.2,
                                   horizontal_flip = True)

test_datagen = ImageDataGenerator(rescale = 1./255)

training_set = train_datagen.flow_from_directory('dataset/training_set',
                                                 target_size = (64, 64),
                                                 batch_size = 32,
                                                 class_mode = 'binary')

test_set = test_datagen.flow_from_directory('dataset/test_set',
                                            target_size = (64, 64),
                                            batch_size = 32,
                                            class_mode = 'binary')

classifier.fit_generator(training_set,
                         steps_per_epoch = 300,
                         epochs = 25,
                         validation_data = test_set,
                         validation_steps = 2000)

또한 flow_from_directory 메소드를 사용하면 폴더구조를 그대로 가져와서 ImageDataGenerator 객체의 실제 데이터를 채워준다. 이 데이터를 불러올 때 앞서 정의한 파라미터로 전처리를 한다. 마지막으로 fit_generator 함수를 실행함으로써 fitting이 이루어진다. 이 예제의 경우 ImageDataGenerator 객체를 사용하였기 때문에 fit_generator 함수를 통해 fitting한다. steps_per_epoch은 한 번 epoch 돌 때, 데이터를 몇 번 볼 것인가를 정해준다. [트레이닝데이터수/배치사이즈]를 사용하면 되는듯하다. validation_steps는 한 번 epoch 돌 고난 후, validation set을 통해 validation accuracy를 측정할 때 validation set을 몇 번 볼 것인지를 정해준다. 이 때도 마찬가지로 [validation data수/배치사이즈]를 사용하면 된다. 즉 ImageDataGenerator를 쓴 경우, fit_generator를 사용하면 된다고 기억하면 된다. 폴더 구조는 아래와 같이 하면 된다. flow_from_directory에 넣어준 경로(dataset/training_set) 밑에 이런식으로 class(cats, dogs) 별로 폴더를 만들고 폴더 밑에 이미지들을 넣어준다. 그러면 알아서 labeling을 하게 된다.





4. 테스트셋 예측하기


output = classifier.predict_generator(test_set, steps=5)
print(test_set.class_indices)
print(output)
{'cats': 0, 'dogs': 1}
[[ 0.58327454]
 [ 0.08756679]
 [ 0.44407782]
 [ 0.66460747]
 [ 0.38810217]
 [ 0.52190965]
 [ 0.67696238]
 [ 0.67470866]
 [ 0.77020335]
 [ 0.68121213]
 [ 0.66256768]
 [ 0.82018822]
...


반응형