Keras 练习3 - 图片分类

建立CNN网络,对10类图片进行分类判断。
输入:图片大小为32,彩色的,数据为32x32x3,label 10类,进行热独编码
网络:增加了更多的卷积和池化及dropout层
训练:保存模型/重新加载模型(主要是weight)
结果:输出预测值与概率
准确率提高:单纯通过增加epoch数是不能提高准确率的,需要增加更多的卷积层和池化层,训练时间大大曾长。

import numpy as np
import pandas as pd
from keras.utils import np_utils
from keras.datasets import cifar10
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dropout, Flatten, Conv2D, MaxPooling2D

import matplotlib.pyplot as plt
import os

os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
np.random.seed(10)

model_save_name = "SavedModel/cifar10CNN.h5"

(x_train_image, y_train_label), (x_test_image, y_test_label) = cifar10.load_data()
print("size train data =", len(x_train_image))
print("size test data =", len(x_test_image))

print(x_train_image.shape)
print(x_train_image[0])
print(y_train_label.shape)

label_dict = {0:"airplane", 1:"automobile", 2:"bird", 3:"cat", 4:"deer",
            5:"dog", 6:"frog", 7:"horse", 8:"ship", 9:"truck"}

x_train_normal = x_train_image.astype("float32") / 255.0
x_test_normal = x_test_image.astype("float32") / 255.0

y_train_onehot = np_utils.to_categorical(y_train_label)
y_test_onehot = np_utils.to_categorical(y_test_label)

model = Sequential()

model.add(Conv2D(filters=32,
                kernel_size = (3, 3),
                padding = 'same',
                input_shape = (32, 32, 3),
                activation = 'relu'))
model.add(Dropout(0.25))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(filters=64,
                kernel_size = (3, 3),
                padding = 'same',
                activation = 'relu'))
model.add(Dropout(0.25))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Flatten())
model.add(Dropout(0.25))
model.add(Dense(units = 1024,
                activation = 'relu'))
model.add(Dropout(0.25))
model.add(Dense(units = 10,
                activation = 'softmax'))

print(model.summary())


model.compile(loss = "categorical_crossentropy",
            optimizer = "adam", metrics = ["accuracy"])

try:
    model.load_weights(model_save_name)
except:
    print("load model failed!")

history = model.fit(x = x_train_normal,
                y = y_train_onehot,
                validation_split = 0.2,
                epochs = 5,
                batch_size = 128,
                verbose = 2)

model.save_weights(model_save_name)

def show_train_history(train_history, train, val):
    plt.plot(train_history.history[train])
    plt.plot(train_history.history[val])
    plt.title("Train History")
    plt.ylabel(train)
    plt.xlabel("Epochs")
    plt.legend(["train", "validation"], loc="upper left")
    plt.show()

def plot_image_label_prediction(images, labels, prediction, idx = 0, num = 10):
    fig = plt.gcf()
    fig.set_size_inches(12, 14)
    if num > 25:
        num = 25
    for i in range(0, num):
        ax = plt.subplot(5, 5, 1 + i)
        ax.imshow(images[idx], cmap="binary")
        title = str(i) + "." + label_dict[labels[idx][0]]
        if len(prediction) > 0:
            title += " => " + label_dict[prediction[idx]]
        ax.set_title(title, fontsize = 10)
        ax.set_xticks([])
        ax.set_yticks([])
        idx += 1
    plt.show()

def show_prediction_prob(y_label, prediction, x_image, prediction_prob, i):
    print("label: ", label_dict[y_label[i][0]], " predict: ", label_dict[prediction[i]])
    plt.figure(figsize = (2, 2))
    plt.imshow(np.reshape(x_image[i], (32, 32, 3)))
    plt.show()
    for j in range(10):
        print(label_dict[j], " predict probability: %1.9f" % (prediction_prob[i][j]))

show_train_history(history, "acc", "val_acc")
show_train_history(history, "loss", "val_loss")

scores = model.evaluate(x_test_normal, y_test_onehot)
print("accuracy = ", scores[1])

prediction = model.predict_classes(x_test_normal)
print("prediction: ", prediction[:10])

