Keras-DenseNet】CIFAR-10代码

本博客参考:https://blog.csdn.net/bryant_meng/article/details/81333633
当然我只是顺顺代码,实验确实跑不开。。。人家这泰坦的显卡还跑11小时,,我这1070ti的就算了 试了一下跑30代的结构,大概90左右把 也可以了,,所以想看结果和对比实验的参考上面博客。

#https://blog.csdn.net/bryant_meng/article/details/81333633
import os
os.environ["CUDA_DEVICE_ORDER"]="PCI_BUS_ID"
os.environ["CUDA_VISIBLE_DEVICES"]="0"

import keras
import numpy as np
import math
from keras.datasets import cifar10
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Model
from keras.initializers import he_normal
from keras.layers import Dense, Input, add, Activation, Lambda, concatenate
from keras.layers import Conv2D, AveragePooling2D, GlobalAveragePooling2D
from keras.layers.normalization import BatchNormalization
from keras.layers.merge import Concatenate
from keras import optimizers, regularizers
from keras.callbacks import LearningRateScheduler, TensorBoard

growth_rate        = 12
depth              = 100   #100层网络
compression        = 0.5    #压缩凑率减少特征图的数目

img_rows, img_cols = 32, 32
img_channels       = 3   #图像的三通道 彩色
num_classes        = 10  #分为几类 10个类别
batch_size         = 64      #每批大小64    # 64 or 32 or other
epochs             = 30      #300代
iterations         = 782     #迭代次数
weight_decay       = 1e-4

log_filepath  = 'D:/PyCode/network/Keras-densenet/CIFAR-10/densenet_100x12'


#数据预处理并设置 learning schedule
def color_preprocessing(x_train,x_test):
    x_train = x_train.astype('float32')
    x_test = x_test.astype('float32')
    mean = [125.307, 122.95, 113.865]
    std  = [62.9932, 62.0887, 66.7048]
    for i in range(3):
        x_train[:,:,:,i] = (x_train[:,:,:,i] - mean[i]) / std[i]   #预处理减均值除方差
        x_test[:,:,:,i] = (x_test[:,:,:,i] - mean[i]) / std[i]
    return x_train, x_test

#可以改变增长率


def scheduler(epoch):
    if epoch < 150:
        return 0.1
    if epoch < 225:
        return 0.01
    return 0.001

# load data
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
y_train = keras.utils.to_categorical(y_train, num_classes)  #独热编码  转换为二进制只有01的矩阵表示  y-train行 num—classes列
#https://blog.csdn.net/moyu123456789/article/details/83444140
y_test  = keras.utils.to_categorical(y_test, num_classes)
x_train, x_test = color_preprocessing(x_train, x_test)
def conv(x, out_filters, k_size):
    return Conv2D(filters=out_filters,
                  kernel_size=k_size,
                  strides=(1,1),
                  padding='same',
                  kernel_initializer='he_normal',
                  kernel_regularizer=regularizers.l2(weight_decay),
                  use_bias=False)(x)

def dense_layer(x):
    return Dense(units=10,
                 activation='softmax',
                 kernel_initializer='he_normal',
                 kernel_regularizer=regularizers.l2(weight_decay))(x)

def bn_relu(x): #先bn操作在relu
    x = BatchNormalization(momentum=0.9, epsilon=1e-5)(x)
    x = Activation('relu')(x)
    return x

def bottleneck(x):  #瓶颈层 bn-relu-conv----bn-relu-conv
    channels = growth_rate * 4
    x = bn_relu(x)
    x = conv(x, channels, (1,1)) # 48
    x = bn_relu(x)
    x = conv(x, growth_rate, (3,3)) # 12
    return x

# feature map size and channels half
def transition(x, inchannels):
    outchannels = int(inchannels * compression)
    x = bn_relu(x)
    x = conv(x, outchannels, (1, 1))
    x = AveragePooling2D((2, 2), strides=(2, 2))(x)
    return x, outchannels

def dense_block(x, blocks, nchannels):
        concat = x
        for i in range(blocks):
            x = bottleneck(concat)
            concat = concatenate([x, concat], axis=-1)
            nchannels += growth_rate
        return concat, nchannels

def densenet(img_input, classes_num):  #每个 dense_block 有16个bottleneck 也就是 32层,每个 transition 有 1 层(channels 减半),按照如下代码的结构设计,
       #总层数 = conv1 + 32 + 1 + 32 + 1 + 32 + fc = 96+4 = 100
        nblocks = (depth - 4) // 6  #    16  总共100层  100-4=96去除fc和三个transition层 96/3/2  每个 bottleneck 结构有 2 层(channels 分别为 growth_rate*4 和 growth_rate)
        nchannels = growth_rate * 2     # 12*2 = 24

        x = conv(img_input, nchannels, (3, 3))  # 32*32*3 to 32*32*24
        # 32*32*24 to 32*32*(24+nblocks*growth_rate) = 24+16*12 = 216
        x, nchannels = dense_block(x, nblocks, nchannels)  # 32*32*24 to 32*32*216
        x, nchannels = transition(x, nchannels)  # 32*32*216 to 16*16*108

        x, nchannels = dense_block(x, nblocks, nchannels)  # 16*16*108 to 16*16*(108+16*12) = 16*16*300
        x, nchannels = transition(x, nchannels)  # 16*16*300 to 8*8*150

        x, nchannels = dense_block(x, nblocks, nchannels)  # 8*8*150 to 8*8*(150+16*12) = 8*8*342
        x = bn_relu(x)
        x = GlobalAveragePooling2D()(x)  # 8*8*342 to 342
        x = dense_layer(x)  # 342 to 10
        return x

# build network
img_input = Input(shape=(img_rows, img_cols, img_channels))
output = densenet(img_input, 10) #分为10类
model = Model(img_input, output)
print(model.summary())  #网络的架构列表

# set optimizer
sgd = optimizers.SGD(lr=.1, momentum=0.9, nesterov=True)
model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])

# set callback
tb_cb = TensorBoard(log_dir=log_filepath, histogram_freq=0)  #计算图可视化操作
change_lr = LearningRateScheduler(scheduler)  #调整学习率
cbks = [change_lr, tb_cb]

# set data augmentation  数据增强手段
datagen = ImageDataGenerator(horizontal_flip=True,
                                 width_shift_range=0.125,
                                 height_shift_range=0.125,
                                 fill_mode='constant', cval=0.)
datagen.fit(x_train)  #增强的数据加入到x-train训练集中去

# start training
model.fit_generator(datagen.flow(x_train, y_train, batch_size=batch_size),
                        steps_per_epoch=iterations,
                        epochs=epochs,
                        callbacks=cbks,
                        validation_data=(x_test, y_test))  #验证集合 输入的是测试集合x和y
model.save('densenet_100x12.h5')  #保存模型

猜你喜欢

转载自blog.csdn.net/zqx951102/article/details/107644889