实现ResNet50 作者:马育民 • 2020-05-12 11:42 • 阅读:10259 # 官方源码网址 [点击](https://github.com/keras-team/keras-applications/blob/master/keras_applications/resnet_common.py "点击") # 分析代码 参见 https://www.malaoshi.top/show_1EF5LiLIgrnW.html # 代码 ### conv1 ``` import tensorflow as tf from tensorflow.keras import layers,models def conv1(input_shape): img_input = layers.Input(shape=input_shape) x = layers.ZeroPadding2D(padding=(3, 3))(img_input) x = layers.Conv2D(64, 7, strides=2)(x) x = layers.BatchNormalization( epsilon=1.001e-5)(x) x = layers.Activation('relu')(x) x = layers.ZeroPadding2D(padding=(1, 1))(x) return img_input,x ``` ### conv2_x到conv5_x的第一个block **注意:** 做加法时,顺序不能调到,否则加载keras ResNet50 预训练模型时会报错,错误如下: ``` ValueError: Shapes (1, 1, 128, 512) and (512, 256, 1, 1) are incompatible ``` ``` def block1(x,filters, stride=1): shortcut=tf.keras.layers.Conv2D(4*filters,1,strides=stride)(x) shortcut = layers.BatchNormalization( epsilon=1.001e-5,)(shortcut) x = layers.Conv2D(filters, 1, strides=stride)(x) x = layers.BatchNormalization( epsilon=1.001e-5)(x) x = layers.Activation('relu')(x) x = layers.Conv2D(filters, 3, padding='SAME')(x) x = layers.BatchNormalization( epsilon=1.001e-5)(x) x = layers.Activation('relu')(x) x = layers.Conv2D(4 * filters, 1)(x) x = layers.BatchNormalization( epsilon=1.001e-5)(x) # 不可调换顺序,否则不能导入tf权重 x = layers.Add()([shortcut,x]) # 使用下面add()也可以 # x=tf.add(shortcut,x) x = layers.Activation('relu')(x) return x ``` ### conv2_x到conv5_x的其他block ``` def block2(x,filters): shortcut=x x = layers.Conv2D(filters, 1)(x) x = layers.BatchNormalization( epsilon=1.001e-5)(x) x = layers.Activation('relu')(x) x = layers.Conv2D(filters, 3, padding='SAME')(x) x = layers.BatchNormalization( epsilon=1.001e-5)(x) x = layers.Activation('relu')(x) x = layers.Conv2D(4 * filters, 1)(x) x = layers.BatchNormalization( epsilon=1.001e-5,)(x) x = layers.Add()([shortcut, x]) # 使用下面add()也可以 # x=tf.add(shortcut,x) x = layers.Activation('relu')(x) return x ``` ### ResNet50 ``` def resnet50(input_shape,weights_path): img_input,x=conv1(input_shape=input_shape) x=tf.keras.layers.MaxPool2D((3,3),2)(x) x=block1(x,64,1) x=block2(x,64) x=block2(x,64) x=block1(x,128,2) x=block2(x,128) x=block2(x,128) x=block2(x,128) x=block1(x,256,2) x=block2(x,256) x=block2(x,256) x=block2(x,256) x=block2(x,256) x=block2(x,256) x=block1(x,512,2) x=block2(x,512) x=block2(x,512) model=tf.keras.Model(img_input,x) if weights_path: model.load_weights(weights_path) print("加载权重成功!") return model ``` ### 测试 ``` model=resnet50(input_shape=(224,224,3),weights_path="/Users/mym/.keras/models/resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5") ``` 原文出处:http://malaoshi.top/show_1EF5VeQUYY0Y.html