图片2分类卷积神经网络模型训练、分类预测案例全过程(1)


前言

(1)尽管目前有关卷积神经网络深度学习的相关材料较多,但深度学习牵涉到数据预处理、模型构建、模型调用等环节,我也是一个初学者,中间有很多问题都是查阅好多资料才得以解决,我在这里会尽量的详细写清楚关键环节,供和我一样的初学者参考。超过2分类的多分类操作流程基本一样。
(2)这里我不提供深度学习的最基础原理,都是从实际操作中出发,能够上手应用。
(3)主要内容包括:数据预处理(包括tfrecord格式数据生成与读取喂给网络)、模型搭建及相关参数设置、模型调用等主要内容。
(4)如下的这些代码是基于win10系统、rtx3090显卡的tensorflow-gpu环境,如果没有gpu环境,cpu也是可以的。python版本3.8。
(5)本人也是个非专业的初学者,肯定还有埋坑的地方,也请大神能够给予指点,也方便我改进提高


一、目标:图片的2分类预测如何完成?

(1)目前有一堆图片,我们只需要图片分为两类,一类的标签为dis、另一次标签为undis,图片格式为jpg,每个图片命名规则为:dis_***.jpg或undis_***.jpg。通过图片名字的split可以知道某张图片属于哪个类别。
(2)数据分别放到2个文件夹里面,一个用于模型训练的文件夹名字为train_da、另一个用于训练好的模型测试的数据文件夹名字为test_da(也可以认为是实际需要分类需要的数据)。

二、主要内容

1.数据预处理

为了提高数据读写性能,我们将数据写为tfrecord格式数据,包括图片本身的tfrecord和对应标签的tfrecord。
下面的函数分别用于生成tfrecord数据和读取tfrecord数据:

# 样本数据tfrecord格式文件制作与读取
def preprocess_image(_image):'''这个函数用于对jpg图片数据进行解码,包括简单的归一化处理resize后的尺寸根据后面网络结构输入数据进行相同的调整'''_image = tf.image.decode_jpeg(_image, channels=3)_image = tf.image.resize(_image, [256, 256])_image /= 255.0  # normalize to [0,1] rangereturn _imagedef load_and_preprocess_image(_path):'''这个函数用于加载jpg图片数据'''_image = tf.io.read_file(_path)_image = preprocess_image(_image)return _imagedef img_parse(x):'''这个函数用于读取jpg图片tfrecord数据时,对图片数据进行解析'''result = tf.io.parse_tensor(x, out_type=tf.float32)result = tf.reshape(result, [256, 256, 3])return resultdef label_parse(y):'''这个函数用于读取jpg图片对应的标签tfrecord数据时,对标签数据进行解析'''result = tf.io.parse_tensor(y, out_type=tf.int32)result = tf.reshape(result, [2])return resultdef tfrecord_data_create(_data_path, _img_tfrecord_abspath, _label_tfrecord_abspath):'''制作训练样本tdrecord格式文件_data_path为jpg格式图片存放绝对路径_img_tfrecord_abspath图片数据tfrecord保存绝对路径_label_tfrecord_abspath标签数据tfrecord保存绝对路径'''all_imgs_path = get_all_file_abspath_with_specific_format_under_one_folder(_data_path, '*.jpg')random.shuffle(all_imgs_path)label2index_dict = {'dis': 0, 'undis': 1}all_labels = [label2index_dict.get(os.path.basename(a_img).split('_')[0])for a_img in all_imgs_path]all_labels = tf.one_hot(indices=all_labels, depth=2, on_value=1, off_value=0, axis=-1)ds_image = tf.data.Dataset.from_tensor_slices(all_imgs_path)ds_image = ds_image.map(load_and_preprocess_image)ds_image = ds_image.map(tf.io.serialize_tensor)ds_image_record = tf.data.experimental.TFRecordWriter(_img_tfrecord_abspath)ds_image_record.write(ds_image)ds_label = tf.data.Dataset.from_tensor_slices(tf.cast(all_labels, tf.int32))ds_label = ds_label.map(tf.io.serialize_tensor)ds_label_record = tf.data.experimental.TFRecordWriter(_label_tfrecord_abspath)ds_label_record.write(ds_label)def tfrecord_data_read_decode(_img_tfrecord_abspath, _label_tfrecord_abspath, _ratio=0.2):'''读取和解码训练样本tfrecord格式文件_img_tfrecord_abspath图片数据tfrecord保存绝对路径_label_tfrecord_abspath标签数据tfrecord保存绝对路径_ratio训练模型验证数据集占比,默认值为20%'''img_ds = tf.data.TFRecordDataset(_img_tfrecord_abspath)_tem = 0img_length = len([_tem for tem in img_ds])AUTOTUNE = tf.data.experimental.AUTOTUNEimg_ds = img_ds.map(img_parse, num_parallel_calls=AUTOTUNE)label_ds = tf.data.TFRecordDataset(_label_tfrecord_abspath)_tem = 0label_length = len([_tem for tem in label_ds])label_ds = label_ds.map(label_parse, num_parallel_calls=AUTOTUNE)if img_length != label_length:print('......严重错误:图片数据和标签数据tfrecord格式文件长度不一致!')else:img_label_ds = tf.data.Dataset.zip((img_ds, label_ds))# 模型训练数据和模型测试数据划分,保证两部分数据没有重叠verify_ds_num = int(img_length*_ratio)train_ds_num = img_length - verify_ds_numprint('样本总数据{}个, 训练数据有{}个, 验证数据有{}个.'.format(img_length, train_ds_num, verify_ds_num))train_ds = img_label_ds.skip(verify_ds_num)verify_ds = img_label_ds.take(verify_ds_num)# 获取dis样本数量,这个是我的项目需要的内容,可以根据实际情况进行删减dis_num = 0undis_num = 0for label in label_ds.take(img_length):dis_value = label.numpy()[0]if dis_value == 1:dis_num += 1else:undis_num += 1return train_ds, train_ds_num, verify_ds, verify_ds_num, dis_num, undis_num# 为什么返回值的是train_ds, train_ds_num, verify_ds, verify_ds_num, dis_num, undis_num,是为了和后面模型训练直接对接,方便喂给神经网络# 上述6个参数代表的含义分别是:第一个参数train_ds:模型训练数据#                          第二个参数train_ds_num:模型训练数据个数#                          第三个参数verify_ds:模型验证数据#                           第四个参数verify_ds_num:模型验证数据个数#                         第五个、第六个参数 dis_num和undis_num:分别是两个类别样本的个数(包括训练和验证数据)# 可能有人问为什么不讲jpg图片数据和标签数据写入到一个tfrecord中,不更方便,我也知道这样方便,想到了但是没做到,请高人指点。

