ResNet Keras实现

伪代码:

graph TD
A(导入相应库) --> Z[模型参数设置以及其它配置]
Z --> B[生成训练集,测试集,验证集的三个迭代器] 
B --> C[identity_block函数的编写]
C --> D[bottleneck_block函数的编写]
D --> F[根据resnet网络构建表来构建网络]
F --> G[模型训练与验证]
G --> H[模型保存]
H --> I(模型在测试集上测试)

代码:

from keras.models import Model
from keras.layers import Input, Dense, Dropout, BatchNormalization, Conv2D, MaxPooling2D, AveragePooling2D, concatenate, \
    Activation, ZeroPadding2D
from keras.layers import add, Flatten
from keras.utils import plot_model
from keras.metrics import top_k_categorical_accuracy
from keras.preprocessing.image import ImageDataGenerator
from keras.models import load_model
import os

# Global Constants
NB_CLASS=20
IM_WIDTH=224
IM_HEIGHT=224
train_root='your train dataset'
vaildation_root='your val dataset
test_root='your test dataset'
batch_size=32
EPOCH=60

# train data
train_datagen = ImageDataGenerator(
    width_shift_range=0.1,
    height_shift_range=0.1,
    shear_range=0.1,
    zoom_range=0.1,
    horizontal_flip=True,
    rescale=1./255
)
train_generator = train_datagen.flow_from_directory(
    train_root,
    target_size=(IM_WIDTH, IM_HEIGHT),
    batch_size=batch_size,
    shuffle=True
)

# vaild data
vaild_datagen = ImageDataGenerator(
    width_shift_range=0.1,
    height_shift_range=0.1,
    shear_range=0.1,
    zoom_range=0.1,
    horizontal_flip=True,
    rescale=1./255
)
vaild_generator = train_datagen.flow_from_directory(
    vaildation_root,
    target_size=(IM_WIDTH, IM_HEIGHT),
    batch_size=batch_size,
)

# test data
test_datagen = ImageDataGenerator(
    rescale=1./255
)
test_generator = train_datagen.flow_from_directory(
    test_root,
    target_size=(IM_WIDTH, IM_HEIGHT),
    batch_size=batch_size,
)

def Conv2d_BN(x, nb_filter, kernel_size, strides=(1, 1), padding='same', name=None):
    if name is not None:
        bn_name = name + '_bn'
        conv_name = name + '_conv'
    else:
        bn_name = None
        conv_name = None

    x = Conv2D(nb_filter, kernel_size, padding=padding, strides=strides, activation='relu', name=conv_name)(x)
    x = BatchNormalization(axis=3, name=bn_name)(x)
    return x


def identity_Block(inpt, nb_filter, kernel_size, strides=(1, 1), with_conv_shortcut=False):
    x = Conv2d_BN(inpt, nb_filter=nb_filter, kernel_size=kernel_size, strides=strides, padding='same')
    x = Conv2d_BN(x, nb_filter=nb_filter, kernel_size=kernel_size, padding='same')
    if with_conv_shortcut:
        shortcut = Conv2d_BN(inpt, nb_filter=nb_filter, strides=strides, kernel_size=kernel_size)
        x = add([x, shortcut])
        return x
    else:
        x = add([x, inpt])
        return x

def bottleneck_Block(inpt,nb_filters,strides=(1,1),with_conv_shortcut=False):
    k1,k2,k3=nb_filters
    x = Conv2d_BN(inpt, nb_filter=k1, kernel_size=1, strides=strides, padding='same')
    x = Conv2d_BN(x, nb_filter=k2, kernel_size=3, padding='same')
    x = Conv2d_BN(x, nb_filter=k3, kernel_size=1, padding='same')
    if with_conv_shortcut:
        shortcut = Conv2d_BN(inpt, nb_filter=k3, strides=strides, kernel_size=1)
        x = add([x, shortcut])
        return x
    else:
        x = add([x, inpt])
        return x

