提交 967fa064 编写于 作者: 别团等shy哥发育's avatar 别团等shy哥发育

NasNet架构复现--CVPR2018

上级 1d99602c
...@@ -2,7 +2,7 @@ import tensorflow as tf ...@@ -2,7 +2,7 @@ import tensorflow as tf
from tensorflow.keras import layers from tensorflow.keras import layers
from tensorflow.keras.models import Model from tensorflow.keras.models import Model
from tensorflow.keras import backend from tensorflow.keras import backend
from plot_model import plot_model
def correct_pad(inputs, kernel_size): def correct_pad(inputs, kernel_size):
"""返回一个元组,用于带有下采样的2D卷积的零填充. """返回一个元组,用于带有下采样的2D卷积的零填充.
...@@ -33,7 +33,9 @@ def _adjust_block(p, # 需要修改的输入张量 ...@@ -33,7 +33,9 @@ def _adjust_block(p, # 需要修改的输入张量
block_id=None): block_id=None):
channel_dim = 1 if backend.image_data_format() == 'channels_first' else -1 channel_dim = 1 if backend.image_data_format() == 'channels_first' else -1
img_dim = 2 if backend.image_data_format() == 'channels_first' else -2 img_dim = 2 if backend.image_data_format() == 'channels_first' else -2
ip_shape = backend.int_shape(ip) ip_shape = backend.int_shape(ip)
if p is not None: if p is not None:
p_shape = backend.int_shape(p) p_shape = backend.int_shape(p)
...@@ -88,6 +90,7 @@ def _separable_conv_block(ip, # 输入张量 ...@@ -88,6 +90,7 @@ def _separable_conv_block(ip, # 输入张量
kernel_size=(3, 3), # 可分离卷积的内核大小 kernel_size=(3, 3), # 可分离卷积的内核大小
strides=(1, 1), # 用于下采样的跨步卷积 strides=(1, 1), # 用于下采样的跨步卷积
block_id=None): block_id=None):
# channel_dim = 1 if backend.image_data_format() == 'channels_first' else -1
with backend.name_scope('separable_conv_block_%s' % block_id): with backend.name_scope('separable_conv_block_%s' % block_id):
x = layers.Activation('relu')(ip) x = layers.Activation('relu')(ip)
if strides == (2, 2): if strides == (2, 2):
...@@ -119,8 +122,8 @@ def _separable_conv_block(ip, # 输入张量 ...@@ -119,8 +122,8 @@ def _separable_conv_block(ip, # 输入张量
# Adds a Reduction cell for NASNet-A(原论文图4) # Adds a Reduction cell for NASNet-A(原论文图4)
def _reduction_a_cell(ip, # 输入张量 def _reduction_a_cell(ip, # 输入张量x
p, # 输入张量 p, # 输入张量p
filters, # 输出filters的数量 filters, # 输出filters的数量
block_id=None): block_id=None):
channel_dim = 1 if backend.image_data_format() == 'channels_first' else -1 channel_dim = 1 if backend.image_data_format() == 'channels_first' else -1
...@@ -204,6 +207,7 @@ def _normal_a_cell(ip, # 输入张量x ...@@ -204,6 +207,7 @@ def _normal_a_cell(ip, # 输入张量x
h = layers.Activation('relu')(ip) h = layers.Activation('relu')(ip)
h = layers.Conv2D(filters=filters, h = layers.Conv2D(filters=filters,
kernel_size=(1, 1), kernel_size=(1, 1),
strides=(1,1),
padding='same', padding='same',
use_bias=False, use_bias=False,
kernel_initializer='he_normal', kernel_initializer='he_normal',
...@@ -232,12 +236,13 @@ def _normal_a_cell(ip, # 输入张量x ...@@ -232,12 +236,13 @@ def _normal_a_cell(ip, # 输入张量x
x4_1 = layers.AveragePooling2D(pool_size=(3, 3), x4_1 = layers.AveragePooling2D(pool_size=(3, 3),
strides=(1, 1), strides=(1, 1),
padding='same', padding='same',
name='normal-left4_%s' % block_id)(p) name='normal_left4_%s' % block_id)(p)
x4_2 = layers.AveragePooling2D(pool_size=(3, 3), x4_2 = layers.AveragePooling2D(pool_size=(3, 3),
strides=(1, 1), strides=(1, 1),
padding='same', padding='same',
name='normal_right4_%s' % block_id)(p) name='normal_right4_%s' % block_id)(p)
x4 = layers.add([x4_1, x4_2], name='normal_add_4_%s' % block_id) x4 = layers.add([x4_1, x4_2], name='normal_add_4_%s' % block_id)
with backend.name_scope('block_5'): with backend.name_scope('block_5'):
x5 = _separable_conv_block(h, filters, block_id='normal_left5_%s' % block_id) x5 = _separable_conv_block(h, filters, block_id='normal_left5_%s' % block_id)
x5 = layers.add([x5, h], name='normal_add_5_%s' % block_id) x5 = layers.add([x5, h], name='normal_add_5_%s' % block_id)
...@@ -262,7 +267,7 @@ def NASNet(input_shape=None, # 输入shape ...@@ -262,7 +267,7 @@ def NASNet(input_shape=None, # 输入shape
if default_size is None: if default_size is None:
default_size = 331 default_size = 331
img_input = layers.Input(shape=input_shape) img_input = layers.Input(shape=input_shape)
inputs=img_input inputs = img_input
filters = penultimate_filters // 24 filters = penultimate_filters // 24
...@@ -293,27 +298,28 @@ def NASNet(input_shape=None, # 输入shape ...@@ -293,27 +298,28 @@ def NASNet(input_shape=None, # 输入shape
p, p,
filters * filter_multiplier ** 2, filters * filter_multiplier ** 2,
block_id='reduce_%d' % (2 * num_blocks)) block_id='reduce_%d' % (2 * num_blocks))
p=p0 if not skip_reduction else p p = p0 if not skip_reduction else p
for i in range(num_blocks): for i in range(num_blocks):
x,p=_normal_a_cell(x, x, p = _normal_a_cell(x,
p, p,
filters*filter_multiplier**2, filters * filter_multiplier ** 2,
block_id='%d'%(2*num_blocks+i+1)) block_id='%d' % (2 * num_blocks + i + 1))
x=layers.Activation('relu')(x) x = layers.Activation('relu')(x)
if include_top: if include_top:
x=layers.GlobalAveragePooling2D()(x) x = layers.GlobalAveragePooling2D()(x)
x=layers.Dense(classes,activation=classifier_activation, x = layers.Dense(classes, activation=classifier_activation,
name='predictions')(x) name='predictions')(x)
else: else:
if pooling=='avg': if pooling == 'avg':
x=layers.GlobalAveragePooling2D()(x) x = layers.GlobalAveragePooling2D()(x)
elif pooling=='max': elif pooling == 'max':
x=layers.GlobalMaxPooling2D()(x) x = layers.GlobalMaxPooling2D()(x)
model=Model(inputs,x,name='NASNet') model = Model(inputs, x, name='NASNet')
return model return model
def NASNetMobile(input_shape=None, def NASNetMobile(input_shape=None,
include_top=True, include_top=True,
weights='imagenet', weights='imagenet',
...@@ -332,6 +338,29 @@ def NASNetMobile(input_shape=None, ...@@ -332,6 +338,29 @@ def NASNetMobile(input_shape=None,
pooling=pooling, pooling=pooling,
classes=classes, classes=classes,
default_size=224) default_size=224)
def NASNetLarge(input_shape=None,
include_top=True,
weights='imagenet',
input_tensor=None,
pooling=None,
classes=1000,
classifier_activation='softmax'):
return NASNet(input_shape,
penultimate_filters=4032,
num_blocks=6,
stem_block_filters=96,
skip_reduction=True,
filter_multiplier=2,
include_top=include_top,
weights=weights,
input_tensor=input_tensor,
pooling=pooling,
classes=classes,
default_size=331,
classifier_activation=classifier_activation)
if __name__ == '__main__': if __name__ == '__main__':
model=NASNetMobile(input_shape=(224,224,3),classes=1000) model = NASNetMobile(input_shape=(224, 224, 3), classes=1000)
model.summary() # model=NASNetLarge(input_shape=(224,224,3),classes=1000)
\ No newline at end of file model.summary()
# plot_model(model,to_file='img/NASNetMobile.pdf')
from tensorflow.keras.applications import NASNetMobile
model=NASNetMobile(include_top=True,
input_shape=(224,224,3),
classes=1000)
model.summary()
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册