Style fixes and small bug fixes

This commit is contained in:
Francois Chollet 2016-08-03 11:08:48 -07:00
parent c725f8d354
commit 99f564e972
13 changed files with 177 additions and 86 deletions

@ -53,8 +53,21 @@ model.compile(loss='categorical_crossentropy',
metrics=['accuracy']) metrics=['accuracy'])
history = model.fit(X_train, Y_train, history = model.fit(X_train, Y_train,
batch_size=batch_size, nb_epoch=nb_epoch, batch_size=batch_size, nb_epoch=3,
verbose=1, validation_data=(X_test, Y_test)) verbose=1, validation_data=(X_test, Y_test))
score = model.evaluate(X_test, Y_test, verbose=0) score = model.evaluate(X_test, Y_test, verbose=0)
print('Test score:', score[0]) print('Test score:', score[0])
print('Test accuracy:', score[1]) print('Test accuracy:', score[1])
model.save('tmp.h5')
from keras.models import load_model
model = load_model('tmp.h5')
score = model.evaluate(X_test, Y_test, verbose=0)
print('Test score:', score[0])
print('Test accuracy:', score[1])
model.fit(X_train, Y_train,
batch_size=batch_size, nb_epoch=3,
verbose=1, validation_data=(X_test, Y_test))

@ -1,14 +1,14 @@
'''This script demonstrates how to build a deep residual network '''This script demonstrates how to build a deep residual network
using the Keras functional API. using the Keras functional API.
get_resne50 returns the deep residual network model (50 layers) get_resnet50() returns the deep residual network model (50 layers)
Please visit Kaiming He's GitHub homepage: Please visit Kaiming He's GitHub homepage:
https://github.com/KaimingHe https://github.com/KaimingHe
for more information. for more information.
The related paper is The related paper is
"Deep Residual Learning for Image Recognition" 'Deep Residual Learning for Image Recognition'
Kaiming He, Xiangyu Zhang, Shaoqing Ren, Jian Sun Kaiming He, Xiangyu Zhang, Shaoqing Ren, Jian Sun
http://arxiv.org/abs/1512.03385 http://arxiv.org/abs/1512.03385
@ -17,12 +17,14 @@ Pretrained weights were converted from Kaiming He's caffe model directly.
For now we provide weights for the tensorflow backend only, For now we provide weights for the tensorflow backend only,
thus use 'tf' dim_ordering (e.g. input_shape=(224, 224, 3) for 224*224 color image) thus use 'tf' dim_ordering (e.g. input_shape=(224, 224, 3) for 224*224 color image)
would accelerate the computation, but we also provide weights for 'th' dim_ordering for compatibility. would accelerate the computation, but we also provide weights for 'th' dim_ordering for compatibility.
please donwload them at: You can set your default dim ordering in your Keras config file at ~/.keras/keras.json
http://pan.baidu.com/s/1o8pO2q2 ('th' dim ordering, For China)
http://pan.baidu.com/s/1pLanuTt ('tf' dim ordering, For China)
https://drive.google.com/open?id=0B4ChsjFJvew3NVQ2U041Q0xHRHM ('th' dim ordering, For other countries) please donwload them at:
https://drive.google.com/open?id=0B4ChsjFJvew3NWN5THdxcTdSWmc ('tf' dim ordering, For other countries) http://pan.baidu.com/s/1o8pO2q2 ('th' dim ordering, for China)
http://pan.baidu.com/s/1pLanuTt ('tf' dim ordering, for China)
https://drive.google.com/open?id=0B4ChsjFJvew3NVQ2U041Q0xHRHM ('th' dim ordering, for other countries)
https://drive.google.com/open?id=0B4ChsjFJvew3NWN5THdxcTdSWmc ('tf' dim ordering, for other countries)
@author: BigMoyan, University of Electronic Science and Technology of China @author: BigMoyan, University of Electronic Science and Technology of China
''' '''
@ -44,36 +46,37 @@ import numpy as np
# branch: '1' for shortcut and '2' for main path # branch: '1' for shortcut and '2' for main path
# layer: 'a','b','c'... for different layers in a block # layer: 'a','b','c'... for different layers in a block
def identity_block(input_tensor, kernel_size, filters, stage, block): def identity_block(input_tensor, kernel_size, filters, stage, block):
""" '''The identity_block is the block that has no conv layer at shortcut
the identity_block is the block that has no conv layer at shortcut
params: # Arguments
input_tensor: input tensor input_tensor: input tensor
kernel_size: defualt 3, the kernel size of middle conv layer at main path kernel_size: defualt 3, the kernel size of middle conv layer at main path
filters: list of integers, the nb_filters of 3 conv layer at main path filters: list of integers, the nb_filters of 3 conv layer at main path
stage: integer, current stage label, used for generating layer names stage: integer, current stage label, used for generating layer names
block: 'a','b'..., current block label, used for generating layer names block: 'a','b'..., current block label, used for generating layer names
""" '''
dim_ordering = K.image_dim_ordering() dim_ordering = K.image_dim_ordering()
nb_filter1, nb_filter2, nb_filter3 = filters nb_filter1, nb_filter2, nb_filter3 = filters
if dim_ordering == 'tf': if dim_ordering == 'tf':
axis = 3 bn_axis = 3
else: else:
axis = 1 bn_axis = 1
conv_name_base = 'res' + str(stage) + block + '_branch' conv_name_base = 'res' + str(stage) + block + '_branch'
bn_name_base = 'bn' + str(stage) + block + '_branch' bn_name_base = 'bn' + str(stage) + block + '_branch'
out = Convolution2D(nb_filter1, 1, 1, dim_ordering=dim_ordering, name=conv_name_base + '2a')(input_tensor) out = Convolution2D(nb_filter1, 1, 1, dim_ordering=dim_ordering, name=conv_name_base + '2a')(input_tensor)
out = BatchNormalization(axis=axis, name=bn_name_base + '2a')(out) out = BatchNormalization(axis=bn_axis, name=bn_name_base + '2a')(out)
out = Activation('relu')(out) out = Activation('relu')(out)
out = out = Convolution2D(nb_filter2, kernel_size, kernel_size, border_mode='same', out = out = Convolution2D(nb_filter2, kernel_size, kernel_size, border_mode='same',
dim_ordering=dim_ordering, name=conv_name_base + '2b')(out) dim_ordering=dim_ordering, name=conv_name_base + '2b')(out)
out = BatchNormalization(axis=axis, name=bn_name_base + '2b')(out) out = BatchNormalization(axis=bn_axis, name=bn_name_base + '2b')(out)
out = Activation('relu')(out) out = Activation('relu')(out)
out = Convolution2D(nb_filter3, 1, 1, dim_ordering=dim_ordering, name=conv_name_base + '2c')(out) out = Convolution2D(nb_filter3, 1, 1, dim_ordering=dim_ordering, name=conv_name_base + '2c')(out)
out = BatchNormalization(axis=axis, name=bn_name_base + '2c')(out) out = BatchNormalization(axis=bn_axis, name=bn_name_base + '2c')(out)
out = merge([out, input_tensor], mode='sum') out = merge([out, input_tensor], mode='sum')
out = Activation('relu')(out) out = Activation('relu')(out)
@ -81,9 +84,9 @@ def identity_block(input_tensor, kernel_size, filters, stage, block):
def conv_block(input_tensor, kernel_size, filters, stage, block, strides=(2, 2)): def conv_block(input_tensor, kernel_size, filters, stage, block, strides=(2, 2)):
""" '''conv_block is the block that has a conv layer at shortcut
conv_block is the block that has a conv layer at shortcut
params: # Arguments
input_tensor: input tensor input_tensor: input tensor
kernel_size: defualt 3, the kernel size of middle conv layer at main path kernel_size: defualt 3, the kernel size of middle conv layer at main path
filters: list of integers, the nb_filters of 3 conv layer at main path filters: list of integers, the nb_filters of 3 conv layer at main path
@ -92,32 +95,32 @@ def conv_block(input_tensor, kernel_size, filters, stage, block, strides=(2, 2))
Note that from stage 3, the first conv layer at main path is with subsample=(2,2) Note that from stage 3, the first conv layer at main path is with subsample=(2,2)
And the shortcut should has subsample=(2,2) as well And the shortcut should has subsample=(2,2) as well
""" '''
nb_filter1, nb_filter2, nb_filter3 = filters nb_filter1, nb_filter2, nb_filter3 = filters
dim_ordering = K.image_dim_ordering() dim_ordering = K.image_dim_ordering()
if dim_ordering == 'tf': if dim_ordering == 'tf':
axis = 3 bn_axis = 3
else: else:
axis = 1 bn_axis = 1
conv_name_base = 'res' + str(stage) + block + '_branch' conv_name_base = 'res' + str(stage) + block + '_branch'
bn_name_base = 'bn' + str(stage) + block + '_branch' bn_name_base = 'bn' + str(stage) + block + '_branch'
out = Convolution2D(nb_filter1, 1, 1, subsample=strides, out = Convolution2D(nb_filter1, 1, 1, subsample=strides,
dim_ordering=dim_ordering, name=conv_name_base + '2a')(input_tensor) dim_ordering=dim_ordering, name=conv_name_base + '2a')(input_tensor)
out = BatchNormalization(axis=axis, name=bn_name_base + '2a')(out) out = BatchNormalization(axis=bn_axis, name=bn_name_base + '2a')(out)
out = Activation('relu')(out) out = Activation('relu')(out)
out = Convolution2D(nb_filter2, kernel_size, kernel_size, border_mode='same', out = Convolution2D(nb_filter2, kernel_size, kernel_size, border_mode='same',
dim_ordering=dim_ordering, name=conv_name_base + '2b')(out) dim_ordering=dim_ordering, name=conv_name_base + '2b')(out)
out = BatchNormalization(axis=axis, name=bn_name_base + '2b')(out) out = BatchNormalization(axis=bn_axis, name=bn_name_base + '2b')(out)
out = Activation('relu')(out) out = Activation('relu')(out)
out = Convolution2D(nb_filter3, 1, 1, dim_ordering=dim_ordering, name=conv_name_base + '2c')(out) out = Convolution2D(nb_filter3, 1, 1, dim_ordering=dim_ordering, name=conv_name_base + '2c')(out)
out = BatchNormalization(axis=axis, name=bn_name_base + '2c')(out) out = BatchNormalization(axis=bn_axis, name=bn_name_base + '2c')(out)
shortcut = Convolution2D(nb_filter3, 1, 1, subsample=strides, shortcut = Convolution2D(nb_filter3, 1, 1, subsample=strides,
dim_ordering=dim_ordering, name=conv_name_base + '1')(input_tensor) dim_ordering=dim_ordering, name=conv_name_base + '1')(input_tensor)
shortcut = BatchNormalization(axis=axis, name=bn_name_base + '1')(shortcut) shortcut = BatchNormalization(axis=bn_axis, name=bn_name_base + '1')(shortcut)
out = merge([out, shortcut], mode='sum') out = merge([out, shortcut], mode='sum')
out = Activation('relu')(out) out = Activation('relu')(out)
@ -125,48 +128,46 @@ def conv_block(input_tensor, kernel_size, filters, stage, block, strides=(2, 2))
def read_img(img_path): def read_img(img_path):
""" '''This function returns a preprocessed image
this function returns preprocessed image '''
"""
dim_ordering = K.image_dim_ordering() dim_ordering = K.image_dim_ordering()
mean = (103.939, 116.779, 123.68) mean = (103.939, 116.779, 123.68)
img = load_img(img_path, target_size=(224, 224)) img = load_img(img_path, target_size=(224, 224))
img = img_to_array(img, dim_ordering=dim_ordering) img = img_to_array(img, dim_ordering=dim_ordering)
# decenterize if dim_ordering == 'th':
img[0, :, :] -= mean[0] img[0, :, :] -= mean[0]
img[1, :, :] -= mean[1] img[1, :, :] -= mean[1]
img[2, :, :] -= mean[2] img[2, :, :] -= mean[2]
# 'RGB'->'BGR' # 'RGB'->'BGR'
if dim_ordering == 'th':
img = img[::-1, :, :] img = img[::-1, :, :]
else: else:
img[:, :, 0] -= mean[0]
img[:, :, 1] -= mean[1]
img[:, :, 2] -= mean[2]
img = img[:, :, ::-1] img = img[:, :, ::-1]
# expand dim for test
img = np.expand_dims(img, axis=0) img = np.expand_dims(img, axis=0)
return img return img
def get_resnet50(): def get_resnet50():
""" '''This function returns the 50-layer residual network model
this function returns the 50-layer residual network model
you should load pretrained weights if you want to use it directly. you should load pretrained weights if you want to use it directly.
Note that since the pretrained weights is converted from caffemodel Note that since the pretrained weights is converted from caffemodel
the order of channels for input image should be 'BGR' (the channel order of caffe) the order of channels for input image should be 'BGR' (the channel order of caffe)
""" '''
if K.image_dim_ordering() == 'tf': if K.image_dim_ordering() == 'tf':
inp = Input(shape=(224, 224, 3)) inp = Input(shape=(224, 224, 3))
axis = 3 bn_axis = 3
else: else:
inp = Input(shape=(3, 224, 224)) inp = Input(shape=(3, 224, 224))
axis = 1 bn_axis = 1
dim_ordering = K.image_dim_ordering() dim_ordering = K.image_dim_ordering()
out = ZeroPadding2D((3, 3), dim_ordering=dim_ordering)(inp) out = ZeroPadding2D((3, 3), dim_ordering=dim_ordering)(inp)
out = Convolution2D(64, 7, 7, subsample=(2, 2), dim_ordering=dim_ordering, name='conv1')(out) out = Convolution2D(64, 7, 7, subsample=(2, 2), dim_ordering=dim_ordering, name='conv1')(out)
out = BatchNormalization(axis=axis, name='bn_conv1')(out) out = BatchNormalization(axis=bn_axis, name='bn_conv1')(out)
out = Activation('relu')(out) out = Activation('relu')(out)
out = MaxPooling2D((3, 3), strides=(2, 2), dim_ordering=dim_ordering)(out) out = MaxPooling2D((3, 3), strides=(2, 2), dim_ordering=dim_ordering)(out)
@ -200,17 +201,19 @@ def get_resnet50():
if __name__ == '__main__': if __name__ == '__main__':
K.set_image_dim_ordering('tf')
weights_file = K.image_dim_ordering() + '_dim_ordering_resnet50.h5' weights_file = K.image_dim_ordering() + '_dim_ordering_resnet50.h5'
resnet_model = get_resnet50() resnet_model = get_resnet50()
resnet_model.load_weights(weights_file) resnet_model.load_weights(weights_file)
test_img1 = read_img('cat.jpg')
test_img2 = read_img('airplane.jpg') # you may download synset_words from the address given at the begining of this file
# you may download synset_words from address given at the begining of this file class_table = open('synset_words.txt', 'r')
class_table = open('synset_words', 'r')
lines = class_table.readlines() lines = class_table.readlines()
print "result for test 1 is"
test_img1 = read_img('cat.jpg')
print 'result for test 1 is'
print lines[np.argmax(resnet_model.predict(test_img1)[0])] print lines[np.argmax(resnet_model.predict(test_img1)[0])]
print "result for test 2 is"
test_img2 = read_img('elephant.jpg')
print 'result for test 2 is'
print lines[np.argmax(resnet_model.predict(test_img2)[0])] print lines[np.argmax(resnet_model.predict(test_img2)[0])]
class_table.close() class_table.close()