def resnet_34(width,height,channel,classes):
    inpt = Input(shape=(width, height, channel))
    x = ZeroPadding2D((3, 3))(inpt)

    #conv1
    x = Conv2d_BN(x, nb_filter=64, kernel_size=(7, 7), strides=(2, 2), padding='valid')
    x = MaxPooling2D(pool_size=(3, 3), strides=(2, 2), padding='same')(x)

    #conv2_x
    x = identity_Block(x, nb_filter=64, kernel_size=(3, 3))
    x = identity_Block(x, nb_filter=64, kernel_size=(3, 3))
    x = identity_Block(x, nb_filter=64, kernel_size=(3, 3))

    #conv3_x
    x = identity_Block(x, nb_filter=128, kernel_size=(3, 3), strides=(2, 2), with_conv_shortcut=True)
    x = identity_Block(x, nb_filter=128, kernel_size=(3, 3))
    x = identity_Block(x, nb_filter=128, kernel_size=(3, 3))
    x = identity_Block(x, nb_filter=128, kernel_size=(3, 3))

    #conv4_x
    x = identity_Block(x, nb_filter=256, kernel_size=(3, 3), strides=(2, 2), with_conv_shortcut=True)
    x = identity_Block(x, nb_filter=256, kernel_size=(3, 3))
    x = identity_Block(x, nb_filter=256, kernel_size=(3, 3))
    x = identity_Block(x, nb_filter=256, kernel_size=(3, 3))
    x = identity_Block(x, nb_filter=256, kernel_size=(3, 3))
    x = identity_Block(x, nb_filter=256, kernel_size=(3, 3))

    #conv5_x
    x = identity_Block(x, nb_filter=512, kernel_size=(3, 3), strides=(2, 2), with_conv_shortcut=True)
    x = identity_Block(x, nb_filter=512, kernel_size=(3, 3))
    x = identity_Block(x, nb_filter=512, kernel_size=(3, 3))
    x = AveragePooling2D(pool_size=(7, 7))(x)
    x = Flatten()(x)
    x = Dense(classes, activation='softmax')(x)

    model = Model(inputs=inpt, outputs=x)
    return model

def resnet_50(width,height,channel,classes):
    inpt = Input(shape=(width, height, channel))
    x = ZeroPadding2D((3, 3))(inpt)
    x = Conv2d_BN(x, nb_filter=64, kernel_size=(7, 7), strides=(2, 2), padding='valid')
    x = MaxPooling2D(pool_size=(3, 3), strides=(2, 2), padding='same')(x)

    #conv2_x
    x = bottleneck_Block(x, nb_filters=[64,64,256],strides=(1,1),with_conv_shortcut=True)
    x = bottleneck_Block(x, nb_filters=[64,64,256])
    x = bottleneck_Block(x, nb_filters=[64,64,256])

    #conv3_x
    x = bottleneck_Block(x, nb_filters=[128, 128, 512],strides=(2,2),with_conv_shortcut=True)
    x = bottleneck_Block(x, nb_filters=[128, 128, 512])
    x = bottleneck_Block(x, nb_filters=[128, 128, 512])
    x = bottleneck_Block(x, nb_filters=[128, 128, 512])

    #conv4_x
    x = bottleneck_Block(x, nb_filters=[256, 256, 1024],strides=(2,2),with_conv_shortcut=True)
    x = bottleneck_Block(x, nb_filters=[256, 256, 1024])
    x = bottleneck_Block(x, nb_filters=[256, 256, 1024])
    x = bottleneck_Block(x, nb_filters=[256, 256, 1024])
    x = bottleneck_Block(x, nb_filters=[256, 256, 1024])
    x = bottleneck_Block(x, nb_filters=[256, 256, 1024])

    #conv5_x
    x = bottleneck_Block(x, nb_filters=[512, 512, 2048], strides=(2, 2), with_conv_shortcut=True)
    x = bottleneck_Block(x, nb_filters=[512, 512, 2048])
    x = bottleneck_Block(x, nb_filters=[512, 512, 2048])

    x = AveragePooling2D(pool_size=(7, 7))(x)
    x = Flatten()(x)
    x = Dense(classes, activation='softmax')(x)

    model = Model(inputs=inpt, outputs=x)
    return model

def acc_top2(y_true, y_pred):
    return top_k_categorical_accuracy(y_true, y_pred, k=2)


def check_print():
    # Create a Keras Model
    model = resnet_50(IM_WIDTH,IM_HEIGHT,3,NB_CLASS)
    model.summary()
    # Save a PNG of the Model Build
    plot_model(model, to_file='resnet.png')
    model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['acc',top_k_categorical_accuracy])
    print 'Model Compiled'
    return model


