Created
March 3, 2021 04:41
-
-
Save jainxy/9f54e4cf94d05e1dc90dad4b4b6d5348 to your computer and use it in GitHub Desktop.
Model architecture samples
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
A collection of models we'll use to attempt to classify videos. | |
""" | |
from keras.layers import Dense, Flatten, Dropout, ZeroPadding3D | |
from keras.layers.recurrent import LSTM | |
from keras.models import Sequential, load_model | |
from keras.optimizers import Adam, RMSprop | |
from keras.layers.wrappers import TimeDistributed | |
from keras.layers.convolutional import (Conv2D, MaxPooling3D, Conv3D, | |
MaxPooling2D) | |
from collections import deque | |
import sys | |
class TraialModels(): | |
def __init__(self, nb_classes, model, seq_length, | |
saved_model=None, features_length=2048): | |
""" | |
`model` = one of: | |
lstm | |
lrcn | |
mlp | |
conv_3d | |
c3d | |
`nb_classes` = the number of classes to predict | |
`seq_length` = the length of our video sequences | |
`saved_model` = the path to a saved Keras model to load | |
""" | |
# Set defaults. | |
self.seq_length = seq_length | |
self.load_model = load_model | |
self.saved_model = saved_model | |
self.nb_classes = nb_classes | |
self.feature_queue = deque() | |
# Set the metrics. Only use top k if there's a need. | |
metrics = ['accuracy'] | |
if self.nb_classes >= 10: | |
metrics.append('top_k_categorical_accuracy') | |
# Get the appropriate model. | |
if self.saved_model is not None: | |
print("Loading model %s" % self.saved_model) | |
self.model = load_model(self.saved_model) | |
elif model == 'lstm': | |
print("Loading LSTM model.") | |
self.input_shape = (seq_length, features_length) | |
self.model = self.lstm() | |
elif model == 'lrcn': | |
print("Loading CNN-LSTM model.") | |
self.input_shape = (seq_length, 80, 80, 3) | |
self.model = self.lrcn() | |
elif model == 'mlp': | |
print("Loading simple MLP.") | |
self.input_shape = (seq_length, features_length) | |
self.model = self.mlp() | |
elif model == 'conv_3d': | |
print("Loading Conv3D") | |
self.input_shape = (seq_length, 80, 80, 3) | |
self.model = self.conv_3d() | |
elif model == 'c3d': | |
print("Loading C3D") | |
self.input_shape = (seq_length, 80, 80, 3) | |
self.model = self.c3d() | |
else: | |
print("Unknown network.") | |
sys.exit() | |
# Now compile the network. | |
optimizer = Adam(lr=1e-5, decay=1e-6) | |
self.model.compile(loss='categorical_crossentropy', optimizer=optimizer, | |
metrics=metrics) | |
print(self.model.summary()) | |
def lstm(self): | |
"""Simple LSTM network.""" | |
# Model. | |
model = Sequential() | |
model.add(LSTM(2048, return_sequences=False, | |
input_shape=self.input_shape, | |
dropout=0.5)) | |
model.add(Dense(512, activation='relu')) | |
model.add(Dropout(0.5)) | |
model.add(Dense(self.nb_classes, activation='softmax')) | |
return model | |
def lrcn(self): | |
def add_default_block(model, kernel_filters, init, reg_lambda): | |
# conv | |
model.add(TimeDistributed(Conv2D(kernel_filters, (3, 3), padding='same', | |
kernel_initializer=init, kernel_regularizer=L2_reg(l=reg_lambda)))) | |
model.add(TimeDistributed(BatchNormalization())) | |
model.add(TimeDistributed(Activation('relu'))) | |
# conv | |
model.add(TimeDistributed(Conv2D(kernel_filters, (3, 3), padding='same', | |
kernel_initializer=init, kernel_regularizer=L2_reg(l=reg_lambda)))) | |
model.add(TimeDistributed(BatchNormalization())) | |
model.add(TimeDistributed(Activation('relu'))) | |
# max pool | |
model.add(TimeDistributed(MaxPooling2D((2, 2), strides=(2, 2)))) | |
return model | |
initialiser = 'glorot_uniform' | |
reg_lambda = 0.001 | |
model = Sequential() | |
# first (non-default) block | |
model.add(TimeDistributed(Conv2D(32, (7, 7), strides=(2, 2), padding='same', | |
kernel_initializer=initialiser, kernel_regularizer=L2_reg(l=reg_lambda)), | |
input_shape=self.input_shape)) | |
model.add(TimeDistributed(BatchNormalization())) | |
model.add(TimeDistributed(Activation('relu'))) | |
model.add(TimeDistributed(Conv2D(32, (3,3), kernel_initializer=initialiser, kernel_regularizer=L2_reg(l=reg_lambda)))) | |
model.add(TimeDistributed(BatchNormalization())) | |
model.add(TimeDistributed(Activation('relu'))) | |
model.add(TimeDistributed(MaxPooling2D((2, 2), strides=(2, 2)))) | |
# 2nd-5th (default) blocks | |
model = add_default_block(model, 64, init=initialiser, reg_lambda=reg_lambda) | |
model = add_default_block(model, 128, init=initialiser, reg_lambda=reg_lambda) | |
model = add_default_block(model, 256, init=initialiser, reg_lambda=reg_lambda) | |
model = add_default_block(model, 512, init=initialiser, reg_lambda=reg_lambda) | |
# LSTM output head | |
model.add(TimeDistributed(Flatten())) | |
model.add(LSTM(256, return_sequences=False, dropout=0.5)) | |
model.add(LSTM(256, return_sequences=False, dropout=0.5)) | |
model.add(LSTM(256, return_sequences=False, dropout=0.5)) | |
model.add(Dense(self.nb_classes, activation='softmax')) | |
return model | |
def mlp(self): | |
"""A simple MLP.""" | |
# Model. | |
model = Sequential() | |
model.add(Flatten(input_shape=self.input_shape)) | |
model.add(Dense(512)) | |
model.add(Dropout(0.5)) | |
model.add(Dense(512)) | |
model.add(Dropout(0.5)) | |
model.add(Dense(self.nb_classes, activation='softmax')) | |
return model | |
def conv_3d(self): | |
# Model. | |
model = Sequential() | |
model.add(Conv3D( | |
32, (3,3,3), activation='relu', input_shape=self.input_shape | |
)) | |
model.add(MaxPooling3D(pool_size=(1, 2, 2), strides=(1, 2, 2))) | |
model.add(Conv3D(64, (3,3,3), activation='relu')) | |
model.add(MaxPooling3D(pool_size=(1, 2, 2), strides=(1, 2, 2))) | |
model.add(Conv3D(128, (3,3,3), activation='relu')) | |
model.add(Conv3D(128, (3,3,3), activation='relu')) | |
model.add(MaxPooling3D(pool_size=(1, 2, 2), strides=(1, 2, 2))) | |
model.add(Conv3D(256, (2,2,2), activation='relu')) | |
model.add(Conv3D(256, (2,2,2), activation='relu')) | |
model.add(MaxPooling3D(pool_size=(1, 2, 2), strides=(1, 2, 2))) | |
model.add(Flatten()) | |
model.add(Dense(1024)) | |
model.add(Dropout(0.5)) | |
model.add(Dense(1024)) | |
model.add(Dropout(0.5)) | |
model.add(Dense(self.nb_classes, activation='softmax')) | |
return model | |
def c3d(self): | |
model = Sequential() | |
# 1st layer group | |
model.add(Conv3D(64, 3, 3, 3, activation='relu', | |
border_mode='same', name='conv1', | |
subsample=(1, 1, 1), | |
input_shape=self.input_shape)) | |
model.add(MaxPooling3D(pool_size=(1, 2, 2), strides=(1, 2, 2), | |
border_mode='valid', name='pool1')) | |
# 2nd layer group | |
model.add(Conv3D(128, 3, 3, 3, activation='relu', | |
border_mode='same', name='conv2', | |
subsample=(1, 1, 1))) | |
model.add(MaxPooling3D(pool_size=(2, 2, 2), strides=(2, 2, 2), | |
border_mode='valid', name='pool2')) | |
# 3rd layer group | |
model.add(Conv3D(256, 3, 3, 3, activation='relu', | |
border_mode='same', name='conv3a', | |
subsample=(1, 1, 1))) | |
model.add(Conv3D(256, 3, 3, 3, activation='relu', | |
border_mode='same', name='conv3b', | |
subsample=(1, 1, 1))) | |
model.add(MaxPooling3D(pool_size=(2, 2, 2), strides=(2, 2, 2), | |
border_mode='valid', name='pool3')) | |
# 4th layer group | |
model.add(Conv3D(512, 3, 3, 3, activation='relu', | |
border_mode='same', name='conv4a', | |
subsample=(1, 1, 1))) | |
model.add(Conv3D(512, 3, 3, 3, activation='relu', | |
border_mode='same', name='conv4b', | |
subsample=(1, 1, 1))) | |
model.add(MaxPooling3D(pool_size=(2, 2, 2), strides=(2, 2, 2), | |
border_mode='valid', name='pool4')) | |
# 5th layer group | |
model.add(Conv3D(512, 3, 3, 3, activation='relu', | |
border_mode='same', name='conv5a', | |
subsample=(1, 1, 1))) | |
model.add(Conv3D(512, 3, 3, 3, activation='relu', | |
border_mode='same', name='conv5b', | |
subsample=(1, 1, 1))) | |
model.add(ZeroPadding3D(padding=(0, 1, 1))) | |
model.add(MaxPooling3D(pool_size=(2, 2, 2), strides=(2, 2, 2), | |
border_mode='valid', name='pool5')) | |
model.add(Flatten()) | |
# FC layers group | |
model.add(Dense(4096, activation='relu', name='fc6')) | |
model.add(Dropout(0.5)) | |
model.add(Dense(4096, activation='relu', name='fc7')) | |
model.add(Dropout(0.5)) | |
model.add(Dense(self.nb_classes, activation='softmax')) | |
return model | |
##================= 3DCNN | |
model = Sequential() | |
# 1st layer group | |
model.add(Conv3D(64, 3, 3, 3, activation='relu', | |
border_mode='same', name='conv1', | |
subsample=(1, 1, 1), | |
input_shape=self.input_shape)) | |
model.add(MaxPooling3D(pool_size=(1, 2, 2), strides=(1, 2, 2), | |
border_mode='valid', name='pool1')) | |
# 2nd layer group | |
model.add(Conv3D(128, 3, 3, 3, activation='relu', | |
border_mode='same', name='conv2', | |
subsample=(1, 1, 1))) | |
model.add(MaxPooling3D(pool_size=(2, 2, 2), strides=(2, 2, 2), | |
border_mode='valid', name='pool2')) | |
# 3rd layer group | |
model.add(Conv3D(256, 3, 3, 3, activation='relu', | |
border_mode='same', name='conv3a', | |
subsample=(1, 1, 1))) | |
model.add(Conv3D(256, 3, 3, 3, activation='relu', | |
border_mode='same', name='conv3b', | |
subsample=(1, 1, 1))) | |
model.add(MaxPooling3D(pool_size=(2, 2, 2), strides=(2, 2, 2), | |
border_mode='valid', name='pool3')) | |
# 4th layer group | |
model.add(Conv3D(512, 3, 3, 3, activation='relu', | |
border_mode='same', name='conv4a', | |
subsample=(1, 1, 1))) | |
model.add(Conv3D(512, 3, 3, 3, activation='relu', | |
border_mode='same', name='conv4b', | |
subsample=(1, 1, 1))) | |
model.add(MaxPooling3D(pool_size=(2, 2, 2), strides=(2, 2, 2), | |
border_mode='valid', name='pool4')) | |
# 5th layer group | |
model.add(Conv3D(512, 3, 3, 3, activation='relu', | |
border_mode='same', name='conv5a', | |
subsample=(1, 1, 1))) | |
model.add(Conv3D(512, 3, 3, 3, activation='relu', | |
border_mode='same', name='conv5b', | |
subsample=(1, 1, 1))) | |
model.add(ZeroPadding3D(padding=(0, 1, 1))) | |
model.add(MaxPooling3D(pool_size=(2, 2, 2), strides=(2, 2, 2), | |
border_mode='valid', name='pool5')) | |
model.add(GlobalAveragePooling3D()) | |
# FC layers group | |
model.add(Dense(4096, activation='relu', name='fc6')) | |
model.add(Dropout(0.5)) | |
model.add(Dense(4096, activation='relu', name='fc7')) | |
model.add(Dropout(0.5)) | |
model.add(Dense(self.nb_classes, activation='softmax')) | |
return model | |
## 704x396 / maintain aspect ratio | |
## 3DCNN | |
def get_model(width=128, height=128, depth=64): | |
"""Build a 3D convolutional neural network model.""" | |
inputs = keras.Input((width, height, depth, 1)) | |
x = layers.Conv3D(filters=64, kernel_size=3, activation="relu")(inputs) | |
x = layers.MaxPool3D(pool_size=2)(x) | |
x = layers.BatchNormalization()(x) | |
x = layers.Conv3D(filters=64, kernel_size=3, activation="relu")(x) | |
x = layers.MaxPool3D(pool_size=2)(x) | |
x = layers.BatchNormalization()(x) | |
x = layers.Conv3D(filters=128, kernel_size=3, activation="relu")(x) | |
x = layers.MaxPool3D(pool_size=2)(x) | |
x = layers.BatchNormalization()(x) | |
x = layers.Conv3D(filters=256, kernel_size=3, activation="relu")(x) | |
x = layers.MaxPool3D(pool_size=2)(x) | |
x = layers.BatchNormalization()(x) | |
x = layers.GlobalAveragePooling3D()(x) | |
x = layers.Dense(units=512, activation="relu")(x) | |
x = layers.Dropout(0.3)(x) | |
outputs = layers.Dense(units=1, activation="sigmoid")(x) | |
# Define the model. | |
model = keras.Model(inputs, outputs, name="3dcnn") | |
return model | |
# Build model. | |
model = get_model(width=128, height=128, depth=64) | |
model.summary() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment