Last active
March 5, 2016 04:45
-
-
Save keunwoochoi/cb6952f7d5c097b91b98 to your computer and use it in GitHub Desktop.
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
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 |
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
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