@ -11,6 +11,7 @@ from .common import get_uid
from .common import cast_to_floatx from .common import cast_to_floatx
from .common import image_dim_ordering from .common import image_dim_ordering
from .common import set_image_dim_ordering from .common import set_image_dim_ordering
from .common import is_keras_tensor
_keras_base_dir = os.path.expanduser('~') _keras_base_dir = os.path.expanduser('~')
if not os.access(_keras_base_dir, os.W_OK): if not os.access(_keras_base_dir, os.W_OK):
@ -60,3 +61,10 @@ elif _BACKEND == 'tensorflow':
from .tensorflow_backend import * from .tensorflow_backend import *
else: else:
raise Exception('Unknown backend: ' + str(_BACKEND)) raise Exception('Unknown backend: ' + str(_BACKEND))
def backend():
'''Publicly accessible method
for determining the current backend.
'''
return _BACKEND

@ -69,3 +69,10 @@ def get_uid(prefix=''):
def reset_uids(): def reset_uids():
global _UID_PREFIXES global _UID_PREFIXES
_UID_PREFIXES = defaultdict(int) _UID_PREFIXES = defaultdict(int)
def is_keras_tensor(x):
if hasattr(x, '_keras_shape'):
return True
else:
return False

@ -696,10 +696,10 @@ class Layer(object):
' outbound layers. ' ' outbound layers. '
'This will cause part of your model ' 'This will cause part of your model '
'to be disconnected.') 'to be disconnected.')
if not shape:
if hasattr(K, 'int_shape'): if hasattr(K, 'int_shape'):
# auto-infered shape takes priority
shape = K.int_shape(input_tensor) shape = K.int_shape(input_tensor)
else: elif not shape:
raise Exception('`set_input` needs to know the shape ' raise Exception('`set_input` needs to know the shape '
'of the `input_tensor` it receives, but ' 'of the `input_tensor` it receives, but '
'Keras was not able to infer it automatically.' 'Keras was not able to infer it automatically.'
@ -830,6 +830,10 @@ class Layer(object):
'ill-defined for the layer. ' + 'ill-defined for the layer. ' +
'Use `get_output_shape_at(node_index)` instead.') 'Use `get_output_shape_at(node_index)` instead.')
@property
def weights(self):
return self.trainable_weights + self.non_trainable_weights
def set_weights(self, weights): def set_weights(self, weights):
'''Sets the weights of the layer, from Numpy arrays. '''Sets the weights of the layer, from Numpy arrays.
@ -845,7 +849,7 @@ class Layer(object):
raise Exception('You called `set_weights(weights)` on layer "' + self.name + raise Exception('You called `set_weights(weights)` on layer "' + self.name +
'" with a weight list of length ' + str(len(weights)) + '" with a weight list of length ' + str(len(weights)) +
', but the layer was expecting ' + str(len(params)) + ', but the layer was expecting ' + str(len(params)) +
' weights. Provided weights: ' + str(weights)) ' weights. Provided weights: ' + str(weights)[:50] + '...')
if not params: if not params:
return return
weight_value_tuples = [] weight_value_tuples = []