2.模型构建、数据喂入、模型训练与保存

(1)模型构建、数据喂入、模型训练与保存我写入到一个函数中了,方便调用。
(2)这里有两个函数,一个是模型第一次训练(model_train_save),第二个是基于前面模型训练的间断点数据进行模型再训练(model_retrain_save)。

def model_train_save(train_result_save_folder, checkpoint_file_folder, tensorboard_file_folder, save_file_name, train_data, train_data_number, verify_data, verify_data_number, dis_num, undis_num, private_optimizers='adam', batch_size=16, lr=5, loops=5, isDraw=1):'''这个是模型第一次训练的函数train_result_save_folder这个是一个文件夹的绝对路径,用于保存模型训练结果,包括①训练好的模型(h5)②模型训练、验证精度和损失曲线图片③模型训练的关键参数和精度、损失值。如第二个图片所示。checkpoint_file_folder这个是一个文件夹的绝对路径,用于保存checkpoint文件,格式为.cp,这个文件可以保存模型训练过程的最优结果tensorboard_file_folder这个是一个文件夹的绝对路径,用于保存模型训练的tensorboard相关文件,用于后期展示、查看等save_file_name所有保存文件的统一名字,包括train_result_save_folder里面三个文件的名字、checkpoint_file_folder里面cp文件的名字,tensorboard_file_folder里面tensorboard相关文件的名字,大家的名字都一样,只是后后缀名不同。train_data下面6个参数就不重复说明了,可回看“数据预处理”最后面,有详细说明train_data_numberverify_dataverify_data_numberdis_numundis_numprivate_optimizers='adam'这个是优化器,默认值是adam,这个也比较通用batch_size=16批处理大小lr=5学习速率初始值,这里的5表示10的负5次方loops=5模型训练次数isDraw=1模型训练、验证过程精度、损失曲线是否绘图,默认是绘图'''# 数据分批次读取AUTOTUNE = tf.data.experimental.AUTOTUNEtrain_data = train_data.cache(r'D:\Train_Cache_Temporary_Data\Train_Cache_Temporary_Data')# cache用于加快数据取用速度train_data = train_data.shuffle(buffer_size=train_data_number)# 把训练数据乱序train_data = train_data.repeat()# 数据重复,参数为空表示重复无数遍,不会存在读取不到数据batch的情况train_data = train_data.batch(batch_size).prefetch(buffer_size=AUTOTUNE)# 数据分批次读取和预读取train_data = train_data.prefetch(buffer_size=AUTOTUNE)verify_data = verify_data.batch(batch_size)# 上面两句话是验证数据的读取,不需要乱序、重复等操作# 下面是建立模型,包括迁移模型和自己搭建网络,这里迁移学习以resnet50为例,其他模型与此相同resnet_base_structure = tf.keras.applications.resnet50.ResNet50(input_shape=(256, 256, 3), weights='imagenet', include_top=False)# include_top=False表示不需要resnet50的全连接和分类层,根据自己的需要构建后面的全连接和分类层resnet_base_structure.trainable = True# 如果是迁移学习,模型构建如下:transf_model = tf.keras.Sequential([resnet_base_structuretf.keras.layers.GlobalAveragePooling2D(),tf.keras.layers.Dense(1024, activation='relu'),tf.keras.layers.Dropout(0.5),tf.keras.layers.Dense(512, activation='relu'),tf.keras.layers.Dropout(0.5),tf.keras.layers.Dense(2, 'softmax')])# 如果是自己搭建网络,模型构建如下。至于卷积层个数、卷积核大小、步长、填充方式、激活函数,我都使用了最常用的参数,具体可以根据实验结果进行优化调整private_model = tf.keras.Sequential([tf.keras.layers.Conv2D(filters=64, kernel_size=3, strides=1, padding='same', input_shape=(256, 256, 3), activation='relu',),tf.keras.layers.BatchNormalization(),tf.keras.layers.Conv2D(filters=64, kernel_size=3, strides=1, padding='same', activation='relu',),tf.keras.layers.BatchNormalization(),tf.keras.layers.MaxPooling2D(),tf.keras.layers.Conv2D(filters=128, kernel_size=3, strides=1, padding='same', activation='relu',),tf.keras.layers.BatchNormalization(),tf.keras.layers.Conv2D(filters=128, kernel_size=3, strides=1, padding='same', activation='relu',),tf.keras.layers.BatchNormalization(),tf.keras.layers.MaxPooling2D(),tf.keras.layers.Conv2D(filters=256, kernel_size=3, strides=1, padding='same', activation='relu',),tf.keras.layers.BatchNormalization(),tf.keras.layers.Conv2D(filters=256, kernel_size=3, strides=1, padding='same', activation='relu',),tf.keras.layers.BatchNormalization(),# tf.keras.layers.Conv2D(filters=256, kernel_size=3, strides=1, padding='same', activation='relu',),# tf.keras.layers.BatchNormalization(),tf.keras.layers.MaxPooling2D(),tf.keras.layers.Conv2D(filters=512, kernel_size=3, strides=1, padding='same', activation='relu',),tf.keras.layers.BatchNormalization(),tf.keras.layers.Conv2D(filters=512, kernel_size=3, strides=1, padding='same', activation='relu',),tf.keras.layers.BatchNormalization(),# tf.keras.layers.Conv2D(filters=512, kernel_size=3, strides=1, padding='same', activation='relu',),# tf.keras.layers.BatchNormalization(),tf.keras.layers.MaxPooling2D(),tf.keras.layers.Conv2D(filters=512, kernel_size=3, strides=1, padding='same', activation='relu',),tf.keras.layers.BatchNormalization(),tf.keras.layers.Conv2D(filters=512, kernel_size=3, strides=1, padding='same', activation='relu',),tf.keras.layers.BatchNormalization(),# tf.keras.layers.Conv2D(filters=512, kernel_size=3, strides=1, padding='same', activation='relu',),# tf.keras.layers.BatchNormalization(),tf.keras.layers.MaxPooling2D(),tf.keras.layers.GlobalAveragePooling2D(),tf.keras.layers.Dense(1024, activation='relu'),tf.keras.layers.Dropout(0.5),tf.keras.layers.Dense(512, activation='relu'),tf.keras.layers.Dropout(0.5),tf.keras.layers.Dense(2, 'softmax')])# 计算初始学习速率lr_value = float(math.pow(10, -1*lr))# 选择确定优化器函数if private_optimizers == 'sgd':private_optimizers_result = tf.keras.optimizers.SGD(learning_rate=lr_value, momentum=0.9)elif private_optimizers == 'adagrad':private_optimizers_result = tf.keras.optimizers.Adagrad(learning_rate=lr_value)elif private_optimizers == 'adadelta':private_optimizers_result = tf.keras.optimizers.Adadelta(learning_rate=lr_value)elif private_optimizers == 'rmsprop':private_optimizers_result = tf.keras.optimizers.RMSprop(learning_rate=lr_value)elif private_optimizers == 'adam':private_optimizers_result = tf.keras.optimizers.Adam(learning_rate=lr_value)elif private_optimizers == 'adamax':private_optimizers_result = tf.keras.optimizers.Adamax(learning_rate=lr_value)print('______学习速率为{},优化器函数为{}.'.format(lr_value, private_optimizers))# 模型编译,如果是迁移学习,就是如下。如果是自己搭建的网络结构,就使用private_model.compiletransf_model.compile(optimizer=private_optimizers_result, loss=tf.keras.losses.CategoricalCrossentropy(), metrics=['acc'])   # 计算模型训练、验证stepssteps_train = train_data_number//batch_sizesteps_verify = verify_data_number//batch_size# 为模型保存的所有文件生成文件名,这里我将优化器、学习速率、批大小都保存到文件名中了,方便查看,一目了然save_name = 'Trained_model_' + save_file_name + '_Op=' + private_optimizerssave_name = save_name + "_Lr=" + str(lr) + '_Bs=' + str(batch_size)# 设置cp文件回调函数checkpoint_file_name = save_name + '.ckpt'checkpoint_file_abspath = os.path.join(checkpoint_file_folder, checkpoint_file_name)cp_callback_function = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_file_abspath, monitor='val_loss', save_best_only=True, save_weights_only=False)# 设置tensorboard回调函数tensorboard_file_abspath = os.path.join(tensorboard_file_folder, save_name)tensorboard_callback_function = tf.keras.callbacks.TensorBoard(log_dir=tensorboard_file_abspath, histogram_freq=1)# 设置学习速率递减回调函数set the Learning rate decay callback functionlr_decay_ratio = U_lr_decay_ratiolr_reduce_callback_cunction = tf.keras.callbacks.ReduceLROnPlateau(monitor='val_loss', factor=lr_decay_ratio, patience=U_learn_rate_reduce_patience_epochs, mode='auto', verbose=1)# 设置早停回调函数early_stopping_function = tf.keras.callbacks.EarlyStopping(monitor='val_loss', min_delta=0.00001, patience=10, verbose=1, mode='auto', baseline=None, restore_best_weights=False)# 下面开始模型训练,还是以迁移学习模型为例if dis_num <= undis_num:# 这里的weights是调整2个样本数据不平衡使用的,如果两种标签的样本数量差距很大对训练结果不利影响很大,通过weights参数可以减少这种不利影响weights = {0: round(undis_num/dis_num), 1: 1}else:weights = {0: 1, 1: round(dis_num/undis_num)}start_time = time.time()history = transf_model.fit(train_data, epochs=loops, steps_per_epoch=steps_train,validation_data=verify_data, validation_steps=steps_verify,class_weight=weights,callbacks=[cp_callback_function, tensorboard_callback_function, lr_reduce_callback_cunction, early_stopping_function])print('本程序训练过程耗时{}s.'.format(round((time.time() - start_time), 2)))save_path = os.path.join(train_result_save_folder, (save_name + '.png'))if isDraw == 1:draw_history(history.epoch,history.history.get('acc'),history.history.get('loss'),history.history['val_acc'],history.history['val_loss'],savepath=save_path)# 计算训练后模型损失和精度评估值evaluation_loss, evaluation_accuracy = model.evaluate(verify_data, verbose=1)# save_model_parameter是用于方便折叠这一段程序save_model_parameter = Trueif save_model_parameter:# 模型保存model_save_path = os.path.join(train_result_save_folder, (save_name + '.h5'))model.save(model_save_path)# 将模型训练结果参数保存到excelxls_file_path = os.path.join(train_result_save_folder, (save_name + '.xls'))_file = xlwt.Workbook(encoding='utf-8')_sheet = _file.add_sheet('TrainedResult', cell_overwrite_ok=True)_sheet.write(0, 0, 'Train Data Number')_sheet.write(0, 1, train_data_number)_sheet.write(0, 2, 'Verfy Data Number')_sheet.write(0, 3, verify_data_number)_sheet.write(1, 0, 'Epochs')_sheet.write(1, 1, loops)_sheet.write(1, 2, 'Shuffle Number')_sheet.write(1, 3, train_data_number)_sheet.write(2, 0, 'Batch Size')_sheet.write(2, 1, batch_size)_sheet.write(3, 0, 'Initial learn Rate')_sheet.write(3, 1, lr_value)_sheet.write(3, 2, 'Learning rate decay ratio')_sheet.write(3, 3, lr_decay_ratio)_sheet.write(4, 0, 'Model Eval_loss')_sheet.write(4, 1, evaluation_loss)_sheet.write(4, 2, 'Modle Eval_accuracy')_sheet.write(4, 3, evaluation_accuracy)_sheet.write(5, 0, 'Epoch')_sheet.write(5, 1, 'Train Accuracy')_sheet.write(5, 2, 'Train Loss')_sheet.write(5, 3, 'Verify Accuracy')_sheet.write(5, 4, 'Verify Loss')_sheet.write(5, 5, 'Learn rate')for i_xls in range(loops):_sheet.write(i_xls + 6, 0, i_xls + 1)_sheet.write(i_xls + 6, 1, history.history.get('acc')[i_xls])_sheet.write(i_xls + 6, 2, history.history['loss'][i_xls])_sheet.write(i_xls + 6, 3, history.history.get('val_acc')[i_xls])_sheet.write(i_xls + 6, 4, history.history['val_loss'][i_xls])_sheet.write(i_xls + 6, 5, float(history.history.get('lr')[i_xls]))_file.save(xls_file_path)return evaluation_loss, evaluation_accuracy# 至此模型搭建、数据喂入、模型训练已全部完成#  上面还用到1个绘图函数draw_history,该函数具体如下:
def draw_history(epochs, train_acc, train_loss, validation_acc, validation_loss, savepath=None):'''模型训练过程accuracy、loss变化绘图'''plt.figure(figsize=(12, 4))plt.subplot(1, 2, 1)plt.plot(epochs, train_acc, label='Train process')plt.plot(epochs, validation_acc, label='Validation process')plt.title('Train History of Accuracy for train and validation process')plt.ylabel('Accuracy')plt.xlabel('Epoch')plt.legend()plt.subplot(1, 2, 2)plt.plot(epochs, train_loss, label='Train process')plt.plot(epochs, validation_loss, label='Validation process')plt.title('Train History of Loss for train and validation process')plt.ylabel('Loss')plt.xlabel('Epoch')plt.legend()# plt.show()if savepath:plt.savefig(savepath)

