Skip to content

Instantly share code, notes, and snippets.

@keunwoochoi
Last active March 5, 2016 04:45
Show Gist options
  • Save keunwoochoi/cb6952f7d5c097b91b98 to your computer and use it in GitHub Desktop.
Save keunwoochoi/cb6952f7d5c097b91b98 to your computer and use it in GitHub Desktop.
def design_residual_model(setting_dict):
''''''
def design_for_mel():
''''''
model = keras.layers.containers.Sequential() # it's a CONTAINER, not MODEL.
# set numbers
image_patch_sizes = [[3,3]]*num_layers
vgg_modi_weight, pool_sizes = get_residual_weights(num_layers=num_layers)
setting_dict['vgg_modi_weight'] = vgg_modi_weight
height_input = height
width_input = width
num_channel_input = 1
for conv_idx in range(num_layers):
print '= design for mel - conv layer blocks %d will be added = ' % conv_idx
n_feat_here = int(num_stacks[conv_idx]*vgg_modi_weight[conv_idx][0])
# residual block 0
this_node_name = 'residual_block_%d_0' % conv_idx
name_prefix = 'Conv_%d_0' % conv_idx
model.add(my_residual_blocks.building_residual_block(name_prefix,
input_shape=(num_channel_input, height_input, width_input),
n_feature_maps=n_feat_here,
kernel_sizes=image_patch_sizes[conv_idx]
))
last_node_name = this_node_name
# REMOVE TWO BLOCKS FOR SIMPLE CODE IN GIST
# residual block 3
# the last one : subsamples and increase #channels
this_node_name = 'residual_block_%d_3' % conv_idx
try:
n_feat_next = int(num_stacks[conv_idx+1]*vgg_modi_weight[conv_idx+1][0])
except:
pass
name_prefix = 'Conv_%d_3' % conv_idx
model.add(my_residual_blocks.building_residual_block(name_prefix,
input_shape=(n_feat_here, height_input, width_input),
n_feature_maps=n_feat_next,
kernel_sizes=image_patch_sizes[conv_idx],
is_subsample=True,
subsample=pool_sizes[conv_idx]
))
last_node_name = this_node_name
height_input /= pool_sizes[conv_idx][0]
width_input /= pool_sizes[conv_idx][1]
num_channel_input = n_feat_next
this_node_name = 'residual_block_output'
# model.add_output(name=this_node_name, input=last_node_name)
return model
#-------------- design_residual_model -------------------#
#--------------------------------------------------------#
n_skips = setting_dict['n_skips']
tf_type = setting_dict['tf_type']
height = setting_dict["height_image"]
width = setting_dict["width_image"]
num_labels = setting_dict["dim_labels"]
num_layers = setting_dict["num_layers"]
num_fc_layers = setting_dict["num_fc_layers"]
dropouts_fc_layers = setting_dict["dropouts_fc_layers"]
nums_units_fc_layers = setting_dict["nums_units_fc_layers"]
num_stacks = setting_dict["num_feat_maps"]
dropouts_fc_layers = setting_dict["dropouts_fc_layers"]
num_channels = 1
nb_maxout_feature = setting_dict['nb_maxout_feature']
#--------------------------------------------------------#
sys.setrecursionlimit(99999)
# start the model!
model = keras.models.Sequential()
# [residual-based Conv layers]
residual_blocks = design_for_mel()
model.add(residual_blocks)
# [Prepare to add classifier]
residual_output_shape = residual_blocks.output_shape
classifier_input_shape = residual_output_shape[1:]
# [Classifier]
# I HAVE SAME PROBLEM WITHOUT THIS CLASSIFIER BLOCK
# model.add(my_classifier_blocks.building_classifier_block(setting_dict, classifier_input_shape))
return model
import keras
from keras.layers.containers import Sequential, Graph
from keras.layers.core import Layer, Dense, Dropout, Activation, Flatten, MaxoutDense
from keras.layers.convolutional import Convolution2D, MaxPooling2D, ZeroPadding2D
from keras.layers.normalization import BatchNormalization
from keras.activations import relu
class Identity(Layer):
def get_output(self, train):
return self.get_input(train)
def building_residual_block(name_prefix, input_shape, n_feature_maps, kernel_sizes=None, n_skip=2, is_subsample=False, subsample=None):
''' Building block of layers for residual learning.
Code based on https://github.com/ndronen/modeling/blob/master/modeling/residual.py
but modification of wrong relu(f)+x thing and it's for conv layer
It can be used for both cases whether it subsamples or not.
name_prefix : prefix for layer names.
n_feature_maps: number of feature maps. In ResidualNet it increases whenever image is downsampled.
n_skip : number of layers.
is_subsample : If it is True, the layers subsamples (2,2) to reduce the size.
kernel_sizes : list or tuple, (3,3) or [3,3] for example
subsample : tuple, (2,2) or (1,2) for example. Used only if is_MP
'''
print ' - Create residual building block named %s' % name_prefix
print ' input shape:', input_shape
print ' kernel size:', kernel_sizes
kernel_row, kernel_col = kernel_sizes
block = keras.layers.containers.Graph()
# set input shape
input_name = '%s_x' % name_prefix
block.add_input(input_name, input_shape=input_shape)
prev_output = input_name
# set short-cut
shortcut_output = '%s_identity'%name_prefix
block.add_node(Identity(input_shape=input_shape), name=shortcut_output,
input=prev_output)
is_expand_channels = not (input_shape[0] == n_feature_maps) # including the first layer and every subsamples
# more setting on the short-cut
if is_subsample or is_expand_channels:
shortcut_conv_name = '%s_shortcut_conv'
if is_subsample: # to expand the number of channel from 1 to n_feature_maps
print ' - Input channels: %d ---> num feature maps on out: %d' % (input_shape[0], n_feature_maps)
block.add_node(Convolution2D(n_feature_maps, 1, 1,
border_mode='valid',
subsample=subsample), # is input_shape necessary in this case?
name=shortcut_conv_name,
input=shortcut_output)
elif is_expand_channels:
block.add_node(Convolution2D(n_feature_maps, 1, 1,
border_mode='same'),
name=shortcut_conv_name,
input=shortcut_output)
shortcut_output = shortcut_conv_name
# add conv layers...
for i in range(n_skip-1):
if i == 0 and is_subsample:
# taking care of subsampling
# as 'valid' 3x3 conv reduces the size but valid1x1 (for shortcut) doesn't
# zero should be padded here.
print ' - Zero padding on the feature map to subsample.'
# zero pad
layer_name = '%s_pad_%d' % (name_prefix, i)
block.add_node(ZeroPadding2D(padding=(1,1)),
name=layer_name,
input=prev_output)
prev_output = layer_name
# conv
layer_name = '%s_conv_%d' % (name_prefix, i)
layer = Convolution2D(n_feature_maps, kernel_row, kernel_col,
border_mode='valid',
subsample=subsample)
block.add_node(layer, name=layer_name, input=prev_output)
prev_output = layer_name
else:
layer_name = '%s_conv_%d' % (name_prefix, i)
layer = Convolution2D(n_feature_maps, kernel_row, kernel_col, border_mode='same')
block.add_node(layer, name=layer_name, input=prev_output)
prev_output = layer_name
layer_name = '%s_BN_%d' % (name_prefix, i)
try:
block.add_node(BatchNormalization(axis=1), name=layer_name, input=prev_output)
except TypeError:
pdb.set_trace()
prev_output = layer_name
layer_name = '%s_relu_%d' % (name_prefix, i)
block.add_node(Activation('relu'), name=layer_name, input=prev_output)
prev_output = layer_name
i += 1
layer_name = '%s_conv_%d' % (name_prefix, i)
layer = Convolution2D(n_feature_maps, kernel_row, kernel_col, border_mode='same')
block.add_node(layer, name=layer_name, input=prev_output)
prev_output = layer_name
layer_name = '%s_BN_%d' % (name_prefix, i)
block.add_node(BatchNormalization(axis=1),
name=layer_name,
input=prev_output)
prev_output = layer_name
# According to http://torch.ch/blog/2016/02/04/resnets.html,
# BN before merge is desired.
layer_name = '%s_relu_%d' % (name_prefix, i)
block.add_node(Activation('relu'),
name=layer_name,
inputs=[prev_output, shortcut_output],
merge_mode='sum')
prev_output = layer_name
# output
layer_name = '%s_output' % name_prefix
block.add_output(name=layer_name, input=prev_output)
return block
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment