卷积神经网络<二>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. 把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')

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
输入卷积神经网络(Multi-Input Convolutional Neural Network,MICNN)和多分支的神经网络(Multi-Branch Neural Network)是两种常见的用于多源数据融合的深度神经网络结构,它们在处理多输入数据时有一些区别。 1. 输入方式:MICNN接受多个输入,每个输入对应一个数据源的特征。这些输入经过共享的卷积层提取特征,然后将这些特征进行融合后进行分类或回归任务。而多分支神经网络通过为每个数据源建立一个独立的分支,每个分支可以有不同的网络结构和参数,然后通过融合层将不同分支的特征进行融合。 2. 特征处理:MICNN通过共享的卷积层来提取特征,这样可以保留不同输入之间的相关性,并且能够共享参数,减少模型的复杂度。而多分支神经网络则为每个输入数据源独立地构建分支,可以根据不同数据源的特点设计不同的网络结构和参数,更加灵活。 3. 参数共享:MICNN的共享卷积层可以共享参数,这样可以减少网络的参数量,提高模型的训练效率和泛化性能。而多分支神经网络每个分支都有独立的参数,可以更加细致地对不同数据源进行建模,但也会增加模型的参数量。 4. 融合方式:MICNN通过特征融合层将不同输入的特征进行融合,可以使用简单的拼接或加权求和等方式。多分支神经网络则通过融合层将不同分支的特征进行融合,可以使用简单的加权融合或者更复杂的注意力机制来实现特征融合。 综上所述,MICNN和多分支神经网络在多源数据融合方面有不同的设计思路,具体选择哪种结构要根据具体任务和数据特点来决定。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值