27- GoogleNet模型 (TensorFlow系列) (深度学习)

知识要点

  • GoogLeNet2014年Google团队提出

  • GoogLeNet模型参数只有VGG的 1/20 。


一 GoogleNet

GoogLeNet2014年由Google团队提出,斩获当年ImageNet竞赛中 Classification Task (分类任务) 第一名。

网络中的亮点

  • 引入了Inception结构(融合不同尺度的特征信息)
  • 使用1x1的卷积核进行降维以及映射处理
  • 添加两个辅助分类器帮助训练
  • 丢弃全连接层,使用平均池化层(大大减少模型 参数)

图片尺寸变换:

Inception结构

 

注意:每个分支所得的特征矩阵高和宽必须相

1.1 导包

from tensorflow import keras
import tensorflow as tf
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

cpu=tf.config.list_physical_devices("CPU")
tf.config.set_visible_devices(cpu)
print(tf.config.list_logical_devices())

1.2 定义模型

class Inception(keras.layers.Layer):
    def __init__(self, ch1x1, ch3x3red, ch3x3, ch5x5red, ch5x5, pool_proj, **kwargs):
        super().__init__(**kwargs)
        self.branch1 = keras.layers.Conv2D(ch1x1, kernel_size=1, activation='relu')
        
        self.branch2 = keras.Sequential([
            keras.layers.Conv2D(ch3x3red, kernel_size=1, activation='relu'),
            keras.layers.Conv2D(ch3x3, kernel_size=3, padding='SAME', activation='relu')
        ])
        
        self.branch3 = keras.Sequential([
            keras.layers.Conv2D(ch5x5red, kernel_size=1, activation='relu'),
            keras.layers.Conv2D(ch5x5, kernel_size=5, padding='SAME', activation='relu')
        ])
        
        self.branch4 = keras.Sequential([
            keras.layers.MaxPool2D(pool_size=3, strides=1, padding='SAME'),
            keras.layers.Conv2D(pool_proj, kernel_size=1, activation='relu')
        ])
        
    def call(self, inputs, **kwargs):
        branch1 = self.branch1(inputs)
        branch2 = self.branch2(inputs)
        branch3 = self.branch3(inputs)
        branch4 = self.branch4(inputs)
        outputs = keras.layers.concatenate([branch1, branch2, branch3, branch4])
        return outputs
# 定义辅助输出结构
class InceptionAux(keras.layers.Layer):
    def __init__(self, num_classes, **kwargs):
        super().__init__(**kwargs)
        self.average_pool = keras.layers.AvgPool2D(pool_size=5, strides=3)
        self.conv = keras.layers.Conv2D(128, kernel_size=1, activation='relu')
        
        self.fc1 = keras.layers.Dense(1024, activation='relu')
        self.fc2 = keras.layers.Dense(num_classes)
        self.softmax = keras.layers.Softmax()
        
    def call(self, inputs, **kwargs):
        x = self.average_pool(inputs)
        x = self.conv(x)
        x = keras.layers.Flatten()(x)
        x = keras.layers.Dropout(rate=0.5)(x)
        x = self.fc1(x)
        x = keras.layers.Dropout(rate=0.5)(x)
        x = self.fc2(x)
        x = self.softmax(x)
        return x