第二个图片在这里:

excel打开后是这样的:

png图片是这样的:

如果是基于前面模型训练的间断点数据进行模型再训练,模型搭建、数据未如、模型训练完整函数具体如下:

def model_retrain_save(train_result_save_folder, trained_model_path,checkpoint_file_folder, tensorboard_file_folder, retrained_save_file_name,train_data, train_data_number, verify_data, verify_data_number, dis_num, undis_num,private_optimizers='adam', batch_size=16,lr=5, loops=5, isDraw=1):'''所有参数与model_retrain_save函数中的参数意义完全一样只有trained_model_path,这参数是上一次模型训练后保存的cp文件绝对路径'''# 数据分批次读取train_data = train_data.repeat().shuffle(shuffle_number).batch(batch_size)AUTOTUNE = tf.data.experimental.AUTOTUNEtrain_data = train_data.cache()train_data = train_data.prefetch(buffer_size=AUTOTUNE)verify_data = verify_data.batch(batch_size)# 加载模型trained_model = tf.keras.models.load_model(trained_model_path)steps_train = train_data_number//batch_sizesteps_verify = verify_data_number//batch_sizelr_value = float(math.pow(10, -1*lr))if private_optimizers == 'sgd':private_optimizers_result = tf.keras.optimizers.SGD(learning_rate=lr_value, momentum=0.9)elif private_optimizers == 'adagrad':private_optimizers_result = tf.keras.optimizers.Adagrad(learning_rate=lr_value)elif private_optimizers == 'adadelta':private_optimizers_result = tf.keras.optimizers.Adadelta(learning_rate=lr_value)elif private_optimizers == 'rmsprop':private_optimizers_result = tf.keras.optimizers.RMSprop(learning_rate=lr_value)elif private_optimizers == 'adam':private_optimizers_result = tf.keras.optimizers.Adam(learning_rate=lr_value)elif private_optimizers == 'adamax':private_optimizers_result = tf.keras.optimizers.Adamax(learning_rate=lr_value)trained_model.compile(optimizer=private_optimizers_result, loss=tf.keras.losses.CategoricalCrossentropy(), metrics=['acc'])# set the name for saved filessave_name = 'Retrained_model_' + retrained_save_file_name + '_Op=' + private_optimizerssave_name = save_name + "_Lr=" + str(lr) + '_Bs=' + str(batch_size)# set the checkpoint parameterscheckpoint_file_name = save_name + '.ckpt'checkpoint_file_abspath = os.path.join(checkpoint_file_folder, checkpoint_file_name)cp_callback_function = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_file_abspath, monitor='val_loss',save_best_only=True, save_weights_only=False)# set the tensorboard parametertensorboard_file_abspath = os.path.join(tensorboard_file_folder, save_name)tensorboard_callback_function = tf.keras.callbacks.TensorBoard(log_dir=tensorboard_file_abspath, histogram_freq=1)# set the Learning rate decay callback functionlr_decay_ratio = U_lr_decay_ratiolr_reduce_callback_cunction = tf.keras.callbacks.ReduceLROnPlateau(monitor='val_loss', factor=lr_decay_ratio, patience=U_learn_rate_reduce_patience_epochs, mode='auto', verbose=1)if dis_num <= undis_num:weights = {0: round(undis_num/dis_num), 1: 1}else:weights = {0: 1, 1: round(dis_num/undis_num)}start_time = time.time()history = trained_model.fit(train_data, epochs=loops, steps_per_epoch=steps_train, validation_data=verify_data, validation_steps=steps_verify,class_weight=weights, callbacks=[cp_callback_function, tensorboard_callback_function, lr_reduce_callback_cunction])print('本程序训练过程耗时{}s.'.format(round((time.time() - start_time), 2)))save_path = os.path.join(train_result_save_folder, (save_name + '.png'))if isDraw == 1:draw_history(history.epoch, history.history.get('acc'), history.history.get('loss'), history.history['val_acc'], history.history['val_loss'], savepath=save_path)evaluation_loss, evaluation_accuracy = trained_model.evaluate(verify_data, verbose=1)# 方便折叠这一段程序save_model_parameter = Trueif save_model_parameter:# 模型保存model_save_path = os.path.join(train_result_save_folder, (save_name + '.h5'))trained_model.save(model_save_path)# 将模型训练结果参数保存到excelxls_file_path = os.path.join(train_result_save_folder, (save_name + '.xls'))_file = xlwt.Workbook(encoding='utf-8')_sheet = _file.add_sheet('TrainedResult', cell_overwrite_ok=True)_sheet.write(0, 0, 'Train Data Number')_sheet.write(0, 1, train_data_number)_sheet.write(0, 2, 'Verfy Data Number')_sheet.write(0, 3, verify_data_number)_sheet.write(1, 0, 'Epochs')_sheet.write(1, 1, loops)_sheet.write(1, 2, 'Shuffle Number')_sheet.write(1, 3, shuffle_number)_sheet.write(2, 0, 'Batch Size')_sheet.write(2, 1, batch_size)_sheet.write(3, 0, 'Initial learn Rate')_sheet.write(3, 1, lr_value)_sheet.write(3, 2, 'Learning rate decay ratio')_sheet.write(3, 3, lr_decay_ratio)_sheet.write(4, 0, 'Model Eval_loss')_sheet.write(4, 1, evaluation_loss)_sheet.write(4, 2, 'Modle Eval_accuracy')_sheet.write(4, 3, evaluation_accuracy)_sheet.write(5, 0, 'Epoch')_sheet.write(5, 1, 'Train Accuracy')_sheet.write(5, 2, 'Train Loss')_sheet.write(5, 3, 'Verify Accuracy')_sheet.write(5, 4, 'Verify Loss')_sheet.write(5, 5, 'Learn rate')for i_xls in range(loops):_sheet.write(i_xls + 6, 0, i_xls + 1)_sheet.write(i_xls + 6, 1, history.history.get('acc')[i_xls])_sheet.write(i_xls + 6, 2, history.history['loss'][i_xls])_sheet.write(i_xls + 6, 3, history.history.get('val_acc')[i_xls])_sheet.write(i_xls + 6, 4, history.history['val_loss'][i_xls])_sheet.write(i_xls + 6, 5, float(history.history.get('lr')[i_xls]))_file.save(xls_file_path)return evaluation_loss, evaluation_accuracy

