1. Basic Block的实现
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers,optimizers,Sequential
# 构建层
class BasicBlock(layers.Layer):
def __init__(self,filter_num,stride=1):
super(BasicBlock, self).__init__()
# strides=1时,得到output会略小于inputsize,所有需要设置padding=‘same’,保证两者相同
# convolution layer = conv + bn + relu
self.conv1 = layers.Conv2D(filter_num,kernel_size=(3,3),strides=stride,padding='same')
self.bn1 = layers.BatchNormalization()
self.relu = layers.Activation('relu') # rulu层没有参数,可以多次使用
# convolution layer = conv + bn + relu
self.conv2 = layers.Conv2D(filter_num,kernel_size=(3,3),strides=stride,padding='same')
self.bn2 = layers.BatchNormalization()
# 短接层
if stride != 1:
self.downsample = Sequential()
self.downsample.add(layers.Conv2D(filter_num,kernel_size=(1,1),strides = stride))
else:
self.downsample = lambda x:x
# 构建前向传播
def call(self,inputs,training=None):
# inputs:[b,h,w,c]
out = self.conv1(inputs)
out = self.bn1(out)
out = self.relu(out)
out = self.conv2(out)
out = self.bn2(out)
identity = self.downsample(inputs)
output = layers.add([out,identity])
output = self.relu(output)
# output = tf.nn.relu(output)
return output
2.Res Block的实现
def build_resblock(self,filter_num,blocks,stride=1):
res_blocks = Sequential()
# 下采样-只有一个具有下采样的能力
res_blocks.add(BasicBlock(filter_num,stride))
for _ in range(1,blocks):
res_blocks.add(BasicBlock(filter_num,stride=1))
return res_blocks
3.ResNet的实现
class ResNet(keras.Model):
# layer_dims,比如:[2,2,2,2] 4个Res Block,每个Res Block包含两个BasicBlock
# num_classes=100 100类
def __init__(self,layer_dims,num_classes=100):
super(ResNet, self).__init__()
# 预处理层
self.stem = Sequential([layers.Conv2D(64,kernel_size=(3,3),strides=(1,1)),
layers.BatchNormalization(),
layers.Activation('relu'),
layers.MaxPool2D(pool_size=