Tensorflow 2.1 keras 训练 实战 cifar10 cifar100 完整代码 准确率 86%-87% 模型 Resnet SENet

环境:
tensorflow 2.1
最好用GPU

模型:
Resnet
SENet
用Resnet 和SENet网络训练Cifar10 或者Cifar 100.

训练数据:Cifar10 或者 Cifar 100
训练集上准确率:96%左右
验证集上准确率:87%左右
测试集上准确率86%-87%
训练时间在GPU上:一小时多
权重大小:5.08 MB

训练的历程: 普通网络(65%左右)-> 数据增强(70%左右)->模型增强(进入Resnet 和SEnet) 80%左右 -> 模型的结构做了调整(86%)
开始的时候我也用tensorlfow 1.4训练过Cifar10. 但是没有跑出理想的准确率,总是在70%左右。后来也没有想过模型上增强直接跳到tensorflow2.1了。

下一步准备加入inception网络试一试结果如何

训练集上和验证集上训练结果

343/351 [============================>.] - ETA: 0s - loss: 0.1013 - sparse_categorical_accuracy: 0.9641
345/351 [============================>.] - ETA: 0s - loss: 0.1012 - sparse_categorical_accuracy: 0.9641
347/351 [============================>.] - ETA: 0s - loss: 0.1011 - sparse_categorical_accuracy: 0.9642
349/351 [============================>.] - ETA: 0s - loss: 0.1010 - sparse_categorical_accuracy: 0.9643
351/351 [==============================] - 15s 44ms/step - loss: 0.1008 - sparse_categorical_accuracy: 0.9643 - val_loss: 0.5324 - val_sparse_categorical_accuracy: 0.8682

下面是测试集上的结果


#79/79 - 2s - loss: 0.4225 - sparse_categorical_accuracy: 0.8708
#[0.42247119277149814, 0.8708]

下面是完整的代码,运行前建一下这个目录weights3_6,不想写代码自动化建了。
如果要训练Cifar100,直接把cifar10 改成cifar100就可以了。不需要改其它地方

import tensorflow as tf
import tensorflow.keras as keras
import tensorflow.keras.layers as layers
import time as time
import tensorflow.keras.preprocessing.image as image
import matplotlib.pyplot as plt
import os

def senet_block(inputs, ratio):
    shape = inputs.shape
    channel_out = shape[-1]
    # print(shape)
    # (2, 28, 28, 32) , [1,28,28,1], [1,28,28,1]
    squeeze = layers.GlobalAveragePooling2D()(inputs)
    # [2, 1, 1, 32]
    # print(squeeze.shape)
    # 第二层,全连接层
    # [2,32]
    # print(squeeze.shape)
    shape_result = layers.Flatten()(squeeze)
    # print(shape_result.shape)
    # [32,2]
    shape_result = layers.Dense(int(channel_out / ratio), activation='relu')(shape_result)
    # shape_result = layers.BatchNormalization()(shape_result)
    # [2,32]
    shape_result = layers.Dense(channel_out, activation='sigmoid')(shape_result)
    # shape_result = layers.BatchNormalization()(shape_result)

    # 第四层,点乘
    # print('heres2')
    excitation_output = tf.reshape(shape_result, [-1, 1, 1, channel_out])
    # print(excitation_output.shape)
    h_output = excitation_output * inputs
    return h_output

def res_block(input, input_filter, output_filter):
    res_x = layers.Conv2D(filters=output_filter, kernel_size=(3, 3), activation='relu', padding='same')(input)
    res_x = layers.BatchNormalization()(res_x )
    res_x = senet_block(res_x, 8)
    res_x = layers.Conv2D(filters=output_filter, kernel_size=(3, 3), activation=None, padding='same')(res_x )
    res_x = layers.BatchNormalization()(res_x )
    res_x = senet_block(res_x, 8)
    if input_filter == output_filter:
        identity = input
    else: #需要升维或者降维
        identity = layers.Conv2D(filters=output_filter, kernel_size=(1,1), padding='same')(input)

    x = layers.Add()([identity, res_x])
    output = layers.Activation('relu')(x)
    return output

def my_model():
    inputs = keras.Input(shape=(32,32,3), name='img')
    h1 = layers.Conv2D(filters=16, kernel_size=(3, 3), strides=(1, 1), padding='same', activation='relu')(inputs)
    h1 = layers.BatchNormalization()(h1)
    h1 = senet_block(h1, 8)
    block1_out = res_block(h1, 16, 32)
    block1_out = layers.MaxPool2D(pool_size=(2, 2))(block1_out)
    # Resnet block
    block2_out = res_block(block1_out, 32,64)
    block2_out = layers.MaxPool2D(pool_size=(2, 2))(block2_out)
    block3_out = res_block(block2_out, 64, 128)
    block4_out = layers.MaxPool2D(pool_size=(2, 2))(block3_out)
    block4_out = res_block(block4_out, 128, 256)
    h3 = layers.GlobalAveragePooling2D()(block4_out)
    h3 = layers.Flatten()(h3)
    h3 = layers.BatchNormalization()(h3)
    h3 = layers.Dense(64, activation='relu')(h3)
    h3 = layers.BatchNormalization()(h3)
    outputs = layers.Dense(10, activation='softmax')(h3)

    deep_model = keras.Model(inputs, outputs, name='resnet')


    deep_model.compile(optimizer=keras.optimizers.Adam(),
                 loss=keras.losses.SparseCategoricalCrossentropy(),
                #metrics=['accuracy'])
                metrics=[keras.metrics.SparseCategoricalAccuracy()])
    deep_model.summary()
    #keras.utils.plot_model(deep_model, 'my_resNet.png', show_shapes=True)
    return deep_model

