[Keras] fix convert_pooling with same pad (#322)
This commit is contained in:
Родитель
53361fae2a
Коммит
4bd92a4a21
|
@ -16,6 +16,14 @@ def _check_data_format(keras_layer):
|
||||||
raise ValueError("Keras frontend currently supports data_format = channels_last only.")
|
raise ValueError("Keras frontend currently supports data_format = channels_last only.")
|
||||||
|
|
||||||
|
|
||||||
|
def _get_pad_pair(input1d, kernel1d, stride1d):
|
||||||
|
out1d = (input1d + stride1d - 1) // stride1d
|
||||||
|
pad = np.maximum((out1d - 1) * stride1d + kernel1d - input1d, 0)
|
||||||
|
pad_before = pad // 2
|
||||||
|
pad_after = pad - pad_before
|
||||||
|
return [pad_before, pad_after]
|
||||||
|
|
||||||
|
|
||||||
def _convert_activation(insym, keras_layer, _):
|
def _convert_activation(insym, keras_layer, _):
|
||||||
if isinstance(keras_layer, str):
|
if isinstance(keras_layer, str):
|
||||||
act_type = keras_layer
|
act_type = keras_layer
|
||||||
|
@ -120,6 +128,8 @@ def _convert_convolution(insym, keras_layer, symtab):
|
||||||
dilation = [keras_layer.dilation_rate[0], keras_layer.dilation_rate[1]]
|
dilation = [keras_layer.dilation_rate[0], keras_layer.dilation_rate[1]]
|
||||||
else:
|
else:
|
||||||
dilation = [keras_layer.dilation_rate, keras_layer.dilation_rate]
|
dilation = [keras_layer.dilation_rate, keras_layer.dilation_rate]
|
||||||
|
kernel_h = (kernel_h - 1) * dilation[0] + 1
|
||||||
|
kernel_w = (kernel_w - 1) * dilation[1] + 1
|
||||||
stride_h, stride_w = keras_layer.strides
|
stride_h, stride_w = keras_layer.strides
|
||||||
params = {'weight': symtab.new_const(weight),
|
params = {'weight': symtab.new_const(weight),
|
||||||
'kernel_size': [kernel_h, kernel_w],
|
'kernel_size': [kernel_h, kernel_w],
|
||||||
|
@ -141,14 +151,8 @@ def _convert_convolution(insym, keras_layer, symtab):
|
||||||
elif keras_layer.padding == 'same':
|
elif keras_layer.padding == 'same':
|
||||||
in_h = keras_layer.input.shape[1].value
|
in_h = keras_layer.input.shape[1].value
|
||||||
in_w = keras_layer.input.shape[2].value
|
in_w = keras_layer.input.shape[2].value
|
||||||
out_h = (in_h + stride_h - 1) // stride_h
|
pad_t, pad_b = _get_pad_pair(in_h, kernel_h, stride_h)
|
||||||
out_w = (in_w + stride_w - 1) // stride_w
|
pad_l, pad_r = _get_pad_pair(in_w, kernel_w, stride_w)
|
||||||
pad_h = np.maximum((out_h - 1) * stride_h + kernel_h - in_h, 0)
|
|
||||||
pad_w = np.maximum((out_w - 1) * stride_w + kernel_w - in_w, 0)
|
|
||||||
pad_t = pad_h // 2
|
|
||||||
pad_l = pad_w // 2
|
|
||||||
pad_b = pad_h - pad_t
|
|
||||||
pad_r = pad_w - pad_l
|
|
||||||
insym = _sym.pad(data=insym, pad_width=((0, 0), (0, 0), (pad_t, pad_b), (pad_l, pad_r)))
|
insym = _sym.pad(data=insym, pad_width=((0, 0), (0, 0), (pad_t, pad_b), (pad_l, pad_r)))
|
||||||
else:
|
else:
|
||||||
raise TypeError("Unsupported padding type : {}".format(keras_layer.padding))
|
raise TypeError("Unsupported padding type : {}".format(keras_layer.padding))
|
||||||
|
@ -187,14 +191,8 @@ def _convert_separable_convolution(insym, keras_layer, symtab):
|
||||||
elif keras_layer.padding == 'same':
|
elif keras_layer.padding == 'same':
|
||||||
in_h = keras_layer.input.shape[1].value
|
in_h = keras_layer.input.shape[1].value
|
||||||
in_w = keras_layer.input.shape[2].value
|
in_w = keras_layer.input.shape[2].value
|
||||||
out_h = (in_h + stride_h - 1) // stride_h
|
pad_t, pad_b = _get_pad_pair(in_h, kernel_h, stride_h)
|
||||||
out_w = (in_w + stride_w - 1) // stride_w
|
pad_l, pad_r = _get_pad_pair(in_w, kernel_w, stride_w)
|
||||||
pad_h = np.maximum((out_h - 1) * stride_h + kernel_h - in_h, 0)
|
|
||||||
pad_w = np.maximum((out_w - 1) * stride_w + kernel_w - in_w, 0)
|
|
||||||
pad_t = pad_h // 2
|
|
||||||
pad_l = pad_w // 2
|
|
||||||
pad_b = pad_h - pad_t
|
|
||||||
pad_r = pad_w - pad_l
|
|
||||||
insym = _sym.pad(data=insym, pad_width=(
|
insym = _sym.pad(data=insym, pad_width=(
|
||||||
(0, 0), (0, 0), (pad_t, pad_b), (pad_l, pad_r)))
|
(0, 0), (0, 0), (pad_t, pad_b), (pad_l, pad_r)))
|
||||||
else:
|
else:
|
||||||
|
@ -242,23 +240,18 @@ def _convert_pooling(insym, keras_layer, symtab):
|
||||||
pool_h, pool_w = keras_layer.pool_size
|
pool_h, pool_w = keras_layer.pool_size
|
||||||
stride_h, stride_w = keras_layer.strides
|
stride_h, stride_w = keras_layer.strides
|
||||||
params = {'pool_size': [pool_h, pool_w],
|
params = {'pool_size': [pool_h, pool_w],
|
||||||
'strides': [stride_h, stride_w]}
|
'strides': [stride_h, stride_w],
|
||||||
|
'padding': [0, 0]}
|
||||||
if keras_layer.padding == 'valid':
|
if keras_layer.padding == 'valid':
|
||||||
params['padding'] = [0, 0]
|
pass
|
||||||
|
# we insert a separate pad operator
|
||||||
elif keras_layer.padding == 'same':
|
elif keras_layer.padding == 'same':
|
||||||
in_h = keras_layer.input.shape[1].value
|
in_h = keras_layer.input.shape[1].value
|
||||||
in_w = keras_layer.input.shape[2].value
|
in_w = keras_layer.input.shape[2].value
|
||||||
out_h = (in_h + stride_h - 1) // stride_h
|
pad_t, pad_b = _get_pad_pair(in_h, pool_h, stride_h)
|
||||||
out_w = (in_w + stride_w - 1) // stride_w
|
pad_l, pad_r = _get_pad_pair(in_w, pool_w, stride_w)
|
||||||
pad_h = np.maximum((out_h - 1) * stride_h + pool_h - in_h, 0)
|
insym = _sym.pad(data=insym, pad_width=(
|
||||||
pad_w = np.maximum((out_w - 1) * stride_w + pool_w - in_w, 0)
|
(0, 0), (0, 0), (pad_t, pad_b), (pad_l, pad_r)))
|
||||||
pad_t = pad_h // 2
|
|
||||||
pad_l = pad_w // 2
|
|
||||||
pad_b = pad_h - pad_t
|
|
||||||
pad_r = pad_w - pad_l
|
|
||||||
params['padding'] = [pad_t, pad_l]
|
|
||||||
if pad_b > pad_t and pad_r > pad_l:
|
|
||||||
params['ceil_mode'] = True
|
|
||||||
else:
|
else:
|
||||||
raise TypeError("Unsupported padding type : {}".format(keras_layer.padding))
|
raise TypeError("Unsupported padding type : {}".format(keras_layer.padding))
|
||||||
if pool_type == 'MaxPooling2D':
|
if pool_type == 'MaxPooling2D':
|
||||||
|
@ -349,13 +342,11 @@ def _convert_concat(insym, keras_layer, _):
|
||||||
|
|
||||||
|
|
||||||
def _convert_reshape(insym, keras_layer, _):
|
def _convert_reshape(insym, keras_layer, _):
|
||||||
shape = keras_layer.shape if hasattr(keras_layer, 'shape') else \
|
shape = keras_layer.shape if hasattr(keras_layer, 'shape') \
|
||||||
keras_layer.target_shape if hasattr(keras_layer, 'target_shape') else\
|
else keras_layer.target_shape if hasattr(keras_layer, 'target_shape') \
|
||||||
None
|
else None
|
||||||
|
|
||||||
if shape is None:
|
if shape is None:
|
||||||
raise TypeError("No shape attribute in reshape layer: {}".format(keras_layer))
|
raise TypeError("No shape attribute in reshape layer: {}".format(keras_layer))
|
||||||
|
|
||||||
return _sym.reshape(insym, shape=shape)
|
return _sym.reshape(insym, shape=shape)
|
||||||
|
|
||||||
|
|
||||||
|
@ -485,13 +476,11 @@ def from_keras(model):
|
||||||
else:
|
else:
|
||||||
predecessors = []
|
predecessors = []
|
||||||
inbound_nodes = keras_layer.inbound_nodes if hasattr(keras_layer, 'inbound_nodes') \
|
inbound_nodes = keras_layer.inbound_nodes if hasattr(keras_layer, 'inbound_nodes') \
|
||||||
else keras_layer._inbound_nodes if hasattr(keras_layer, '_inbound_nodes') \
|
else keras_layer._inbound_nodes if hasattr(keras_layer, '_inbound_nodes') \
|
||||||
else None
|
else None
|
||||||
|
|
||||||
if inbound_nodes is None:
|
if inbound_nodes is None:
|
||||||
raise TypeError("Unknown layer type or unsupported Keras version : {}"
|
raise TypeError("Unknown layer type or unsupported Keras version : {}"
|
||||||
.format(keras_layer))
|
.format(keras_layer))
|
||||||
|
|
||||||
for node in inbound_nodes:
|
for node in inbound_nodes:
|
||||||
for pred in node.inbound_layers:
|
for pred in node.inbound_layers:
|
||||||
predecessors.append(pred.name)
|
predecessors.append(pred.name)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче