ResNet18和ResNet50的keras实现

注意低版本的keras对一些包的引用方式跟高版本有区别,注意看章节1的代码注释部分。

TensorFlow跟Keras也有版本的对应关系,https://master–floydhub-docs.netlify.app/guides/environments/
例如:
在这里插入图片描述

1.ResNet18

ResNet18

from tensorflow import keras
from tensorflow.keras import layers
# 对于keras==2.0.8应该写成下面这句(pip install keras==2.0.8 -i https://pypi.tuna.tsinghua.edu.cn/simple):
# from tensorflow.python.keras import layers

INPUT_SIZE = 224
CLASS_NUM = 1000

# stage_name=2,3,4,5;  block_name=a,b,c
def ConvBlock(input_tensor, num_output, stride, stage_name, block_name):
    filter1, filter2 = num_output

    x = layers.Conv2D(filter1, 3, strides=stride, padding='same', name='res'+stage_name+block_name+'_branch2a')(input_tensor)
    x = layers.BatchNormalization(name='bn'+stage_name+block_name+'_branch2a')(x)
    x = layers.Activation('relu', name='res'+stage_name+block_name+'_branch2a_relu')(x)

    x = layers.Conv2D(filter2, 3, strides=(1, 1), padding='same', name='res'+stage_name+block_name+'_branch2b')(x)
    x = layers.BatchNormalization(name='bn'+stage_name+block_name+'_branch2b')(x)
    x = layers.Activation('relu', name='res'+stage_name+block_name+'_branch2b_relu')(x)

    shortcut = layers.Conv2D(filter2, 1, strides=stride, padding='same', name='res'+stage_name+block_name+'_branch1')(input_tensor)
    shortcut = layers.BatchNormalization(name='bn'+stage_name+block_name+'_branch1')(shortcut)

    x = layers.add([x, shortcut], name='res'+stage_name+block_name)
    x = layers.Activation('relu', name='res'+stage_name+block_name+'_relu')(x)

    return x

def IdentityBlock(input_tensor, num_output, stage_name, block_name):
    filter1, filter2 = num_output

    x = layers.Conv2D(filter1, 3, strides=(1, 1), padding='same', name='res'+stage_name+block_name+'_branch2a')(input_tensor)
    x = layers.BatchNormalization(name='bn'+stage_name+block_name+'_branch2a')(x)
    x = layers.Activation('relu', name='res'+stage_name+block_name+'_branch2a_relu')(x)

    x = layers.Conv2D(filter2, 3, strides=(1, 1), padding='same', name='res'+stage_name+block_name+'_branch2b')(x)
    x = layers.BatchNormalization(name='bn'+stage_name+block_name+'_branch2b')(x)
    x = layers.Activation('relu', name='res'+stage_name+block_name+'_branch2b_relu')(x)

    shortcut = input_tensor

    x = layers.add([x, shortcut], name='res'+stage_name+block_name)
    x = layers.Activation('relu', name='res'+stage_name+block_name+'_relu')(x)

    return x

def ResNet18(input_shape, class_num):
    input = keras.Input(shape=input_shape, name='input')

    # conv1
    x = layers.Conv2D(64, 7, strides=(2, 2), padding='same', name='conv1')(input)  # 7×7, 64, stride 2
    x = layers.BatchNormalization(name='bn_conv1')(x)
    x = layers.Activation('relu', name='conv1_relu')(x)
    x = layers.MaxPooling2D((3, 3), strides=2, padding='same', name='pool1')(x)   # 3×3 max pool, stride 2

    # conv2_x
    x = ConvBlock(input_tensor=x, num_output=(64, 64), stride=(1, 1), stage_name='2', block_name='a')
    x = IdentityBlock(input_tensor=x, num_output=(64, 64), stage_name='2', block_name='b')

    # conv3_x
    x = ConvBlock(input_tensor=x, num_output=(128, 128), stride=(2, 2), stage_name='3', block_name='a')
    x = IdentityBlock(input_tensor=x, num_output=(128, 128), stage_name='3', block_name='b')

    # conv4_x
    x = ConvBlock(input_tensor=x, num_output=(256, 256), stride=(2, 2), stage_name='4', block_name='a')
    x = IdentityBlock(input_tensor=x, num_output=(256, 256), stage_name='4', block_name='b')

    # conv5_x
    x = ConvBlock(input_tensor=x, num_output=(512, 512), stride=(2, 2), stage_name='5', block_name='a')
    x = IdentityBlock(input_tensor=x, num_output=(512, 512), stage_name='5', block_name='b')

    # average pool, 1000-d fc, softmax
    x = layers.AveragePooling2D((7, 7), strides=(1, 1), name='pool5')(x)
    x = layers.Flatten(name='flatten')(x)
    x = layers.Dense(class_num, activation='softmax', name='fc1000')(x)

    model = keras.Model(input, x, name='resnet18')
    # 对于keras==2.0.8应该写成下面这句,否则会报错:AttributeError: module 'tensorflow.python.keras' has no attribute 'Model'
    # model = keras.models.Model(input, x, name='resnet18')

    model.summary()
    return model

if __name__ == '__main__':
    model = ResNet18((INPUT_SIZE, INPUT_SIZE, 3), CLASS_NUM)
    print('Done.')

train_resnet18.py

from tensorflow import keras
from tensorflow.keras import layers
# 对于keras==2.0.8应该写成:from tensorflow.python.keras import layers
# pip install keras==2.0.8  -i https://pypi.tuna.tsinghua.edu.cn/simple 

INPUT_SIZE = 224
CLASS_NUM = 2

# stage_name=2,3,4,5;  block_name=a,b,c
def ConvBlock(input_tensor, num_output, stride, stage_name, block_name):
    filter1, filter2 = num_output

    x = layers.Conv2D(filter1, 3, strides=stride, padding='same', name='res'+stage_name+block_name+'_branch2a')(input_tensor)
    x = layers.BatchNormalization(name='bn'+stage_name+block_name+'_branch2a')(x)
    x = layers.Activation('relu', name='res'+stage_name+block_name+'_branch2a_relu')(x)

    x = layers.Conv2D(filter2, 3, strides=(1, 1), padding='same', name='res'+stage_name+block_name+'_branch2b')(x)
    x = layers.BatchNormalization(name='bn'+stage_name+block_name+'_branch2b')(x)
    x = layers.Activation('relu', name='res'+stage_name+block_name+'_branch2b_relu')(x)

    shortcut = layers.Conv2D(filter2, 1, strides=stride, padding='same', name='res'+stage_name+block_name+'_branch1')(input_tensor)
    shortcut = layers.BatchNormalization(name='bn'+stage_name+block_name+'_branch1')(shortcut)

    x = layers.add([x, shortcut], name='res'+stage_name+block_name)
    x = layers.Activation('relu', name='res'+stage_name+block_name+'_relu')(x)

    return x

def IdentityBlock(input_tensor, num_output, stage_name, block_name):
    filter1, filter2 = num_output

    x = layers.Conv2D(filter1, 3, strides=(1, 1), padding='same', name='res'+stage_name+block_name+'_branch2a')(input_tensor)
    x = layers.BatchNormalization(name='bn'+stage_name+block_name+'_branch2a')(x)
    x = layers.Activation('relu', name='res'+stage_name+block_name+'_branch2a_relu')(x)

    x = layers.Conv2D(filter2, 3, strides=(1, 1), padding='same', name='res'+stage_name+block_name+'_branch2b')(x)
    x = layers.BatchNormalization(name='bn'+stage_name+block_name+'_branch2b')(x)
    x = layers.Activation('relu', name='res'+stage_name+block_name+'_branch2b_relu')(x)

    shortcut = input_tensor

    x = layers.add([x, shortcut], name='res'+stage_name+block_name)
    x = layers.Activation('relu', name='res'+stage_name+block_name+'_relu')(x)

    return x

