• 卷积神经网络<二>keras实现多分支输入VGG


    VGG的模型图

    在这里插入图片描述

    在这里插入图片描述

    VGG使用Keras实现

    这里的代码借鉴了VGG实现Keras,但是这段代码不支持多通道,并且vgg函数的扩展性不好。下面修改一下,方便进行多分支图片输入的建立,以及更见方便的调参。

    # from keras.models import
    from keras.layers import *
    from keras.models import Input, load_model, Sequential
    from keras import Model
    from keras.datasets import mnist
    from keras.utils import to_categorical
    from keras.losses import categorical_crossentropy
    import keras.optimizers
    import numpy as np
     
     
    def vgg(input_shape, num_cls, filters_num, conv_nums):
        # print(input_shape)
        inputs = Input(shape=input_shape)
        x = inputs
        for i in range(len(conv_nums)):
            for j in range(conv_nums[i]):
                x = Conv2D(filters=filters_num[i], kernel_size=3, padding='same',
                           name='stage{0}_conv{1}'.format(i+1, j+1))(x)
            x = MaxPool2D((2, 2), strides=2, name='maxpool_'+str(i+1))(x)
            x = ZeroPadding2D((1, 1))(x)
        x = Flatten(name='flatten')(x)
        x = Dense(units=4096, name='dense4096_1')(x)
        x = Dense(units=4096, name='dense4096_2')(x)
        x = Dense(units=num_cls, name='dense1000', activation='softmax')(x)
        model = Model(inputs=inputs, outputs=x, name='vgg')
        model.compile(optimizer='sgd', loss='categorical_crossentropy', metrics=['acc'])
        return model
     
     
    def train(net_name):
        path = r'C:\Users\.keras\datasets\mnist.npz'
        with np.load(path, allow_pickle=True) as f:
            x_train, y_train = f['x_train'], f['y_train']
            x_test, y_test = f['x_test'], f['y_test']
     
        x_train = x_train.reshape(x_train.shape[0], 28, 28, 1).astype('float32')
        x_test = x_test.reshape(x_test.shape[0], 28, 28, 1).astype('float32')
        num_classes = 10
        x_train = x_train / 255.
        x_test = x_test / 255.
        y_train = to_categorical(y_train, num_classes)
        y_test = to_categorical(y_test, num_classes)
     
        batch_size = 16
        epochs = 1
     
        if net_name == 'vgg-19':
            filters_num = [64, 128, 256, 512, 512]
            conv_nums = [2, 2, 4, 4, 4]
        else:
            filters_num = [32, 64, 128, 256, 512]
            conv_nums = [2, 2, 3, 3, 3]
        vgg_model = vgg(input_shape=(28, 28, 1), num_cls=num_classes, filters_num=filters_num,
                        conv_nums=conv_nums)
        vgg_model.summary()
        vgg_model.fit(x_train, y_train, epochs=epochs, batch_size=batch_size, validation_split=0.1)
        vgg_model.save('{0}-mnist.h5'.format(net_name))
        eval_res = vgg_model.evaluate(x_test, y_test)
        print(eval_res)
     
     
    if __name__ == '__main__':
        train('vgg-16')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64

    方便调参版本

    1. 把optimizer和input等重要参数进行了封装,方便调参和调用。
    2. 建立了多分支输入函数build_multy_vgg(),方便调用。
    """
    @author:fuzekun
    @file:VGG_Model.py
    @time:2022/11/22
    @description: 定义VGG的模型进行图片的训练,首先只使用rri进行训练
    """
    
    # from keras.models import
    from keras.layers import *
    from keras.models import Input, load_model, Sequential
    from keras import Model
    from keras.datasets import mnist
    from keras.utils.all_utils import to_categorical
    from keras.losses import categorical_crossentropy
    import keras.optimizers
    import numpy as np
    import tensorflow as tf
    """
    这里建立模型的时候,压缩到最后就没有了,个人以为是图片太小导致的,所以240的时候可以去掉zero那一层
    """
    
    def vgg(input_shape, num_cls, filters_num, conv_nums, multy):
        # print(input_shape)
        inputs = Input(shape=input_shape)
        x = inputs
        for i in range(len(conv_nums)):
            for j in range(conv_nums[i]):
                x = Conv2D(filters=filters_num[i], kernel_size=3, padding='same')(x)
            x = MaxPool2D((2, 2), strides=2)(x)
            if input_shape[0] < 224:
                x = ZeroPadding2D((1, 1))(x)
        x = Flatten()(x)
        x = Dense(units=4096)(x)
        x = Dense(units=4096)(x)
        if not multy:      # 单模型直接输出到类别
            x = Dense(units=num_cls, activation='softmax')(x)
        model = Model(inputs=inputs, outputs=x, name='vgg')
        return model
    
    
    def build_vgg(net_name, input_shape, num_classes, optimizer, filter_num=[], conv_nums=[], multy = False):
    
        if net_name == 'vgg-19':
            filters_num = [64, 128, 256, 512, 512]
            conv_nums = [2, 2, 4, 4, 4]
        else:
            filters_num = [32, 64, 128, 256, 512]
            conv_nums = [2, 2, 3, 3, 3]
    
        vgg_model = vgg(input_shape=input_shape, num_cls=num_classes, filters_num=filters_num,
                        conv_nums=conv_nums, multy=multy)
        if not multy:   # 多输入的不进行编译
            vgg_model.compile(optimizer=optimizer, loss='categorical_crossentropy', metrics=['acc'])
        # vgg_model.summary()
        return vgg_model
    
    # 创建多输入的VGG模型
    def build_multy_VGG(net_name, input_shape, num_classes, optimizer, n_hiddens,
                        filter_num=[], conv_nums=[]):
        out_rri = build_vgg(net_name, input_shape, num_classes, optimizer, filter_num, conv_nums, True)
        out_edr = build_vgg(net_name, input_shape, num_classes, optimizer, filter_num, conv_nums, True)
        out_amp = build_vgg(net_name, input_shape, num_classes, optimizer, filter_num, conv_nums, True)
        # 2. 进行模型融合
        # print(out_rri.output)
        combined = concatenate([out_rri.output, out_edr.output])  # (None, 7, 7, 768)
        # print(combined)
        # 2.1融合输入
        x = Dense(n_hiddens, activation='relu')(combined)
        x = Flatten()(x)
        # 2.2最后输出
        x = Dense(num_classes, activation='softmax')(x)
        # 2.3模型定义完成
        model = Model(inputs=[out_rri.input, out_edr.input], outputs=x)
        model.compile(optimizer=optimizer, loss='categorical_crossentropy', metrics=['acc'])
        return model
    
    def train(net_name):
        path = r'C:\Users\.keras\datasets\mnist.npz'
        with np.load(path, allow_pickle=True) as f:
            x_train, y_train = f['x_train'], f['y_train']
            x_test, y_test = f['x_test'], f['y_test']
    
        x_train = x_train.reshape(x_train.shape[0], 28, 28, 1).astype('float32')
        x_test = x_test.reshape(x_test.shape[0], 28, 28, 1).astype('float32')
        num_classes = 10
        x_train = x_train / 255.
        x_test = x_test / 255.
        y_train = to_categorical(y_train, num_classes)
        y_test = to_categorical(y_test, num_classes)
    
        batch_size = 16
        epochs = 1
    
        lr = 0.001
        opt = tf.keras.optimizers.Adam(learning_rate=lr)
        model = build_vgg("vgg-16", input_shape=(28,28,1), num_classes=2, optimizer=opt)
        model.fit(x_train, y_train, epochs=epochs, batch_size=batch_size, validation_split=0.1)
        model.save('{0}-mnist.h5'.format(net_name))
        eval_res = model.evaluate(x_test, y_test)
        print(eval_res)
    
    
    if __name__ == '__main__':
        train('vgg-16')
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
  • 相关阅读:
    驱动开发:内核远程堆分配与销毁
    无法访问mybatis.dto.StudengInVO-使用maven编译报错-2022新项目
    【小黑送书—第七期】>>程序员To架构师?一起来看架构师系列书籍推荐
    常见生产环境问题及排查方法
    Python数据攻略-Pandas与地理空间数据分析
    LeetCode98题:验证二叉搜索树(python3)
    澳大利亚量子计算制造商SQC获5000万美元投资用于硅量子计算
    shell--for循环
    【云原生】第二篇--容器管理工具 Docker生态架构及部署
    小分子PEG CAS:1352814-07-3生物素-PEG6-丙酸叔丁酯
  • 原文地址:https://blog.csdn.net/fuzekun/article/details/127991833