Programing/Python programming

Multi-view image deep learing with CNN-LSTM

sosal 2019. 4. 3. 22:35
반응형

https://machinelearningmastery.com/cnn-long-short-term-memory-networks/

 

CNN Long Short-Term Memory Networks

Gentle introduction to CNN LSTM recurrent neural networks with example Python code. Input with spatial structure, like images, cannot be modeled easily with the standard Vanilla LSTM. The CNN Long Short-Term Memory Network or CNN LSTM for short is an LSTM

machinelearningmastery.com

 

Objectives:

Axial, Sagittal, Coronal 3가지 Input을 동시에 받아, classification을 해야 할 일이 생김

 

1. 기존의 CNN은 하나의 이미지밖에 받지 못한다.

2. 3개의 Input을 동시에 받아 각자 처리하는 CNN을 ensemble로 묶기엔 모델이 너무 커진다.

# 3개의 Input을 받아서 Fully conntected layer단만 연결하여 loss를 주는 방법도 있는 것 같은데..

 

이미지 3장을 연속으로 받아서 RNN으로 Prediction 하면 더 편할 것 같아서

CNN-RNN을 공부해볼 겸 포스팅을 시작한다.

 

 

이 글에서 RNN은 GRU도 사용할 수 있지만, LSTM을 사용한다.

Input 데이터가 다수의 Image나 Video처럼,

time까지 고려했을 때 3차원인 데이터가 들어오는 경우 기본적인 RNN 알고리즘으로는 처리하기 어렵다.

 

따라서 CNN을 통해서 2-dimension 이미지를 1차원의 vector로 만들어준 후, RNN을 적용함으로써

RNN 분석을 가능하게 한다.

 

 

RNN의 데이터 구조는 아주 쉽게 말하면 다음과 같다.

- 하나의 샘플에 해당되는 x는 t개의 벡터를, y는 t개의 값을 가진다.

(t = time point)

 

따라서 한 point에 2개의 값을 가지는 경우의 예를 아래와 같이 들 수 있다.

 

 

sample_size = 12800
x_seed = [[1,1], [0,0], [0,0], [0,0], [0,0], [0,0]]
y_seed = [1, 0.8, 0.6, 0, 0, 0]
 
x_train = np.array( [[x_seed] * sample_size]).reshape(sample_size, len(x_seed), 1)
y_train = np.array( [[y_seed] * sample_size]).reshape(sample_size, len(y_seed), 1)
 
model = Sequential()
model.add(SimpleRNN(1, activation='tanh', return_sequences = True) )
model.add(TimeDistributed(Dense(1, activation = "sigmoid")))
model.compile(loss = "mse", optimizer = "rmsprop")
 
model.fit(x_train, y_train, epochs = 10, batch_size = 32, verbose = T)
 

 

결국 CNN-LSTM의 구조는

 

x_seed = [ [[1,1],[1,1]],

               [[0,0], [0,0]],

               [[0,0], [0,0]],

               [[0,0], [0,0]],

               [[0,0], [0,0]],

               [[0,0], [0,0]]]

 

위와 같이 2차원의 matrix가 time-point 수 만큼 존재하는 Input에 대하여,

 

x_seed = [[1,1], [0,0], [0,0], [0,0], [0,0], [0,0]]

과 같이, 1차원 벡터가 t개 존재하는 RNN이 입력받을 수 있는 형태로 바꾸는 것이 목적이다.

 

Convolutional Neural Network Long Short-Term Memory Network Architecture

위 이미지와 구조는 (https://machinelearningmastery.com/cnn-long-short-term-memory-networks/) 에서 가져옴.

 

결국 CNN Model은 time-step별 2D 이미지에서 1D feature vector로, Feature extraction의 역할을 수행하는 것이며

아래 LSTM (RNN)은 Feature를 time-step별 Feature들을 통해 Output을 내는 역할을 수행하게 되는 것이다.

 

가장 쉬운 방법은 CNN 모델을 따로 구성하고,

CNN 모델을 TimeDistributed() function으로 감싸는 것.

 

CNN = Sequential()
CNN.add(Conv2D(...))
CNN.add(MaxPooling2D(...))
CNN.add(Flatten())

 

# define LSTM model
model = Sequential()
model.add(TimeDistributed(CNN, ...))
model.add(LSTM(..))
model.add(Dense(...))

 

 

예를 들면, 다음과 같은 구성도 가능하다.

 

CNN = Sequential()

RESNET = keras.applications.resnet50.ResNet50(include_top=False,

                                    weights='imagenet', input_tensor=None,

                                    input_shape=(224,224,3), pooling=None, classes=2)

CNN.add(RESNET)

CNN.add(MaxPooling2D())

CNN.add( Flatten() )

model = Sequential()
model.add(TimeDistributed(CNN))

model.add(LSTM(7, activation='tanh', return_sequences = False) )

model.add(Dense(2, activation='relu'))

model.compile(optimizer='adam',

                    loss='categorical_crossentropy',
                    metrics=['accuracy'])