def GoogLeNet(im_height = 224, im_width = 224, class_num = 1000, aux_logits = False):
    input_image = keras.layers.Input(shape = (im_height, im_width, 3), dtype = 'float32')
    x = keras.layers.Conv2D(64, kernel_size = 7, strides = 2, padding = 'SAME', activation = 'relu')(input_image)
    # 注意maxpool2d, padding = 'SAME', 224/2 = 112, padding = 'VALID', (224 - (3 - 1))/2 = 111, same向上取整
    x = keras.layers.MaxPool2D(pool_size = 3, strides = 2, padding = 'SAME')(x)
    x = keras.layers.Conv2D(64, kernel_size = 1, strides = 1, padding = 'SAME', activation = 'relu')(x)
    x = keras.layers.Conv2D(192, kernel_size = 3, strides = 1, padding = 'SAME', activation = 'relu')(x)
    x = keras.layers.MaxPool2D(pool_size = 3, strides = 2, padding = 'SAME')(x)
    
    x = Inception(64, 96, 128, 16, 32, 32, name = 'inception_3a')(x)
    x = Inception(128, 128, 192, 32, 96, 64, name = 'inception_3b')(x)
    
    x = keras.layers.MaxPool2D(pool_size = 3, strides = 2, padding = 'SAME')(x)
    x = Inception(192, 96, 208, 16, 48, 64, name = 'inception_4a')(x)
    
    if aux_logits:
        aux1 = InceptionAux(class_num, name = 'aux_1')(x)
    
#     if aux_logits:
#         aux1 = InceptionAux(class_num, name = 'aux_1')(x)
    
    x = Inception(160, 112, 224, 24, 64, 64, name = 'inception_4b')(x)
    x = Inception(128, 128, 256, 24, 64, 64, name = 'inception_4c')(x)
    x = Inception(112, 144, 288, 32, 64, 64, name = 'inception_4d')(x)
    
    if aux_logits:
        aux2 = InceptionAux(class_num, name = 'aux_2')(x)
        
    x = Inception(256, 160, 320, 32, 128, 128, name = 'inception_4e')(x)
    x = keras.layers.MaxPool2D(pool_size = 3, strides = 2, padding = 'SAME')(x)
    
    x = Inception(256, 160, 320, 32, 128, 128, name = 'inception_5a')(x)
    x = Inception(384, 192, 384, 48, 128, 128, name = 'inception_5b')(x)
    
    x = keras.layers.AvgPool2D(pool_size = 7, strides = 1)(x)
    x = keras.layers.Flatten()(x)
    
    x = keras.layers.Dropout(rate = 0.4)(x)  
    x = keras.layers.Dense(class_num)(x)
    aux3 = keras.layers.Softmax(name = 'aux_3')(x)
    
    if aux_logits:
        aux = aux1 * 0.2 + aux2 * 0.3 + aux3 * 0.5
        model = keras.models.Model(inputs = input_image, outputs = aux)
    else:
        model = keras.models.Model(inputs = input_image, outputs = aux3)
    
    return model
googlenet = GoogLeNet(class_num=10, aux_logits = True)
googlenet.summary()

 1.3 数据处理

train_dir = './training/training/'
valid_dir = './validation/validation/'

# 图片数据生成器
train_datagen = keras.preprocessing.image.ImageDataGenerator(
    rescale = 1. / 255,
    rotation_range = 40,
    width_shift_range = 0.2,
    height_shift_range = 0.2,
    shear_range = 0.2,
    zoom_range = 0.2,
    horizontal_flip = True,
    vertical_flip = True,
    fill_mode = 'nearest'
)

height = 224
width = 224
channels = 3
batch_size = 32
num_classes = 10

train_generator = train_datagen.flow_from_directory(train_dir,
                                 target_size = (height, width),
                                 batch_size = batch_size,
                                 shuffle = True,
                                 seed = 7,
                                 class_mode = 'categorical')

valid_datagen = keras.preprocessing.image.ImageDataGenerator(
    rescale = 1. / 255
)
valid_generator = valid_datagen.flow_from_directory(valid_dir,
                                 target_size = (height, width),
                                 batch_size = batch_size,
                                 shuffle = True,
                                 seed = 7,
                                 class_mode = 'categorical')
print(train_generator.samples)
print(valid_generator.samples)

1.4 模型训练

googlenet.compile(optimizer = 'adam',   # optimizer 优化器, 防止过拟合 
              loss = 'categorical_crossentropy',
              metrics = ['accuracy'])

histroy = googlenet.fit(train_generator,
                        steps_per_epoch= train_generator.samples // batch_size,
                        epochs = 10,
                        validation_data = valid_generator,
                        validation_steps= valid_generator.samples // batch_size)

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值