def ResNet18(input_shape, class_num):
    input = keras.Input(shape=input_shape, name='input')

    # conv1
    x = layers.Conv2D(64, 7, strides=(2, 2), padding='same', name='conv1')(input)  # 7×7, 64, stride 2
    x = layers.BatchNormalization(name='bn_conv1')(x)
    x = layers.Activation('relu', name='conv1_relu')(x)
    x = layers.MaxPooling2D((3, 3), strides=2, padding='same', name='pool1')(x)   # 3×3 max pool, stride 2

    # conv2_x
    x = ConvBlock(input_tensor=x, num_output=(64, 64), stride=(1, 1), stage_name='2', block_name='a')
    x = IdentityBlock(input_tensor=x, num_output=(64, 64), stage_name='2', block_name='b')

    # conv3_x
    x = ConvBlock(input_tensor=x, num_output=(128, 128), stride=(2, 2), stage_name='3', block_name='a')
    x = IdentityBlock(input_tensor=x, num_output=(128, 128), stage_name='3', block_name='b')

    # conv4_x
    x = ConvBlock(input_tensor=x, num_output=(256, 256), stride=(2, 2), stage_name='4', block_name='a')
    x = IdentityBlock(input_tensor=x, num_output=(256, 256), stage_name='4', block_name='b')

    # conv5_x
    x = ConvBlock(input_tensor=x, num_output=(512, 512), stride=(2, 2), stage_name='5', block_name='a')
    x = IdentityBlock(input_tensor=x, num_output=(512, 512), stage_name='5', block_name='b')

    # average pool, 1000-d fc, softmax
    x = layers.AveragePooling2D((7, 7), strides=(1, 1), name='pool5')(x)
    x = layers.Flatten(name='flatten')(x)
    x = layers.Dense(class_num, activation='softmax', name='fc1000')(x)

    model = keras.Model(input, x, name='resnet18')
    model.summary()
    return model

if __name__ == '__main__':
    model = ResNet18((INPUT_SIZE, INPUT_SIZE, 3), CLASS_NUM)
    print('Done.')

predict_resnet18.py

import matplotlib.pyplot as plt

from ResNet18 import ResNet18
import cv2
import numpy as np
from tensorflow.keras import backend as K   # K.set_image_dim_ordering('tf')
from tensorflow.keras.utils import to_categorical

INPUT_IMG_SIZE = 224
NUM_CLASSES = 2
label_dict = {0:'CAT', 1:'DOG'}

def show_predict_probability(y_gts, predictions, x_imgs, predict_probabilitys, idx):
    for i in range(len(label_dict)):
        print(label_dict[i]+', Probability:%1.9f'%(predict_probabilitys[idx][i]))
    print('label: ', label_dict[int(y_gts[idx])], ', predict: ', label_dict[predictions[idx]])
    plt.figure(figsize=(2, 2))
    plt.imshow(np.reshape(x_imgs[idx], (INPUT_IMG_SIZE, INPUT_IMG_SIZE, 3)))
    plt.show()

def plot_images_labels_prediction(images, labels, prediction, idx, num):
    fig = plt.gcf()
    fig.set_size_inches(12, 14)
    if num>25: num=25
    for i in range(0, num):
        ax = plt.subplot(2, 5, 1+i)
        ax.imshow(images[idx], cmap='binary')
        title = 'labels='+str(labels[idx])
        if len(prediction) > 0:
            title += "prediction="+str(prediction[idx])
        ax.set_title(title, fontsize=10)
        idx += 1
    plt.show()

if __name__ == '__main__':
    log_path = r"D:\02.Work\00.LearnML\003.Net\ResNet\log\\"
    model = ResNet18((224, 224, 3), NUM_CLASSES)
    model.load_weights(log_path+"resnet18.h5")

    ### cat dog dataset
    lines = []
    root_path = r"D:\03.Data\01.CatDog"
    with open(root_path + "\\test.txt") as f:
       lines = f.readlines()

    x_images_normalize = []
    y_labels_onehot = []
    y_labels = []

    for i in range(len(lines)):
        img_path = lines[i].split(";")[0]
        img = cv2.imread(img_path)
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        img = cv2.resize(img, (INPUT_IMG_SIZE, INPUT_IMG_SIZE))
        img = img / 255
        x_images_normalize.append(img)
        label = to_categorical(lines[i].split(";")[1], num_classes=NUM_CLASSES)
        y_labels_onehot.append(label)
        y_labels.append(lines[i].split(";")[1])
    x_images_normalize = np.array(x_images_normalize)
    # x_images_normalize = x_images_normalize.reshape(-1, INPUT_IMG_SIZE, INPUT_IMG_SIZE, 3)
    y_labels_onehot = np.array(y_labels_onehot)

    predict_probability = model.predict(x_images_normalize, verbose=1)
    predict = np.argmax(predict_probability, axis=1)

    plot_images_labels_prediction(x_images_normalize, y_labels, predict, 0, 10)
    show_predict_probability(y_labels, predict, x_images_normalize, predict_probability, 0)
    print('done')

