当前位置:主页 > 查看内容

深度学习Keras Sequential模型训练cifia10预测图片 过程以及遇到

发布时间:2021-04-06 00:00| 位朋友查看

简介:编程软件 之前使用pycharm来训练模型发现很难对代码进行实时的修改在训练完模型之后保存后 需要运行很多余的代码在这里我觉的notebook 更适合用来进行训练测试 代码 # 导入需要的包 from keras . datasets import cifar10 from keras . utils import np_util……

编程软件

之前使用pycharm来训练模型发现很难对代码进行实时的修改,在训练完模型之后保存后 需要运行很多余的代码,在这里我觉的notebook 更适合用来进行训练测试

代码

# 导入需要的包
from keras.datasets import cifar10
from keras.utils import np_utils
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation, Flatten
from keras.layers.convolutional import Conv2D, MaxPooling2D
from keras.optimizers import SGD, Adam, RMSprop
import matplotlib.pyplot as plt
import pandas as pd
import os
import cv2 as cv
import numpy as np
import PIL.Image as Image
# CIFAR-10 是包含了60000 张 32*32 的三通道数据集,
#在这里保存下图片的大小
IMG_CHANNELS = 3
IMG_ROWS = 32
IMG_COLS = 32

保存图片的维度是因为在keras Sequential模型中, 第一层Conv2D 中需要输入图片的大小尺寸

# 定义超参数
BATCH_SIZE = 128
NB_EPOCH = 40
NB_CLASSES = 10
VERBOSE = 1
VALIDATION_SPLIT = 0.2
OPTIM= RMSprop()

# 加载数据集
(X_train, y_train), (X_test, y_test) = cifar10.load_data()
print('X_train.shape: ', X_train.shape)
print(X_train.shape[0], 'train samples')
print(X_test.shape[0], 'test samples')

# 做one-hot 编码,并把图片归一化操作
# 分类转换
Y_train = np_utils.to_categorical(y_train, NB_CLASSES)
Y_test = np_utils.to_categorical(y_test, NB_CLASSES)

# 将其转化为float类型, 并对其进行归一化操作
X_train = X_train.astype('float32')
X_test = X_test.astype('float32')
X_train /= 255
X_test /=255

构建神经网络

# 构建神经网络
model = Sequential()
model.add(Conv2D(32, (3, 3), padding='same',
          input_shape=(IMG_ROWS, IMG_COLS, IMG_CHANNELS))) # 32个卷积滤波器, 每个滤波器的大小是3*3