prediction_prob = model.predict(x_test_normal)

plot_image_label_prediction(x_test_image, y_test_label, prediction, idx=0, num=25)
show_prediction_prob(y_test_label, prediction, x_test_image, prediction_prob, 0)

print(pd.crosstab(y_test_label.reshape(-1), prediction, rownames = ["label"], colnames = ["predict"]))

网络结构:

_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
conv2d_1 (Conv2D)            (None, 32, 32, 32)        896
_________________________________________________________________
dropout_1 (Dropout)          (None, 32, 32, 32)        0
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 16, 16, 32)        0
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 16, 16, 64)        18496
_________________________________________________________________
dropout_2 (Dropout)          (None, 16, 16, 64)        0
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 8, 8, 64)          0
_________________________________________________________________
flatten_1 (Flatten)          (None, 4096)              0
_________________________________________________________________
dropout_3 (Dropout)          (None, 4096)              0
_________________________________________________________________
dense_1 (Dense)              (None, 1024)              4195328
_________________________________________________________________
dropout_4 (Dropout)          (None, 1024)              0
_________________________________________________________________
dense_2 (Dense)              (None, 10)                10250
=================================================================
Total params: 4,224,970
Trainable params: 4,224,970
Non-trainable params: 0
_________________________________________________________________

训练结果:

Train on 40000 samples, validate on 10000 samples
Epoch 1/10
 - 103s - loss: 0.3368 - acc: 0.8847 - val_loss: 0.9838 - val_acc: 0.6791
Epoch 2/10
 - 105s - loss: 0.2636 - acc: 0.9103 - val_loss: 0.9136 - val_acc: 0.6980
Epoch 3/10
 - 102s - loss: 0.6777 - acc: 0.7622 - val_loss: 0.8316 - val_acc: 0.7260
Epoch 4/10
 - 108s - loss: 0.5570 - acc: 0.8042 - val_loss: 0.8110 - val_acc: 0.7274
Epoch 5/10
 - 108s - loss: 0.4739 - acc: 0.8323 - val_loss: 0.8112 - val_acc: 0.7245
Epoch 6/10
 - 97s - loss: 0.4158 - acc: 0.8545 - val_loss: 0.7957 - val_acc: 0.7283
Epoch 7/10
 - 103s - loss: 0.3588 - acc: 0.8761 - val_loss: 0.7921 - val_acc: 0.7279
Epoch 8/10
 - 103s - loss: 0.3198 - acc: 0.8888 - val_loss: 0.7851 - val_acc: 0.7328
Epoch 9/10
 - 98s - loss: 0.2869 - acc: 0.8999 - val_loss: 0.8147 - val_acc: 0.7261
Epoch 10/10
 - 100s - loss: 0.2498 - acc: 0.9149 - val_loss: 0.7858 - val_acc: 0.7359

识别结果:


混淆矩阵

predict    0    1    2    3    4    5    6    7    8    9
label
0        758   11   48   12   31    8   11    8   76   37
1         20  796    7   11    9    8   12    3   29  105
2         52    1  649   35  108   53   60   22   10   10
3         22    8   96  470   85  172   91   32    6   18
4         11    1   61   45  763   22   46   37   12    2
5         15    3   76  120   62  639   38   34    4    9
6          1    3   35   44   29   19  861    2    5    1
7          9    1   34   24   80   64    7  770    2    9
8         42   28   18    9   11    3   13    3  848   25
9         34   66   13   12    8    8    8   13   27  811

单个图片的识别结果和概率:

label:  cat  predict:  dog
airplane  predict probability: 0.008377961
automobile  predict probability: 0.001823489
bird  predict probability: 0.016125565
cat  predict probability: 0.414337575
deer  predict probability: 0.029035321
dog  predict probability: 0.430770338
frog  predict probability: 0.040058933
horse  predict probability: 0.016318403
ship  predict probability: 0.036439165
truck  predict probability: 0.006713260

问题:为什么要做标准化和归一化,参考:https://blog.csdn.net/resourse_sharing/article/details/51979494

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容