if __name__ == '__main__':
    if os.path.exists('resnet_50.h5'):
        model=load_model('resnet_50.h5')
    else:
        model=check_print()

    model.fit_generator(train_generator,validation_data=vaild_generator,epochs=EPOCH,steps_per_epoch=train_generator.n/batch_size
                        ,validation_steps=vaild_generator.n/batch_size)
    model.save('resnet_50.h5')
    loss,acc,top_acc=model.evaluate_generator(test_generator, steps=test_generator.n / batch_size)
    print 'Test result:loss:%f,acc:%f,top_acc:%f' % (loss, acc, top_acc)

 

  • 5
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: ResNet是一种深度卷积神经网络,可以使用Keras实现。 在Keras中,可以使用 `keras.applications.resnet.ResNet50` 来加载预训练的ResNet50模型。也可以从头开始构建ResNet模型,并使用自己的数据进行训练。 示例代码如下: ``` from keras.applications import ResNet50 # 加载预训练的ResNet50模型 model = ResNet50(weights='imagenet', include_top=True) # 编译模型 model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) # 训练模型 model.fit(x_train, y_train, epochs=10, batch_size=32) ``` 在这个示例中,我们使用预训练的ImageNet权重来初始化模型,并训练模型来识别图像分类。 如果想构建自己的ResNet模型,可以参考代码如下: ``` from keras.layers import Input, Conv2D, Add, Activation, BatchNormalization from keras.models import Model def resnet_block(inputs, filters, kernel_size, strides): x = Conv2D(filters, kernel_size, strides=strides, padding='same')(inputs) x = BatchNormalization()(x) x = Activation('relu')(x) x = Conv2D(filters, kernel_size, strides=strides, padding='same')(x) x = BatchNormalization()(x) return x def resnet_layer(inputs, filters, kernel_size, strides): x = resnet_block(inputs, filters, kernel_size, strides) y = resnet_block(inputs, filters, kernel_size, strides) z = Add()([x, y]) z = Activation('relu')(z) return z inputs = Input(shape=(256, 256, 3)) x = resnet_layer(inputs, 64, (3, 3), (1, 1)) x = resnet_layer(x, 128, (3, 3), (2, 2 ### 回答2: resnet(深度残差网络)是一种深度学习模型,旨在解决传统深度神经网络中的梯度消失和梯度爆炸问题。Keras是一个易于使用且功能强大的深度学习框架。 在Keras实现ResNet模型可以通过使用ResNet50、ResNet101或ResNet152等预训练模型进行迁移学习。这些模型已经在大规模图像分类任务中取得了很好的效果。 首先,需要导入所需的库和模块。然后,可以使用Keras的预训练模型ResNet50作为基础模型,并加载预训练的权重。 ```python from keras.applications import ResNet50 from keras.models import Sequential from keras.layers import Dense # 创建ResNet50模型 base_model = ResNet50(weights='imagenet', include_top=False, input_shape=(224, 224, 3)) # 冻结基础模型的权重 for layer in base_model.layers: layer.trainable = False # 在基础模型的顶部添加自定义的全连接层 model = Sequential() model.add(base_model) model.add(Dense(10, activation='softmax')) # 假设我们有10个类别 # 编译模型 model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) # 拟合模型 model.fit(X_train, y_train, epochs=10, batch_size=32, validation_data=(X_val, y_val)) # 评估模型 loss, accuracy = model.evaluate(X_test, y_test) ``` 在上述代码中,我们首先使用`ResNet50`函数创建一个基础模型,使用参数`weights='imagenet'`加载预训练的权重。然后,我们冻结了基础模型的所有层,这样在训练时它们的权重将不会更新。之后,我们通过`Sequential`模型在基础模型的顶部添加了一个自定义的全连接层。最后,编译模型并使用训练数据进行拟合。 需要注意的是,输入数据的形状应与ResNet50模型的预期输入形状(通常为224x224x3)相匹配。此外,定义全连接层时,输出维度应与数据集的类别数相匹配。 最后,我们可以评估模型的性能并检查损失和准确率。这样,我们就可以使用ResNet模型在Keras实现图像分类任务。 ### 回答3: ResNet(Residual Network)是一种深度卷积神经网络模型,它通过引入残差连接解决了深度网络训练过程中的梯度消失和梯度爆炸问题。在Keras实现ResNet模型可以通过使用预定义的ResNet模型架构函数或自定义模型实现。 使用Keras实现ResNet模型的一种方法是使用预定义的ResNet模型架构函数。Keras提供了ResNet50、ResNet101、ResNet152等不同层数的模型架构函数,可以直接调用这些函数来构建ResNet模型。例如,可以使用"ResNet50()"函数来构建一个包含50个卷积层的ResNet模型。 另一种方法是自定义ResNet模型。这种方法需要在Keras中定义一个包含残差块(Residual Block)的函数,并使用这些残差块构建自己的ResNet模型。残差块由多个卷积层组成,每个卷积层后面都有一个跳跃连接(skip connection),将输入直接添加到输出中。这样可以确保在深层网络训练过程中,梯度可以直接传递到浅层网络,避免了梯度消失问题。同时,通过使用批量归一化和激活函数,可以进一步提高模型性能。 自定义ResNet模型的关键是构建残差块。可以定义一个函数,该函数接受输入张量和输出通道数作为参数,并返回包含多个残差块的模型。在残差块中,可以使用Keras中的Conv2D、BatchNormalization和Activation等层来定义卷积、批量归一化和激活操作。 在构建好自定义ResNet模型后,可以使用Keras提供的编译、训练和评估函数对模型进行编译、训练和评估。编译模型时可以选择适当的损失函数、优化器和性能指标。训练模型时可以传入训练数据和标签,并设置合适的批量大小和训练轮数。评估模型时可以使用测试数据进行验证,并计算出模型的准确率、损失等指标。 总结来说,使用Keras实现ResNet模型,可以通过使用预定义的ResNet模型架构函数或自定义模型来构建ResNet模型。无论使用哪种方法,都需要定义合适的残差块来引入残差连接,解决深度网络训练过程中的梯度消失和梯度爆炸问题。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值