该处使用的url网络请求的数据。

3.上述函数的实际操作使用

假设现在模型训练所有的数据都保存在traind_ds文件夹中,我们(1)制作tfrecord数据(2)读取tdrecord数据(3)将读取到的tdrecord数据喂给网络,并进行模型训练。

traind_ds = r''  #训练数据文件夹绝对路径

(1)制作tfrecord数据

# 假设生成的jpg图片数据及其对应标签数据tfrecord数据绝对路径分别为:img_tfrecord_abspath, label_tfrecord_abspath
tfrecord_data_create(traind_ds, img_tfrecord_abspath, label_tfrecord_abspath)

(2)读取tdrecord数据

train_ds, train_ds_num, verify_ds, verify_ds_num, dis_num, undis_num = tfrecord_data_read_decode(img_tfrecord_abspath, label_tfrecord_abspath, ratio=0.2)
# 这里的ratio=0.2是指训练样本占样本总数的80%,验证样本占比20%

(3)数据喂给网络,并进行网络训练

train_result_save_folder = r''  #模型训练结果保存文件夹绝对路径
checkpoint_file_folder = r'' #模型cp文件保存绝对路径
tensorboard_file_folder = r''    #模型tensorboard文件保存绝对路径
save_file_name = '模型第一次训练'
model_train_save(train_result_save_folder, checkpoint_file_folder, tensorboard_file_folder, save_file_name,train_data, train_data_number, verify_data, verify_data_number, dis_num, undis_num,private_optimizers='adam', batch_size=16, lr=5, loops=20, isDraw=1)
# 假设这一次模型训练后cp文件保存的绝对路径为:checkpoint_file_abspath = r'E:\.....\*****.ckpt'
# 其中*****.ckpt为cp文件名
# 如果我们想基于这个最优的结果对模型进行再训练,调用函数如下:
train_result_save_folder = r''  #模型训练结果保存文件夹绝对路径
trained_model_path = r'E:\.....\*****.ckpt'
checkpoint_file_folder = r'' #模型cp文件保存绝对路径
tensorboard_file_folder = r''    #模型tensorboard文件保存绝对路径
save_file_name = '模型第一次再训练'
model_retrain_save(train_result_save_folder, trained_model_path,checkpoint_file_folder, tensorboard_file_folder, retrained_save_file_name,train_data, train_data_number, verify_data, verify_data_number, dis_num, undis_num,private_optimizers='adam', batch_size=16, lr=5, loops=15, isDraw=1):

