기존 케라스 모델들의 경우 CNN과 RNN을 결합할 때 feature map을 만드는 모델과 Feature map을 바탕으로 RNN을 적용하는 모델 이렇게 두개로 나누어 모델을 생성하는 형식인데, 이러한 형태의 모델링은 Feature Map 이 용량을 많이 차지하게 되므로 큰 문제가 될 수도 있다. 따라서 가급적 모델이 커넥션 된 형태가 좋을 것이라 생각되었지만 마땅한 코드를 찾지 못해서 시간이 생겨 해당 형태로 레이어를 만들어 보았다.

def feature_model():
    feature_extractor = tf.keras.applications.InceptionV3(
        weights="imagenet",
        include_top=False,
        pooling="avg",
        input_shape=(240, 320, 3),
    )
    preprocess_input = tf.keras.applications.inception_v3.preprocess_input

    inputs = tf.keras.Input((240, 320, 3))
    preprocessed = preprocess_input(inputs)
    outputs = feature_extractor(preprocessed)
    return tf.keras.Model(inputs, 
    	outputs, name="feature_extractor")

def my_rnn_model():
    tf.keras.backend.clear_session()
    tf.random.set_seed(42)

    inputs = tf.keras.Input((125,2048))
    x1=tf.keras.layers.GRU(64, return_sequences=True)(inputs)
    x1=tf.keras.layers.GRU(16)(x1)
    x1=tf.keras.layers.Dropout(.3)(x1)
    x1=tf.keras.layers.Dense(512)(x1)
    x1=tf.keras.layers.Dense(3,activation='softmax',name='output1')(x1)

    x2=tf.keras.layers.GRU(64, return_sequences=True)(inputs)
    x2=tf.keras.layers.GRU(16)(x2)
    x2=tf.keras.layers.Dropout(.3)(x2)
    x2=tf.keras.layers.Dense(256)(x2)
    x2=tf.keras.layers.Dense(3,activation='softmax',name='output2')(x2)
    rnn_model=tf.keras.Model(inputs,[x1,x2])
    return rnn_model


with tf.device("/gpu:0"):
    make_feature=feature_model()
    
Keras documentation: Video Classification with a CNN-RNN Architecture
Keras documentation

구현한 형태는 아래와 같다. 포스팅 후 안 사실이지만 모델을 쪼개는 이유는 모델 메모리 문제인 것 같다. 당연히 피쳐를 뽑기 위해사용한 모델은 매우 큰 크기를 자랑하기때문에 문제가 되는 것 같기도하다.

import tensorflow as tf

feature_extractor = tf.keras.applications.InceptionV3(
    weights="imagenet",
    include_top=False,
    pooling="avg",
    input_shape=(240, 320, 3),
)
preprocess_input = tf.keras.applications.inception_v3.preprocess_input

inp=tf.keras.layers.Input((125,240,320,3))
out=tf.keras.layers.concatenate(
	[tf.keras.layers.Reshape((1,-1))(
    	feature_extractor(
        	preprocess_input(i))) for i in tf.unstack(
            	inp, axis=1)],axis=1)

feture_model=tf.keras.Model(inp,out)

x1=tf.keras.layers.GRU(64, return_sequences=True)(
	feture_model.output)
x1=tf.keras.layers.GRU(16)(x1)
x1=tf.keras.layers.Dropout(.3)(x1)
x1=tf.keras.layers.Dense(512)(x1)
x1=tf.keras.layers.Dense(3,
	activation='softmax',name='output1')(x1)

x2=tf.keras.layers.GRU(64, return_sequences=True)(
	feture_model.output)
x2=tf.keras.layers.GRU(16)(x2)
x2=tf.keras.layers.Dropout(.3)(x2)
x2=tf.keras.layers.Dense(256)(x2)
x2=tf.keras.layers.Dense(3,
	activation='softmax',name='output2')(x2)

rnn_model=tf.keras.Model(feture_model.input,[x1,x2])