current_max_loss = 9999

def train_my_model(deep_model):
    (x_train, y_train), (x_test, y_test) = tf.keras.datasets.cifar10.load_data()

    train_datagen = image.ImageDataGenerator(
        rescale=1 / 255,
        rotation_range=40,  # 角度值,0-180.表示图像随机旋转的角度范围
        width_shift_range=0.2,  # 平移比例,下同
        height_shift_range=0.2,
        shear_range=0.2,  # 随机错切变换角度
        zoom_range=0.2,  # 随即缩放比例
        horizontal_flip=True,  # 随机将一半图像水平翻转
        fill_mode='nearest'  # 填充新创建像素的方法
    )

    test_datagen = image.ImageDataGenerator(rescale=1 / 255)

    validation_datagen = image.ImageDataGenerator(rescale=1 / 255)

    train_generator = train_datagen.flow(x_train[:45000], y_train[:45000], batch_size=128)
    # train_generator = train_datagen.flow(x_train, y_train, batch_size=128)
    validation_generator = validation_datagen.flow(x_train[45000:], y_train[45000:], batch_size=128)

    test_generator = test_datagen.flow(x_test, y_test, batch_size=128)

    begin_time = time.time()

    if os.path.isfile('./weights3_6/model.h5'):
        print('load weight')
        deep_model.load_weights('./weights3_6/model.h5')


    def save_weight(epoch, logs):
        global current_max_loss
        if(logs['val_loss'] is not None and logs['val_loss']< current_max_loss):
            current_max_loss = logs['val_loss']
            print('save_weight', epoch, current_max_loss)
            deep_model.save_weights('./weights3_6/model.h5')

    batch_print_callback = keras.callbacks.LambdaCallback(
        on_epoch_end=save_weight
    )
    callbacks = [
        tf.keras.callbacks.EarlyStopping(patience=4, monitor='loss'),
        batch_print_callback,
        # keras.callbacks.ModelCheckpoint('./weights/model.h5', save_best_only=True),
        tf.keras.callbacks.TensorBoard(log_dir='logs3_6')
    ]

    print(train_generator[0][0].shape)

    history = deep_model.fit_generator(train_generator, steps_per_epoch=351, epochs=200, callbacks=callbacks,
                                       validation_data=validation_generator, validation_steps=39, initial_epoch = 0)

    result = deep_model.evaluate_generator(test_generator, verbose=2)

    print(result)
    print('time', time.time() - begin_time)

    def show_result(history):
        plt.plot(history.history['loss'])
        plt.plot(history.history['val_loss'])
        plt.plot(history.history['sparse_categorical_accuracy'])
        plt.plot(history.history['val_sparse_categorical_accuracy'])
        plt.legend(['loss', 'val_loss', 'sparse_categorical_accuracy', 'val_sparse_categorical_accuracy'],
                   loc='upper left')
        plt.show()
        print(history)

    show_result(history)

def predict_module(deep_model):
    (x_train, y_train), (x_test, y_test) = tf.keras.datasets.cifar10.load_data()

    import numpy as np
    if os.path.isfile('./weights3_6/model.h5'):
        print('load weight')
        deep_model.load_weights('./weights3_6/model.h5')

    print(y_test[0:20])
    for i in range(20):
        img = x_test[i][np.newaxis, :]/255

        y_ = deep_model.predict(img)
        v  = np.argmax(y_)
        print(v, y_test[i])

def test_module(deep_model):
    (x_train, y_train), (x_test, y_test) = tf.keras.datasets.cifar10.load_data()

    test_datagen = image.ImageDataGenerator(rescale=1 / 255)


    test_generator = test_datagen.flow(x_test, y_test, batch_size=128)

    begin_time = time.time()

    if os.path.isfile('./weights3_6/model.h5'):
        print('load weight')
        deep_model.load_weights('./weights3_6/model.h5')

    result = deep_model.evaluate_generator(test_generator, verbose=2)

    print(result)
    print('time', time.time() - begin_time)



if __name__ == '__main__':
    deep_model = my_model()
    train_my_model(deep_model)
    #predict_module(deep_model)
    #test_module(deep_model)


你可能感兴趣的:(tensorflow)