总结

(1)函数较长,可能出现个别错误,如果运行报错,要具体分析看下。
(2)本来想把模型使用、分类预测也写进来,实在太长了,这个内容放到下一篇中。
(3)本人也是非专业初学者,还请路过的高人指点改进。

图片2分类卷积神经网络模型训练、分类预测案例全过程(1)相关推荐

  1. 图片2分类卷积神经网络模型训练、分类预测案例全过程(2)

    上一篇博客内容讲述了卷积神经网络模型构建.训练以及模型的保存,包括训练样本数据的预处理和喂给网络. 本篇博客内容讲述训练好的模型的应用和实际图片数据的分类预测. 图片2分类卷积神经网络模型训练.分类预 ...

  2. 波士顿房价预测python代码_使用Python和Numpy构建神经网络模型——波士顿房价预测案例...

    原标题:使用Python和Numpy构建神经网络模型--波士顿房价预测案例

  3. Python人脸微笑识别2-----Ubuntu16.04基于Tensorflow卷积神经网络模型训练的Python3+Dlib+Opencv实现摄像头人脸微笑检测

    Python人脸微笑识别2--卷积神经网络进行模型训练目录 一.微笑数据集下载 1.微笑数据集下载 2.创建人脸微笑识别项目 3.数据集上传至Ubuntu人脸微笑识别项目文件夹 二.Python代码实 ...

  4. Tensorflow精进之路(二):两层卷积神经网络模型训练MNIST

    这段时间,打算把TensorFlow再补补,提升一下技术水平~ 希望我能坚持下来,抽空把这本书刷下来吧~ 导入数据 下面的代码会直接下载数据,如果没有那个文件夹的话,但是,如果有这个文件夹而且里面有那 ...

  5. 【CNTK】CNTK学习笔记之应用卷积神经网络模型进行数据预测

    跳坑里爬了三天,爬不出来了. VS2013新建CPP工程,把 \cntk\Examples\Evaluation\CPPEvalClient\CPPEvalClient.cpp 拷贝到工程里,在项目上 ...

  6. TensorFlow神经网络模型训练

    TensorFlow神经网络模型训练 fashion_MNIST数据集的模型识别训练 fashion_mnist数据加载 图片保存 fashion_mnist可视化 神经网络模型训练,预测 模型保存 ...

  7. TensorFlow精进之路(三):两层卷积神经网络模型将MNIST未识别对的图片筛选出来

    1.概述 自从开了专栏<TensorFlow精进之路>关于对TensorFlow的整理思路更加清晰.上两篇讲到Softmax回归模型和两层卷积神经网络模型训练MNIST,虽然使用神经网络能 ...

  8. 卷积神经网络模型搭建(水果识别项目)

    项目概述 把一堆苹果.香蕉的图片交给模型训练,让它判断这张图是苹果还是香蕉 说明: 环境要用到Anaconda 就是要安装下面的包,本博客只写了数据封装和模型搭建的代码. 数据集封装 import o ...

  9. 卷积神经网络模型解读及数学原理 ——翻拍图片识别

    目录 一.需求背景 二.知识储备 1.深度学习 2.卷积神经网络 3.PyTorch框架 4.张量 5.梯度下降法 三.模型解读 1.输入层 2.隐藏层 1)卷积层 2)激活函数 3)池化层 4)流向 ...

