人工智能-实验四( 三 )


读入数据
? 要构建一个图像分类的模型 , 图像的信息要分为两部分 , 一部分是图像本身的像素信息 , 另一类是图片的类别信息 。使用读入的图像信息是以BGR顺序读取的 , 需要转成RGB , 并且要将图片裁剪成统一的大小 。
? 加载图片:
def load_pictures():pics = []labels = []for key, v in map_characters.items():pictures = [k for k in glob.glob(imgsPath + "/" + v + "/*")]for pic in pictures:img = cv2.imread(pic)img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)img = cv2.resize(img, (img_width, img_height))pics.append(img)labels.append(key)return np.array(pics), np.array(labels)
? 其中存储了人物类别到数值的映射 , A-V映射到0-15 , 作为图像的类别label信息 。这个信息还需要转换为编码 , 在划分训练集和验证集时完成 。
? 划分训练集和测试集 , 测试集比例为0.15 。
def get_dataset():X, Y = load_pictures()Y = keras.utils.to_categorical(Y, num_classes) #转为OneHot编码X_train, X_test = train_test_split(X, test_size=0.15)y_train, y_test = train_test_split(Y, test_size=0.15)return X_train, X_test, y_train, y_test
构建模型
? 实验构建的CNN模型有6个带有ReLU激活函数的卷积层和一个全连接的隐藏层 , 每两层卷积层后有池化层来减少参数 , 并有层来防止过拟合 , 将池化层的部分输出舍弃 。最终的输出层输出图像属于各个类别的概率 。
def create_model_six_conv(input_shape):# ********** Begin *********#model = Sequential()model.add(Conv2D(32, (3, 3), activation='relu', input_shape=input_shape))#特征提取model.add(Conv2D(32, (3, 3), activation='relu'))model.add(MaxPooling2D(pool_size=(2, 2)))model.add(Dropout(0.2))#特征提取model.add(Conv2D(64, (3, 3),activation='relu'))model.add(Conv2D(64, (3, 3), activation='relu'))model.add(MaxPooling2D(pool_size=(2, 2)))model.add(Dropout(0.2))#特征提取model.add(Conv2D(128, (3, 3), activation='relu'))model.add(Conv2D(128, (3, 3), activation='relu'))model.add(MaxPooling2D(pool_size=(2, 2)))model.add(Dropout(0.2))#经过扁平层和全连接层 , 最终在输出层输出结果model.add(Flatten())#扁平层进行降维model.add(Dense(1024, activation='relu'))model.add(Dropout(0.5))model.add(Dense(num_classes, activation='softmax'))return model;
模型训练
? 开始模型训练前需要设定一些参数 。主要有以下部分:
loss:损失函数 , 对于分类问题 , 可以采用交叉熵损失函数(ropy):性能指标 , 采用准确率:一次训练采用的样本数据数量:训练轮次
? 在训练过程中 , 可以随着训练循环次数的增加 , 对权重调整的学习率进行衰减 。可以在保持一个恒定学习速率一段时间后立即降低 , 借助模块的一个方法 r [ 1 ] ^{[1]} [1]实现:
def lr_schedule(epoch):initial_lrate = 0.01drop = 0.5epochs_drop = 10.0lrate = initial_lrate * math.pow(drop, math.floor((1+epoch)/epochs_drop))return lrate
? 此外 , 在测试时为了保证长时间的训练可以中途保存 , 使用模块的保存点来存储模型的权重 , 保存最好的模型 。
lr = 0.01sgd = SGD(lr=lr, decay=0.0 , momentum=0.9 , nesterov= True)model.compile(loss= 'categorical_crossentropy' ,optimizer= sgd,metrics=['accuracy'] )def lr_schedule(epoch):lr = 0.01drop = 0.5epochs_drop = 10.0lrate = lr * math.pow(drop, math.floor((1+epoch)/epochs_drop))return lratebatch_size = 32epochs = 20filepath = "model.h5"history = model.fit(X_train, y_train,batch_size=batch_size,epochs=epochs,validation_data=http://www.kingceram.com/post/(X_test, y_test),shuffle=True,#打乱数据集verbose = 0,callbacks=[LearningRateScheduler(lr_schedule),ModelCheckpoint(filepath, save_best_only=True)])