import os
import tensorflow as tf
from datetime import datetime
import numpy as np
from keras import models
from keras.preprocessing.image import ImageDataGenerator
import matplotlib.pyplot as plt
from tensorflow import keras
from keras.utils.np_utils import to_categorical
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Conv2D, MaxPooling2D
batch_size = 200
num_classes = 10
epochs = 2000
data_augmentation = True
# 展示数据
def showPic(X_train, y_train):
# 键列表
classes = ['plane', 'car', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck']
# 获取键列表长度
num_classes = len(classes)
# 取7个数据
samples_per_class = 7
# 迭代键列表
for y, cls in enumerate(classes):
idxs = np.flatnonzero(y_train == y)
# 一个类别中挑出一些
idxs = np.random.choice(idxs, samples_per_class, replace=False)
for i, idx in enumerate(idxs):
plt_idx = i * num_classes + y + 1
plt.subplot(samples_per_class, num_classes, plt_idx)
plt.imshow(X_train[idx].astype('uint8'))
plt.axis('off')
if i == 0:
plt.title(cls)
plt.show()
# 数据增强
def data_augmented():
datagen = ImageDataGenerator(
# 输入数据中心化,均值为0,即每个通道减去通道均值
featurewise_center=False,
# 样本中心化,每个样本减去样本均值
samplewise_center=False,
# 输入标准化,每个通道除以标准差
featurewise_std_normalization=False,
# 样本标准化
samplewise_std_normalization=False,
# 白化,去除样本相关性
zca_whitening=False,
# 随机旋转角度
rotation_range=0,
# 平移
width_shift_range=0.1,
# 垂直移动
height_shift_range=0.1,
# 水平翻转
horizontal_flip=True,
# 垂直翻转
vertical_flip=False)
return datagen
def loadData():
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.cifar10.load_data()
# showPic(x_train, y_train)
# 输入数据归一化
train_data = x_train.astype('float32') / 255.
test_data = x_test.astype('float32') / 255.
# 输出标签One-Hot编码
train_labels = to_categorical(y_train, 10)
test_labels = to_categorical(y_test, 10)
return train_data, train_labels, test_data, test_labels
def create_model():
# 创建模型,线性堆叠
model = models.Sequential()
model.add(Conv2D(32, (3, 3), padding='same', input_shape=train_data.shape[1:]))
model.add(Activation('relu'))
model.add(Conv2D(32, (3, 3)))
model.add(Activation('relu'))
model.add(Dropout(0.25))
model.add(Conv2D(64, (3, 3), padding='same'))
model.add(Activation('relu'))
model.add(Conv2D(64, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Conv2D(128, (3, 3), padding='same'))
model.add(Activation('relu'))
model.add(Conv2D(128, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Conv2D(256, (3, 3), padding='same'))
model.add(Activation('relu'))
model.add(Conv2D(256, (1, 1)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes))
model.add(Activation('softmax'))
model.summary()
return model
def create_model1():
# 搭面包架子
model = models.Sequential()
# 加面包:卷积层1 和 池化层1
model.add(Conv2D(filters=32, kernel_size=(3, 3),
input_shape=(32, 32, 3),
activation='relu',
padding='same'))
model.add(Dropout(rate=0.25))
model.add(MaxPooling2D(pool_size=(2, 2))) # 16* 16
# 加面包:卷积层2 和 池化层2
model.add(Conv2D(filters=64, kernel_size=(3, 3),
activation='relu', padding='same'))
model.add(Dropout(0.25))
model.add(MaxPooling2D(pool_size=(2, 2))) # 8 * 8
# Step3 建立神經網路(平坦層、隱藏層、輸出層)
model.add(Flatten()) # FC1,64个8*8转化为1维向量
model.add(Dropout(rate=0.25))
model.add(Dense(1024, activation='relu')) # FC2 1024
model.add(Dropout(rate=0.25))
model.add(Dense(10, activation='softmax')) # Output 10
print(model.summary())
return model
if __name__ == '__main__':
train_data, train_labels, test_data, test_labels = loadData()
model = create_model()
try:
model.load_weights("SaveModel/cifarCnnModel.h5")
print("载入模型成果!继续训练模型")
except:
print("载入模型失败!开始训练一个新模型")
# 编译模型
opt = keras.optimizers.RMSprop(lr=0.0001, decay=1e-6)
model.compile(loss='categorical_crossentropy',
optimizer=opt,
metrics=['accuracy'])
callbacks = [
keras.callbacks.TensorBoard(
log_dir='mylogdir',
histogram_freq=1,
embeddings_freq=1,
)
]
# 开始拟合,计时
start_time = datetime.now()
# history = model.fit(train_data, train_labels,
# validation_split=0.2,
# epochs=10, batch_size=128, verbose=1,
# callbacks=callbacks)
datagen = data_augmented()
datagen.fit(train_data)
model.fit_generator(datagen.flow(train_data,
train_labels,
batch_size=batch_size),
steps_per_epoch=train_data.shape[0] // batch_size,
epochs=epochs,
validation_data=(test_data, test_labels))
finish_time = datetime.now()
os.mkdir("SaveModel")
model.save_weights("SaveModel/cifarCnnModel.h5")
print("Saved model to disk")
print('运行时间: ', (finish_time - start_time).seconds)
prediction = model.predict(test_data)
print(prediction)
prediction = to_categorical(prediction)
# 计算测试集上的错误率
erro_count = 0
for i in range(len(test_labels)):
if (test_labels[i] != np.argmax(prediction[i])):
erro_count += 1
print('当前神经网络在测试集上的正确率为:%f' % (1 - erro_count / len(test_labels) + 0.0))
模型0精度74%+
模型1精度68%