最新文章

  1. 全线衰退:PC产业一枝孤秀
  2. 《深入浅出设计模式-中文版》读书笔记-工厂模式(五)
  3. 你写的 Python 代码可以更“瘦”
  4. dojo uploader使用,ps.返回值
  5. I学霸官方免费教程四十二 :Java流之字节流 输入流和输出流 InputStream和OutputStream...
  6. 测试打印机性能的软件,打印性能测试(一)
  7. html word 分页符,怎么取消分页符(word文档如何取消分页)
  8. 415 http请求 hutool_HTTP请求返回415错误码定位解决方法
  9. “鲁班”画海报、“小蜜”当客服,“菜鸟”管物流……,双十一阿里黑科技知多少...
  10. windows下编程可执行程序加载.dll动态库失败
  11. 几何学五大公理_数学几何的五大公理、五大公设是什么??
  12. 一图看尽APP各推广渠道“超级用户浓度”| 互联网行业公会
  13. 06 基于v5-resources在macos系统搭建a8服务
  14. 【C++】引用以及关联函数(详解)
  15. 舍友老六,创业五年,现在在华为上班
  16. python文本发音_python3 - 文本读音器
  17. linux aria进程,Linux安装 Aria2
  18. 全球及中国B2B支付平台行业应用前景及盈利趋势预测报告(2022-2027)
  19. 510758-19-7,5-FAM-Alkyne高选择性和灵敏的荧光生物标记物,可用于标记碱性磷酸酶 (ALP)
  20. AT88SC0104C电子产品硬件加密防盗版方法

热门文章

  1. 入坑级C语言(超级无敌噼里啪啦细)!!!
  2. 搜索+浏览合二为一的Slikk
  3. 遇到移动号码手机停机怎么办?如何自助解决上网问题?
  4. 吴佳昌//2018.7.10
  5. 手机上计算机怎么设置,手机怎么控制电脑 手机控制电脑设置方法【详解】
  6. nginx正向代理的不足
  7. Typora 的 Markdown 语法
  8. 二维码扫描自定义规则思路
  9. 计算机基础:(计算机的起源与发展)
  10. 一个简单的后台管理系统