@ -254,11 +254,12 @@ class Convolution2D(Layer):
''' '''
def __init__(self, nb_filter, nb_row, nb_col, def __init__(self, nb_filter, nb_row, nb_col,
init='glorot_uniform', activation='linear', weights=None, init='glorot_uniform', activation='linear', weights=None,
border_mode='valid', subsample=(1, 1), dim_ordering=K.image_dim_ordering(), border_mode='valid', subsample=(1, 1), dim_ordering='default',
W_regularizer=None, b_regularizer=None, activity_regularizer=None, W_regularizer=None, b_regularizer=None, activity_regularizer=None,
W_constraint=None, b_constraint=None, W_constraint=None, b_constraint=None,
bias=True, **kwargs): bias=True, **kwargs):
if dim_ordering == 'default':
dim_ordering = K.image_dim_ordering()
if border_mode not in {'valid', 'same'}: if border_mode not in {'valid', 'same'}:
raise Exception('Invalid border mode for Convolution2D:', border_mode) raise Exception('Invalid border mode for Convolution2D:', border_mode)
self.nb_filter = nb_filter self.nb_filter = nb_filter
@ -526,10 +527,12 @@ class AtrousConvolution2D(Convolution2D):
def __init__(self, nb_filter, nb_row, nb_col, def __init__(self, nb_filter, nb_row, nb_col,
init='glorot_uniform', activation='linear', weights=None, init='glorot_uniform', activation='linear', weights=None,
border_mode='valid', subsample=(1, 1), border_mode='valid', subsample=(1, 1),
atrous_rate=(1, 1), dim_ordering=K.image_dim_ordering(), atrous_rate=(1, 1), dim_ordering='default',
W_regularizer=None, b_regularizer=None, activity_regularizer=None, W_regularizer=None, b_regularizer=None, activity_regularizer=None,
W_constraint=None, b_constraint=None, W_constraint=None, b_constraint=None,
bias=True, **kwargs): bias=True, **kwargs):
if dim_ordering == 'default':
dim_ordering = K.image_dim_ordering()
if border_mode not in {'valid', 'same'}: if border_mode not in {'valid', 'same'}:
raise Exception('Invalid border mode for AtrousConv2D:', border_mode) raise Exception('Invalid border mode for AtrousConv2D:', border_mode)
@ -668,7 +671,7 @@ class SeparableConvolution2D(Layer):
def __init__(self, nb_filter, nb_row, nb_col, def __init__(self, nb_filter, nb_row, nb_col,
init='glorot_uniform', activation='linear', weights=None, init='glorot_uniform', activation='linear', weights=None,
border_mode='valid', subsample=(1, 1), border_mode='valid', subsample=(1, 1),
depth_multiplier=1, dim_ordering=K.image_dim_ordering(), depth_multiplier=1, dim_ordering='default',
depthwise_regularizer=None, pointwise_regularizer=None, depthwise_regularizer=None, pointwise_regularizer=None,
b_regularizer=None, activity_regularizer=None, b_regularizer=None, activity_regularizer=None,
depthwise_constraint=None, pointwise_constraint=None, depthwise_constraint=None, pointwise_constraint=None,
@ -679,6 +682,9 @@ class SeparableConvolution2D(Layer):
raise Exception('SeparableConv2D is only available ' raise Exception('SeparableConv2D is only available '
'with TensorFlow for the time being.') 'with TensorFlow for the time being.')
if dim_ordering == 'default':
dim_ordering = K.image_dim_ordering()
if border_mode not in {'valid', 'same'}: if border_mode not in {'valid', 'same'}:
raise Exception('Invalid border mode for SeparableConv2D:', border_mode) raise Exception('Invalid border mode for SeparableConv2D:', border_mode)
@ -879,10 +885,13 @@ class Convolution3D(Layer):
def __init__(self, nb_filter, kernel_dim1, kernel_dim2, kernel_dim3, def __init__(self, nb_filter, kernel_dim1, kernel_dim2, kernel_dim3,
init='glorot_uniform', activation='linear', weights=None, init='glorot_uniform', activation='linear', weights=None,
border_mode='valid', subsample=(1, 1, 1), dim_ordering=K.image_dim_ordering(), border_mode='valid', subsample=(1, 1, 1), dim_ordering='default',
W_regularizer=None, b_regularizer=None, activity_regularizer=None, W_regularizer=None, b_regularizer=None, activity_regularizer=None,
W_constraint=None, b_constraint=None, W_constraint=None, b_constraint=None,
bias=True, **kwargs): bias=True, **kwargs):
if dim_ordering == 'default':
dim_ordering = K.image_dim_ordering()
if border_mode not in {'valid', 'same'}: if border_mode not in {'valid', 'same'}:
raise Exception('Invalid border mode for Convolution3D:', border_mode) raise Exception('Invalid border mode for Convolution3D:', border_mode)
self.nb_filter = nb_filter self.nb_filter = nb_filter
@ -1074,7 +1083,9 @@ class UpSampling2D(Layer):
`(samples, upsampled_rows, upsampled_cols, channels)` if dim_ordering='tf'. `(samples, upsampled_rows, upsampled_cols, channels)` if dim_ordering='tf'.
''' '''
def __init__(self, size=(2, 2), dim_ordering=K.image_dim_ordering(), **kwargs): def __init__(self, size=(2, 2), dim_ordering='default', **kwargs):
if dim_ordering == 'default':
dim_ordering = K.image_dim_ordering()
self.size = tuple(size) self.size = tuple(size)
assert dim_ordering in {'tf', 'th'}, 'dim_ordering must be in {tf, th}' assert dim_ordering in {'tf', 'th'}, 'dim_ordering must be in {tf, th}'
self.dim_ordering = dim_ordering self.dim_ordering = dim_ordering
@ -1131,7 +1142,9 @@ class UpSampling3D(Layer):
`(samples, upsampled_dim1, upsampled_dim2, upsampled_dim3, channels)` if dim_ordering='tf'. `(samples, upsampled_dim1, upsampled_dim2, upsampled_dim3, channels)` if dim_ordering='tf'.
''' '''
def __init__(self, size=(2, 2, 2), dim_ordering=K.image_dim_ordering(), **kwargs): def __init__(self, size=(2, 2, 2), dim_ordering='default', **kwargs):
if dim_ordering == 'default':
dim_ordering = K.image_dim_ordering()
self.size = tuple(size) self.size = tuple(size)
assert dim_ordering in {'tf', 'th'}, 'dim_ordering must be in {tf, th}' assert dim_ordering in {'tf', 'th'}, 'dim_ordering must be in {tf, th}'
self.dim_ordering = dim_ordering self.dim_ordering = dim_ordering
@ -1222,8 +1235,10 @@ class ZeroPadding2D(Layer):
(samples, depth, first_padded_axis, second_padded_axis) (samples, depth, first_padded_axis, second_padded_axis)
''' '''
def __init__(self, padding=(1, 1), dim_ordering=K.image_dim_ordering(), **kwargs): def __init__(self, padding=(1, 1), dim_ordering='default', **kwargs):
super(ZeroPadding2D, self).__init__(**kwargs) super(ZeroPadding2D, self).__init__(**kwargs)
if dim_ordering == 'default':
dim_ordering = K.image_dim_ordering()
self.padding = tuple(padding) self.padding = tuple(padding)
assert dim_ordering in {'tf', 'th'}, 'dim_ordering must be in {tf, th}' assert dim_ordering in {'tf', 'th'}, 'dim_ordering must be in {tf, th}'
self.dim_ordering = dim_ordering self.dim_ordering = dim_ordering
@ -1280,8 +1295,10 @@ class ZeroPadding3D(Layer):
(samples, depth, first_padded_axis, second_padded_axis, third_axis_to_pad) (samples, depth, first_padded_axis, second_padded_axis, third_axis_to_pad)
''' '''
def __init__(self, padding=(1, 1, 1), dim_ordering=K.image_dim_ordering(), **kwargs): def __init__(self, padding=(1, 1, 1), dim_ordering='default', **kwargs):
super(ZeroPadding3D, self).__init__(**kwargs) super(ZeroPadding3D, self).__init__(**kwargs)
if dim_ordering == 'default':
dim_ordering = K.image_dim_ordering()
self.padding = tuple(padding) self.padding = tuple(padding)
assert dim_ordering in {'tf', 'th'}, 'dim_ordering must be in {tf, th}' assert dim_ordering in {'tf', 'th'}, 'dim_ordering must be in {tf, th}'
self.dim_ordering = dim_ordering self.dim_ordering = dim_ordering

@ -75,7 +75,7 @@ class LocallyConnected1D(Layer):
W_constraint=None, b_constraint=None, W_constraint=None, b_constraint=None,
bias=True, input_dim=None, input_length=None, **kwargs): bias=True, input_dim=None, input_length=None, **kwargs):
if border_mode != 'valid': if border_mode != 'valid':
raise Exception('Invalid border mode for Convolution2D ' raise Exception('Invalid border mode for LocallyConnected1D '
'(only "valid" is supported):', border_mode) '(only "valid" is supported):', border_mode)
self.nb_filter = nb_filter self.nb_filter = nb_filter
self.filter_length = filter_length self.filter_length = filter_length
@ -251,12 +251,14 @@ class LocallyConnected2D(Layer):
def __init__(self, nb_filter, nb_row, nb_col, def __init__(self, nb_filter, nb_row, nb_col,
init='glorot_uniform', activation='linear', weights=None, init='glorot_uniform', activation='linear', weights=None,
border_mode='valid', subsample=(1, 1), border_mode='valid', subsample=(1, 1),
dim_ordering=K.image_dim_ordering(), dim_ordering='default',
W_regularizer=None, b_regularizer=None, activity_regularizer=None, W_regularizer=None, b_regularizer=None, activity_regularizer=None,
W_constraint=None, b_constraint=None, W_constraint=None, b_constraint=None,
bias=True, **kwargs): bias=True, **kwargs):
if dim_ordering == 'default':
dim_ordering = K.image_dim_ordering()
if border_mode != 'valid': if border_mode != 'valid':
raise Exception('Invalid border mode for Convolution2D ' raise Exception('Invalid border mode for LocallyConnected2D '
'(only "valid" is supported):', border_mode) '(only "valid" is supported):', border_mode)
self.nb_filter = nb_filter self.nb_filter = nb_filter
self.nb_row = nb_row self.nb_row = nb_row

