深度学习 keras解决多分类

详细看代码,外加代码里面有注释。
数据集在这:https://download.csdn.net/download/zqx951102/12675542

import numpy as np
from keras.preprocessing.image import ImageDataGenerator  #数据增强要用到
import os,random,shutil
np.random.seed(7)
#本文参考来自:https://www.jianshu.com/p/6904aa059387  代码和介绍
#数据集参考:https://blog.csdn.net/sinat_26917383/article/details/72861152
#http://pan.baidu.com/s/1nuqlTnN网盘数据  5类一共500张图片分为大巴车、恐龙、大象、鲜花和马五个类,每个类100张。
# 为Keras模型准备数据集

######首先将这些不同类别的照片放在不同的文件夹中,最终的train文件夹有5个子文件夹,(这句话好好读!分别在训练和测试文件夹下各建立5个文件夹)
# ###每个子文件夹中有80张图片,最终的test文件夹中有5个子文件夹,每个子文件夹中有20张图片。总共只有500张图片。

#1,指定一些超参数:
train_data_dir='D:/re/re/train'
val_data_dir='D:/re/re//test'
train_samples_num=400 # train set中全部照片数
val_samples_num=100
IMG_W,IMG_H,IMG_CH=384,256,3 # 单张图片的大小
batch_size=20
epochs=100  # 用比较少的epochs数目做演示,节约训练时间  50代
class_num=5 # 此处有5个类别

# 2,准备训练集,keras有很多Generator可以直接处理图片的加载,增强等操作,封装的非常好
from keras.preprocessing.image import ImageDataGenerator  #ImageDataGenerator来做数据增强,并且用flow_from_directory来从文件夹中产生数据流。
train_datagen = ImageDataGenerator( # 单张图片的处理方式,train时一般都会进行图片增强
        rescale=1. / 255, # 图片像素值为0-255,此处都乘以1/255,调整到0-1之间
        shear_range=0.2, # 斜切
        zoom_range=0.2, # 放大缩小范围
        horizontal_flip=True) # 水平翻转

train_generator = train_datagen.flow_from_directory(# 从文件夹中产生数据流
    train_data_dir, # 训练集图片的文件夹
    target_size=(IMG_W, IMG_H), # 调整后每张图片的大小
    batch_size=batch_size,
    class_mode='categorical') # 此处是多分类问题,故而mode是categorical
#唯一的不同之处是要设置class_mode='categorical',而不是原来二分类问题的class_mode='binary'
# 3,同样的方式准备测试集
val_datagen = ImageDataGenerator(rescale=1. / 255) # 只需要和trainset同样的scale即可,不需增强
val_generator = val_datagen.flow_from_directory(
        val_data_dir,
        target_size=(IMG_W, IMG_H),
        batch_size=batch_size,
        class_mode='categorical')


# 4,建立Keras模型:模型的建立主要包括模型的搭建,模型的配置
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
from keras import applications
from keras import optimizers
from keras.models import Model

def build_model(input_shape):
    # 模型的搭建:此处构建三个CNN层+2个全连接层的结构
    model = Sequential()
    model.add(Conv2D(32, (3, 3), input_shape=input_shape))
    model.add(Activation('relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))

    model.add(Conv2D(32, (3, 3)))
    model.add(Activation('relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))

    model.add(Conv2D(64, (3, 3)))
    model.add(Activation('relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))

    model.add(Flatten())
    model.add(Dense(64))
    model.add(Activation('relu'))
    model.add(Dropout(0.5))  # Dropout防止过拟合
    model.add(Dense(class_num))  # 此处多分类问题,用Dense(class_num)
    model.add(Activation('softmax'))  # 多分类问题用softmax作为activation function

    # 模型的配置
    model.compile(loss='categorical_crossentropy',  # 定义模型的loss func,optimizer,
                  optimizer=optimizers.RMSprop(),  # 使用默认的lr=0.001
                  metrics=['accuracy'])  # 主要优化accuracy

    return model  # 返回构建好的模型

model=build_model(input_shape=(IMG_W,IMG_H,IMG_CH)) # 输入的图片维度
# 模型的训练
history_ft = model.fit_generator(
                        train_generator, # 数据流
                        steps_per_epoch=train_samples_num // batch_size,
                        epochs=epochs,
                        validation_data=val_generator,
                        validation_steps=val_samples_num // batch_size)

# 画图,将训练时的acc和loss都绘制到图上
import matplotlib.pyplot as plt

def plot_training(history):
    plt.figure(12)

    plt.subplot(121)
    train_acc = history.history['acc']
    val_acc = history.history['val_acc']
    epochs = range(len(train_acc))
    plt.plot(epochs, train_acc, 'b', label='train_acc')
    plt.plot(epochs, val_acc, 'r', label='test_acc')
    plt.title('Train and Test accuracy')
    plt.legend()

    plt.subplot(122)
    train_loss = history.history['loss']
    val_loss = history.history['val_loss']
    epochs = range(len(train_loss))
    plt.plot(epochs, train_loss, 'b', label='train_loss')
    plt.plot(epochs, val_loss, 'r', label='test_loss')
    plt.title('Train and Test loss')
    plt.legend()
    plt.show()
plot_training(history_ft)

#loss: 0.2220 - acc: 0.9775 - val_loss: 1.0277 - val_acc: 0.9000
#没有出现过拟合现象,但是test acc不太稳定,变化比较大。在平台期后的test acc约为0.85.
#1,多分类问题和二分类问题基本相同,不同之处在于:1,设置flow_flow_directory时要用设置class_mode='categorical'。2,模型的最后一层要用Dense(class_num)和softmax这个多分类专用激活函数。3,模型的loss function要使用categorical_crossentropy。

在这里插入图片描述
loss: 0.2678 - acc: 0.9700 - val_loss: 0.2781 - val_acc: 0.9600 50代的结果
在这里插入图片描述
#loss: 0.2220 - acc: 0.9775 - val_loss: 1.0277 - val_acc: 0.9000这个是训练100代的结果图片。test acc不太稳定,变化比较大。

在这里插入图片描述
loss: 0.1851 - acc: 0.9700 - val_loss: 0.6068 - val_acc: 0.9600 训练180代 验证精度上去了 训练精度下降了一点点

猜你喜欢

转载自blog.csdn.net/zqx951102/article/details/107706550
今日推荐