2.ResNet50

ResNet50

from tensorflow import keras
from tensorflow.keras import layers

INPUT_SIZE = 224
CLASS_NUM = 1000

# stage_name=2,3,4,5;  block_name=a,b,c
def ConvBlock(input_tensor, num_output, stride, stage_name, block_name):
    filter1, filter2, filter3 = num_output

    x = layers.Conv2D(filter1, 1, strides=stride, padding='same', name='res'+stage_name+block_name+'_branch2a')(input_tensor)
    x = layers.BatchNormalization(name='bn'+stage_name+block_name+'_branch2a')(x)
    x = layers.Activation('relu', name='res'+stage_name+block_name+'_branch2a_relu')(x)

    x = layers.Conv2D(filter2, 3, strides=(1, 1), padding='same', name='res'+stage_name+block_name+'_branch2b')(x)
    x = layers.BatchNormalization(name='bn'+stage_name+block_name+'_branch2b')(x)
    x = layers.Activation('relu', name='res'+stage_name+block_name+'_branch2b_relu')(x)

    x = layers.Conv2D(filter3, 1, strides=(1, 1), padding='same', name='res'+stage_name+block_name+'_branch2c')(x)
    x = layers.BatchNormalization(name='bn'+stage_name+block_name+'_branch2c')(x)

    shortcut = layers.Conv2D(filter3, 1, strides=stride, padding='same', name='res'+stage_name+block_name+'_branch1')(input_tensor)
    shortcut = layers.BatchNormalization(name='bn'+stage_name+block_name+'_branch1')(shortcut)

    x = layers.add([x, shortcut], name='res'+stage_name+block_name)
    x = layers.Activation('relu', name='res'+stage_name+block_name+'_relu')(x)

    return x

def IdentityBlock(input_tensor, num_output, stage_name, block_name):
    filter1, filter2, filter3 = num_output

    x = layers.Conv2D(filter1, 1, strides=(1, 1), padding='same', name='res'+stage_name+block_name+'_branch2a')(input_tensor)
    x = layers.BatchNormalization(name='bn'+stage_name+block_name+'_branch2a')(x)
    x = layers.Activation('relu', name='res'+stage_name+block_name+'_branch2a_relu')(x)

    x = layers.Conv2D(filter2, 3, strides=(1, 1), padding='same', name='res'+stage_name+block_name+'_branch2b')(x)
    x = layers.BatchNormalization(name='bn'+stage_name+block_name+'_branch2b')(x)
    x = layers.Activation('relu', name='res'+stage_name+block_name+'_branch2b_relu')(x)

    x = layers.Conv2D(filter3, 1, strides=(1, 1), padding='same', name='res'+stage_name+block_name+'_branch2c')(x)
    x = layers.BatchNormalization(name='bn'+stage_name+block_name+'_branch2c')(x)

    shortcut = input_tensor

    x = layers.add([x, shortcut], name='res'+stage_name+block_name)
    x = layers.Activation('relu', name='res'+stage_name+block_name+'_relu')(x)

    return x