@ -114,8 +114,10 @@ class _Pooling2D(Layer):
''' '''
def __init__(self, pool_size=(2, 2), strides=None, border_mode='valid', def __init__(self, pool_size=(2, 2), strides=None, border_mode='valid',
dim_ordering=K.image_dim_ordering(), **kwargs): dim_ordering='default', **kwargs):
super(_Pooling2D, self).__init__(**kwargs) super(_Pooling2D, self).__init__(**kwargs)
if dim_ordering == 'default':
dim_ordering = K.image_dim_ordering()
self.pool_size = tuple(pool_size) self.pool_size = tuple(pool_size)
if strides is None: if strides is None:
strides = self.pool_size strides = self.pool_size
@ -199,7 +201,7 @@ class MaxPooling2D(_Pooling2D):
''' '''
def __init__(self, pool_size=(2, 2), strides=None, border_mode='valid', def __init__(self, pool_size=(2, 2), strides=None, border_mode='valid',
dim_ordering=K.image_dim_ordering(), **kwargs): dim_ordering='default', **kwargs):
super(MaxPooling2D, self).__init__(pool_size, strides, border_mode, super(MaxPooling2D, self).__init__(pool_size, strides, border_mode,
dim_ordering, **kwargs) dim_ordering, **kwargs)
@ -241,7 +243,7 @@ class AveragePooling2D(_Pooling2D):
''' '''
def __init__(self, pool_size=(2, 2), strides=None, border_mode='valid', def __init__(self, pool_size=(2, 2), strides=None, border_mode='valid',
dim_ordering=K.image_dim_ordering(), **kwargs): dim_ordering='default', **kwargs):
super(AveragePooling2D, self).__init__(pool_size, strides, border_mode, super(AveragePooling2D, self).__init__(pool_size, strides, border_mode,
dim_ordering, **kwargs) dim_ordering, **kwargs)
@ -257,8 +259,10 @@ class _Pooling3D(Layer):
''' '''
def __init__(self, pool_size=(2, 2, 2), strides=None, border_mode='valid', def __init__(self, pool_size=(2, 2, 2), strides=None, border_mode='valid',
dim_ordering=K.image_dim_ordering(), **kwargs): dim_ordering='default', **kwargs):
super(_Pooling3D, self).__init__(**kwargs) super(_Pooling3D, self).__init__(**kwargs)
if dim_ordering == 'default':
dim_ordering = K.image_dim_ordering()
self.pool_size = tuple(pool_size) self.pool_size = tuple(pool_size)
if strides is None: if strides is None:
strides = self.pool_size strides = self.pool_size
@ -344,7 +348,7 @@ class MaxPooling3D(_Pooling3D):
''' '''
def __init__(self, pool_size=(2, 2, 2), strides=None, border_mode='valid', def __init__(self, pool_size=(2, 2, 2), strides=None, border_mode='valid',
dim_ordering=K.image_dim_ordering(), **kwargs): dim_ordering='default', **kwargs):
super(MaxPooling3D, self).__init__(pool_size, strides, border_mode, super(MaxPooling3D, self).__init__(pool_size, strides, border_mode,
dim_ordering, **kwargs) dim_ordering, **kwargs)
@ -384,7 +388,7 @@ class AveragePooling3D(_Pooling3D):
''' '''
def __init__(self, pool_size=(2, 2, 2), strides=None, border_mode='valid', def __init__(self, pool_size=(2, 2, 2), strides=None, border_mode='valid',
dim_ordering=K.image_dim_ordering(), **kwargs): dim_ordering='default', **kwargs):
super(AveragePooling3D, self).__init__(pool_size, strides, border_mode, super(AveragePooling3D, self).__init__(pool_size, strides, border_mode,
dim_ordering, **kwargs) dim_ordering, **kwargs)

