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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,504评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,434评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,089评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,378评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,472评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,506评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,519评论 3 413
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,292评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,738评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,022评论 2 329
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,194评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,873评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,536评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,162评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,413评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,075评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,080评论 2 352

推荐阅读更多精彩内容