def ResNet50(input_shape, class_num):
    input = keras.Input(shape=input_shape, name='input')

    # conv1
    x = layers.Conv2D(64, 7, strides=(2, 2), padding='same', name='conv1')(input)  # 7×7, 64, stride 2
    x = layers.BatchNormalization(name='bn_conv1')(x)
    x = layers.Activation('relu', name='conv1_relu')(x)
    x = layers.MaxPooling2D((3, 3), strides=2, padding='same', name='pool1')(x)   # 3×3 max pool, stride 2

    # conv2_x
    x = ConvBlock(input_tensor=x, num_output=(64, 64, 256), stride=(1, 1), stage_name='2', block_name='a')
    x = IdentityBlock(input_tensor=x, num_output=(64, 64, 256), stage_name='2', block_name='b')
    x = IdentityBlock(input_tensor=x, num_output=(64, 64, 256), stage_name='2', block_name='c')

    # conv3_x
    x = ConvBlock(input_tensor=x, num_output=(128, 128, 512), stride=(2, 2), stage_name='3', block_name='a')
    x = IdentityBlock(input_tensor=x, num_output=(128, 128, 512), stage_name='3', block_name='b')
    x = IdentityBlock(input_tensor=x, num_output=(128, 128, 512), stage_name='3', block_name='c')
    x = IdentityBlock(input_tensor=x, num_output=(128, 128, 512), stage_name='3', block_name='d')

    # conv4_x
    x = ConvBlock(input_tensor=x, num_output=(256, 256, 1024), stride=(2, 2), stage_name='4', block_name='a')
    x = IdentityBlock(input_tensor=x, num_output=(256, 256, 1024), stage_name='4', block_name='b')
    x = IdentityBlock(input_tensor=x, num_output=(256, 256, 1024), stage_name='4', block_name='c')
    x = IdentityBlock(input_tensor=x, num_output=(256, 256, 1024), stage_name='4', block_name='d')
    x = IdentityBlock(input_tensor=x, num_output=(256, 256, 1024), stage_name='4', block_name='e')
    x = IdentityBlock(input_tensor=x, num_output=(256, 256, 1024), stage_name='4', block_name='f')

    # conv5_x
    x = ConvBlock(input_tensor=x, num_output=(512, 512, 2048), stride=(2, 2), stage_name='5', block_name='a')
    x = IdentityBlock(input_tensor=x, num_output=(512, 512, 2048), stage_name='5', block_name='b')
    x = IdentityBlock(input_tensor=x, num_output=(512, 512, 2048), stage_name='5', block_name='c')

    # average pool, 1000-d fc, softmax
    x = layers.AveragePooling2D((7, 7), strides=(1, 1), name='pool5')(x)
    x = layers.Flatten(name='flatten')(x)
    x = layers.Dense(class_num, activation='softmax', name='fc1000')(x)

    model = keras.Model(input, x, name='resnet50')
    model.summary()
    return model

if __name__ == '__main__':
    model = ResNet50((INPUT_SIZE, INPUT_SIZE, 3), CLASS_NUM)
    print('Done.')
  • 0
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用Keras实现ResNet50网络并输入大小为50x50的示例代码: ```python import tensorflow as tf from tensorflow.keras.layers import Input, Conv2D, BatchNormalization, Activation, MaxPooling2D, Add, GlobalAveragePooling2D, Dense from tensorflow.keras.models import Model def resnet_block(inputs, filters, strides=1): x = Conv2D(filters, kernel_size=3, strides=strides, padding='same')(inputs) x = BatchNormalization()(x) x = Activation('relu')(x) x = Conv2D(filters, kernel_size=3, padding='same')(x) x = BatchNormalization()(x) if strides != 1 or inputs.shape[-1] != filters: shortcut = Conv2D(filters, kernel_size=1, strides=strides, padding='same')(inputs) shortcut = BatchNormalization()(shortcut) else: shortcut = inputs x = Add()([x, shortcut]) x = Activation('relu')(x) return x def ResNet50(input_shape=(50,50, 3), num_classes=1000): inputs = Input(shape=input_shape) x = Conv2D(64, kernel_size=7, strides=2, padding='same')(inputs) x = BatchNormalization()(x) x = Activation('relu')(x) x = MaxPooling2D(pool_size=3, strides=2, padding='same')(x) x = resnet_block(x, filters=64) x = resnet_block(x, filters=64) x = resnet_block(x, filters=64) x = resnet_block(x, filters=128, strides=2) x = resnet_block(x, filters=128) x = resnet_block(x, filters=128) x = resnet_block(x, filters=128) x = resnet_block(x, filters=256, strides=2) x = resnet_block(x, filters=256) x = resnet_block(x, filters=256) x = resnet_block(x, filters=256) x = resnet_block(x, filters=256) x = resnet_block(x, filters=256) x = resnet_block(x, filters=512, strides=2) x = resnet_block(x, filters=512) x = resnet_block(x, filters=512) x = GlobalAveragePooling2D()(x) x = Dense(num_classes, activation='softmax')(x) model = Model(inputs=inputs, outputs=x) return model model = ResNet50(input_shape=(50, 50, 3), num_classes=1000) model.summary() ``` 这段代码定义了一个ResNet50网络模型,输入大小为50x50的彩色图像。模型的结构包括卷积层、批归一化层、激活函数层、池化层、残差块、全局平均池化层和全连接层。最后使用`model.summary()`打印出模型的结构信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值