@ -337,6 +337,7 @@ class Sequential(Model):
self.inbound_nodes[0].output_tensors = self.outputs self.inbound_nodes[0].output_tensors = self.outputs
self.inbound_nodes[0].output_shapes = [self.outputs[0]._keras_shape] self.inbound_nodes[0].output_shapes = [self.outputs[0]._keras_shape]
self.built = False self.built = False
self._flattened_layers = None
def call(self, x, mask=None): def call(self, x, mask=None):
if not self.built: if not self.built:
@ -467,7 +468,7 @@ class Sequential(Model):
''' '''
# support for legacy behavior # support for legacy behavior
for layer in self.flattened_layers: for layer in self.flattened_layers:
nb_param = len(layer.get_weights()) nb_param = len(layer.weights)
layer.set_weights(weights[:nb_param]) layer.set_weights(weights[:nb_param])
weights = weights[nb_param:] weights = weights[nb_param:]

@ -118,8 +118,10 @@ def flip_axis(x, axis):
return x return x
def array_to_img(x, dim_ordering=K.image_dim_ordering(), scale=True): def array_to_img(x, dim_ordering='default', scale=True):
from PIL import Image from PIL import Image
if dim_ordering == 'default':
dim_ordering = K.image_dim_ordering()
if dim_ordering == 'th': if dim_ordering == 'th':
x = x.transpose(1, 2, 0) x = x.transpose(1, 2, 0)
if scale: if scale:
@ -136,7 +138,9 @@ def array_to_img(x, dim_ordering=K.image_dim_ordering(), scale=True):
raise Exception('Unsupported channel number: ', x.shape[2]) raise Exception('Unsupported channel number: ', x.shape[2])
def img_to_array(img, dim_ordering=K.image_dim_ordering()): def img_to_array(img, dim_ordering='default'):
if dim_ordering == 'default':
dim_ordering = K.image_dim_ordering()
if dim_ordering not in ['th', 'tf']: if dim_ordering not in ['th', 'tf']:
raise Exception('Unknown dim_ordering: ', dim_ordering) raise Exception('Unknown dim_ordering: ', dim_ordering)
# image has dim_ordering (height, width, channel) # image has dim_ordering (height, width, channel)
@ -222,7 +226,9 @@ class ImageDataGenerator(object):
horizontal_flip=False, horizontal_flip=False,
vertical_flip=False, vertical_flip=False,
rescale=None, rescale=None,
dim_ordering=K.image_dim_ordering()): dim_ordering='default'):
if dim_ordering == 'default':
dim_ordering = K.image_dim_ordering()
self.__dict__.update(locals()) self.__dict__.update(locals())
self.mean = None self.mean = None
self.std = None self.std = None
@ -446,12 +452,14 @@ class NumpyArrayIterator(Iterator):
def __init__(self, X, y, image_data_generator, def __init__(self, X, y, image_data_generator,
batch_size=32, shuffle=False, seed=None, batch_size=32, shuffle=False, seed=None,
dim_ordering=K.image_dim_ordering(), dim_ordering='default',
save_to_dir=None, save_prefix='', save_format='jpeg'): save_to_dir=None, save_prefix='', save_format='jpeg'):
if y is not None and len(X) != len(y): if y is not None and len(X) != len(y):
raise Exception('X (images tensor) and y (labels) ' raise Exception('X (images tensor) and y (labels) '
'should have the same length. ' 'should have the same length. '
'Found: X.shape = %s, y.shape = %s' % (np.asarray(X).shape, np.asarray(y).shape)) 'Found: X.shape = %s, y.shape = %s' % (np.asarray(X).shape, np.asarray(y).shape))
if dim_ordering == 'default':
dim_ordering = K.image_dim_ordering()
self.X = X self.X = X
self.y = y self.y = y
self.image_data_generator = image_data_generator self.image_data_generator = image_data_generator
@ -493,10 +501,12 @@ class DirectoryIterator(Iterator):
def __init__(self, directory, image_data_generator, def __init__(self, directory, image_data_generator,
target_size=(256, 256), color_mode='rgb', target_size=(256, 256), color_mode='rgb',
dim_ordering=K.image_dim_ordering, dim_ordering='default',
classes=None, class_mode='categorical', classes=None, class_mode='categorical',
batch_size=32, shuffle=True, seed=None, batch_size=32, shuffle=True, seed=None,
save_to_dir=None, save_prefix='', save_format='jpeg'): save_to_dir=None, save_prefix='', save_format='jpeg'):
if dim_ordering == 'default':
dim_ordering = K.image_dim_ordering()
self.directory = directory self.directory = directory
self.image_data_generator = image_data_generator self.image_data_generator = image_data_generator
self.target_size = tuple(target_size) self.target_size = tuple(target_size)