# 当Conv2D 模型作为第一层的时候需要给其添加输入维度
model.add(Activation('relu'))
model.add(Conv2D(32, (3, 3), padding='same'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

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

#深度管道中的下一个阶段是512 个单元 和Relu 的激活函数的全连接网络,其后是关闭了50% 的神经元的dropout 层作为输出有10 个类的softmax 层,每一个类对应一个类别
model.add(Flatten())
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(NB_CLASSES))
model.add(Activation('softmax'))
model.summary()

训练模型

#定义了网络之后开始训练

model.compile(loss='categorical_crossentropy',optimizer=OPTIM, metrics=['accuracy'])
model.fit(X_train, Y_train, batch_size=BATCH_SIZE,
         epochs=NB_EPOCH, validation_split=VALIDATION_SPLIT, shuffle=True)
score = model.evaluate(X_test, Y_test,
                      batch_size=BATCH_SIZE, verbose=VERBOSE)

print("Test score:", score[0])
print('Test accuracy:', score[1])

结果

Epoch 1/40
313/313 [==============================] - 6s 16ms/step - loss: 2.0243 - accuracy: 0.2575 - val_loss: 1.6328 - val_accuracy: 0.4184
Epoch 2/40
313/313 [==============================] - 4s 14ms/step - loss: 1.4476 - accuracy: 0.4816 - val_loss: 1.1816 - val_accuracy: 0.5755
Epoch 3/40
313/313 [==============================] - 4s 14ms/step - loss: 1.1817 - accuracy: 0.5780 - val_loss: 1.0592 - val_accuracy: 0.6275
Epoch 4/40
313/313 [==============================] - 4s 14ms/step - loss: 1.0345 - accuracy: 0.6376 - val_loss: 1.0002 - val_accuracy: 0.6482
Epoch 5/40
313/313 [==============================] - 4s 14ms/step - loss: 0.9094 - accuracy: 0.6838 - val_loss: 0.9212 - val_accuracy: 0.6794
Epoch 6/40
313/313 [==============================] - 4s 14ms/step - loss: 0.8270 - accuracy: 0.7113 - val_loss: 0.8573 - val_accuracy: 0.7003
Epoch 7/40
313/313 [==============================] - 4s 14ms/step - loss: 0.7702 - accuracy: 0.7303 - val_loss: 0.7958 - val_accuracy: 0.7242
Epoch 8/40
313/313 [==============================] - 4s 14ms/step - loss: 0.7012 - accuracy: 0.7575 - val_loss: 0.7268 - val_accuracy: 0.7517
Epoch 9/40
313/313 [==============================] - 4s 14ms/step - loss: 0.6536 - accuracy: 0.7722 - val_loss: 0.7270 - val_accuracy: 0.7498
Epoch 10/40
313/313 [==============================] - 4s 14ms/step - loss: 0.6312 - accuracy: 0.7812 - val_loss: 0.7472 - val_accuracy: 0.7471
Epoch 11/40
313/313 [==============================] - 4s 14ms/step - loss: 0.5972 - accuracy: 0.7935 - val_loss: 0.7077 - val_accuracy: 0.7733
Epoch 12/40
313/313 [==============================] - 4s 14ms/step - loss: 0.5870 - accuracy: 0.8014 - val_loss: 0.7168 - val_accuracy: 0.7697
Epoch 13/40
313/313 [==============================] - 4s 14ms/step - loss: 0.5611 - accuracy: 0.8081 - val_loss: 0.7616 - val_accuracy: 0.7534
Epoch 14/40
313/313 [==============================] - 5s 15ms/step - loss: 0.5451 - accuracy: 0.8161 - val_loss: 0.7596 - val_accuracy: 0.7668
Epoch 15/40
313/313 [==============================] - 4s 14ms/step - loss: 0.5417 - accuracy: 0.8206 - val_loss: 0.6806 - val_accuracy: 0.7799
Epoch 16/40
313/313 [==============================] - 4s 14ms/step - loss: 0.5407 - accuracy: 0.8213 - val_loss: 0.7599 - val_accuracy: 0.7797
Epoch 17/40
313/313 [==============================] - 4s 14ms/step - loss: 0.5299 - accuracy: 0.8261 - val_loss: 0.7900 - val_accuracy: 0.7603
Epoch 18/40
313/313 [==============================] - 5s 14ms/step - loss: 0.5218 - accuracy: 0.8296 - val_loss: 0.8555 - val_accuracy: 0.7555
Epoch 19/40
313/313 [==============================] - 4s 14ms/step - loss: 0.5224 - accuracy: 0.8256 - val_loss: 0.7607 - val_accuracy: 0.7849
Epoch 20/40
313/313 [==============================] - 4s 14ms/step - loss: 0.5130 - accuracy: 0.8322 - val_loss: 0.7154 - val_accuracy: 0.7703
Epoch 21/40
313/313 [==============================] - 4s 14ms/step - loss: 0.5080 - accuracy: 0.8331 - val_loss: 0.7410 - val_accuracy: 0.7818
Epoch 22/40
313/313 [==============================] - 5s 14ms/step - loss: 0.5121 - accuracy: 0.8384 - val_loss: 0.8094 - val_accuracy: 0.7465
Epoch 23/40
313/313 [==============================] - 4s 14ms/step - loss: 0.5174 - accuracy: 0.8328 - val_loss: 0.7604 - val_accuracy: 0.7760
Epoch 24/40
313/313 [==============================] - 4s 14ms/step - loss: 0.5109 - accuracy: 0.8357 - val_loss: 0.7400 - val_accuracy: 0.7684
Epoch 25/40
313/313 [==============================] - 5s 14ms/step - loss: 0.5049 - accuracy: 0.8380 - val_loss: 0.7450 - val_accuracy: 0.7711
Epoch 26/40
313/313 [==============================] - 4s 14ms/step - loss: 0.5140 - accuracy: 0.8353 - val_loss: 0.7522 - val_accuracy: 0.7767
Epoch 27/40
313/313 [==============================] - 5s 14ms/step - loss: 0.4955 - accuracy: 0.8397 - val_loss: 0.7715 - val_accuracy: 0.7830
Epoch 28/40
313/313 [==============================] - 5s 15ms/step - loss: 0.5037 - accuracy: 0.8395 - val_loss: 0.7806 - val_accuracy: 0.7799
Epoch 29/40
313/313 [==============================] - 5s 15ms/step - loss: 0.5104 - accuracy: 0.8402 - val_loss: 0.8468 - val_accuracy: 0.7866
Epoch 30/40
313/313 [==============================] - 5s 15ms/step - loss: 0.5066 - accuracy: 0.8407 - val_loss: 0.7501 - val_accuracy: 0.7755
Epoch 31/40
313/313 [==============================] - 5s 15ms/step - loss: 0.5118 - accuracy: 0.8370 - val_loss: 0.8303 - val_accuracy: 0.7885
Epoch 32/40
313/313 [==============================] - 5s 15ms/step - loss: 0.5201 - accuracy: 0.8382 - val_loss: 0.7711 - val_accuracy: 0.7880
Epoch 33/40
313/313 [==============================] - 5s 15ms/step - loss: 0.5329 - accuracy: 0.8365 - val_loss: 0.7746 - val_accuracy: 0.7961
Epoch 34/40
313/313 [==============================] - 5s 15ms/step - loss: 0.5065 - accuracy: 0.8407 - val_loss: 1.0186 - val_accuracy: 0.7816
Epoch 35/40
313/313 [==============================] - 5s 15ms/step - loss: 0.5252 - accuracy: 0.8377 - val_loss: 0.7815 - val_accuracy: 0.7771
Epoch 36/40
313/313 [==============================] - 5s 15ms/step - loss: 0.5233 - accuracy: 0.8370 - val_loss: 1.1165 - val_accuracy: 0.7676
Epoch 37/40
313/313 [==============================] - 5s 15ms/step - loss: 0.5336 - accuracy: 0.8356 - val_loss: 0.7393 - val_accuracy: 0.7863
Epoch 38/40
313/313 [==============================] - 5s 15ms/step - loss: 0.5204 - accuracy: 0.8378 - val_loss: 0.9677 - val_accuracy: 0.7916
Epoch 39/40
313/313 [==============================] - 5s 15ms/step - loss: 0.5149 - accuracy: 0.8412 - val_loss: 0.7782 - val_accuracy: 0.7804
Epoch 40/40
313/313 [==============================] - 5s 15ms/step - loss: 0.5300 - accuracy: 0.8358 - val_loss: 0.8108 - val_accuracy: 0.7514
79/79 [==============================] - 0s 4ms/step - loss: 0.8284 - accuracy: 0.7447
Test score: 0.8284057378768921
Test accuracy: 0.744700014591217

保存模型

# 保存模型
model_json = model.to_json()
with open('cifar10_architecture1.json', 'w') as f:
    f.write(model_json)
model.save_weights('cifar10_weights1.h5', overwrite=True)

加载模型

# 利用获取到的模型进行预测
from keras.models import model_from_json
from keras.optimizers import SGD

model_architecture = 'cifar10_architecture1.json'
model_weights = 'cifar10_weights1.h5'
with open('cifar10_architecture1.json', 'r') as f:
    model_read = f.read()
model = model_from_json(model_read)
model.load_weights(model_weights)

加载模型之后就是对图片进行预测了, 在这里用爬虫从网上下载了些猫的图片然后对其进行预测,

这里我用opencv模块对图片进行预处理, 因为在训练模型的时候我们是对图片进行了一系列的操作, 包括输入的维度, 图片的大小, 首先加载图片

预测图片预处理操作

def get_inputs(src=[]):
    prex = []
    for s in src:
        input_img = cv.imread(s)
        input_img = cv.resize(input_img, (32, 32))
        input_img = cv.cvtColor(input_img, cv.COLOR_BGR2RGB)
        prex.append(input_img)
    #由于进入网络的图片是归一化后的图片, 因此在预测的时候也应该对其进行归一化操作
    prex = np.array(prex) / 255.0
    return prex

我是将图片保存在了文件夹下, 而opencv 读取图片文件需要文件的路径以及名称, 因此我需要获取图片文件夹下所有图片的名称并将其 路径+名称 添加到 list 列表中 需要用到os 模块

# 创建文件绝对路径列表
img_path = []
# 文件夹路径
dir = '/home/cyf/PycharmProjects/ProjectTensorFlow/img_cat'
for filename in os.listdir(dir):
	# 因为获取到的文件只是名称 要让opencv 读取需要添加前边的路径
	head = '/home/cyf/PycharmProjects/ProjectTensorFlow/img_cat/'
	path = head + filename
	img_path.append(path)

到这里我们获取到了图片的绝对路径, 可以用opencv 对图片进行处理了

prex = get_inputs(img_path)
# 在这里我们获取到了处理后的图片

到这里我们获取到了处理后的图, 然后可以用训练好的模型对其进行预测了

optim = SGD()
model.compile(loss='categorical_crossentropy', optimizer=optim, metrics=['accuracy'])
predictions = model.predict_classes(prex)

获取到prediction 是一个包含类别的列表

查看准确率

因为这一个文件夹内全部都是猫的图片, 所以通过判断标签下标是否是3 来判断是否预测正确

cat = 3
right = 0
for p in predictions:
    if p == cat:
        right+=1
accurcy = right/len(predictions)
print(len(predictions))
print(accurcy)
1473
0.3693143245078072

最后发现只有30 多的准率, 对于猫来说,

问题

1.在训练的时候准确率明明不是特别低70多把, 但是用在实际上的时候发现只有36% 的准确率, 这是不是过拟合的一种表现?
2.keras 进行预测的时候图片三个通道的顺序会不会对预测结果产生影响, 是不是因为自己的输入数据维度和keras 本身验证测试集的维度顺序有所不一样导致完全不一样的结果呢?

;原文链接:https://blog.csdn.net/qq_43475705/article/details/115413087
本站部分内容转载于网络,版权归原作者所有,转载之目的在于传播更多优秀技术内容,如有侵权请联系QQ/微信:153890879删除,谢谢!

推荐图文


随机推荐