@ -37,11 +37,12 @@ else:
from six.moves.urllib.request import urlretrieve from six.moves.urllib.request import urlretrieve
def get_file(fname, origin, untar=False, md5_hash=None): def get_file(fname, origin, untar=False,
md5_hash=None, cache_subdir='datasets'):
datadir_base = os.path.expanduser(os.path.join('~', '.keras')) datadir_base = os.path.expanduser(os.path.join('~', '.keras'))
if not os.access(datadir_base, os.W_OK): if not os.access(datadir_base, os.W_OK):
datadir_base = os.path.join('/tmp', '.keras') datadir_base = os.path.join('/tmp', '.keras')
datadir = os.path.join(datadir_base, 'datasets') datadir = os.path.join(datadir_base, cache_subdir)
if not os.path.exists(datadir): if not os.path.exists(datadir):
os.makedirs(datadir) os.makedirs(datadir)

@ -1,6 +1,7 @@
from __future__ import print_function from __future__ import print_function
from .generic_utils import get_from_module from .generic_utils import get_from_module
from .np_utils import convert_kernel
from ..layers import * from ..layers import *
from ..models import Model, Sequential, Graph from ..models import Model, Sequential, Graph
from .. import backend as K from .. import backend as K
@ -97,3 +98,22 @@ def print_summary(layers, relevant_nodes=None, line_length=100, positions=[.33,
print('Total params: %s' % total_params) print('Total params: %s' % total_params)
print('_' * line_length) print('_' * line_length)
def convert_all_kernels_in_model(model):
# Note: SeparableConvolution not included
# since only supported by TF.
conv_classes = {
'Convolution1D',
'Convolution2D',
'Convolution3D',
'AtrousConvolution2D',
'Deconvolution2D',
}
to_assign = []
for layer in model.layers:
if layer.__class__.__name__ in conv_classes:
original_w = K.get_value(layer.W)
converted_w = convert_kernel(original_w)
to_assign.append((layer.W, converted_w))
K.batch_set_value(to_assign)

@ -121,6 +121,7 @@ def conv_output_length(input_length, filter_size, border_mode, stride, dilation=
output_length = input_length - dilated_filter_size + 1 output_length = input_length - dilated_filter_size + 1
return (output_length + stride - 1) // stride return (output_length + stride - 1) // stride
def conv_input_length(output_length, filter_size, border_mode, stride): def conv_input_length(output_length, filter_size, border_mode, stride):
if output_length is None: if output_length is None:
return None return None