diff --git "a/\345\233\276\345\203\217\350\257\206\345\210\253/\350\212\261\346\234\265\350\257\206\345\210\253/DenseNet-test.py" "b/\345\233\276\345\203\217\350\257\206\345\210\253/\350\212\261\346\234\265\350\257\206\345\210\253/DenseNet-test.py" index 20e51e250b41ddac51959502fa05ff2d54acb804..5d6e41fb6bc6c4dc0c5bce5374994465a713e98f 100644 --- "a/\345\233\276\345\203\217\350\257\206\345\210\253/\350\212\261\346\234\265\350\257\206\345\210\253/DenseNet-test.py" +++ "b/\345\233\276\345\203\217\350\257\206\345\210\253/\350\212\261\346\234\265\350\257\206\345\210\253/DenseNet-test.py" @@ -56,8 +56,9 @@ def predict_directory(file_path): # 传入文件路径进行预测 preds,prob=predict_single_image(file_dir) - # 取出图片的真实标签(_前面的部分为标签值) - label_true=file.split('_')[0].title() + # 取出图片的真实标签(这里直接将文件夹名称作为真实标签值了) + # label_true=file.split('_')[0].title() + label_true = file_dir.split('\\')[0].split('/')[-1] # 保存真实值和预测值结果 classes_true.append(label_true) classes_pred.append(preds) diff --git "a/\345\233\276\345\203\217\350\257\206\345\210\253/\350\212\261\346\234\265\350\257\206\345\210\253/ResNet-test.py" "b/\345\233\276\345\203\217\350\257\206\345\210\253/\350\212\261\346\234\265\350\257\206\345\210\253/ResNet-test.py" new file mode 100644 index 0000000000000000000000000000000000000000..a7bb652cc0265fb5486a7637d8fc23aca4493d31 --- /dev/null +++ "b/\345\233\276\345\203\217\350\257\206\345\210\253/\350\212\261\346\234\265\350\257\206\345\210\253/ResNet-test.py" @@ -0,0 +1,76 @@ +import tensorflow as tf +import numpy as np +import os +import matplotlib.pyplot as plt +from tensorflow.keras import layers +from tensorflow.keras.models import load_model + +# from PIL import Image + +model = load_model('model/ResNet50(迁移学习)-花朵分类(17).h5') +model.summary() + +# 类别总数 +dataset_dir = 'data/train' +classes = [] +for filename in os.listdir(dataset_dir): + classes.append(filename) +# print('classes:',classes) + +# 预测单张图片 +def predict_single_image(img_path): + img = tf.io.read_file(img_path) + # 将jpg格式转换为tensor + img = tf.image.decode_jpeg(img, channels=3) + # 数据归一化 + img = tf.image.convert_image_dtype(img, dtype=tf.float32) + # resize + img = tf.image.resize(img, size=[224, 224]) + # 扩充一个维度 + img = np.expand_dims(img, axis=0) + + # 预测:结果是二维的 + test_result = model.predict(img) + # print('test_result:', test_result) + # 转化为一维 + result = np.squeeze(test_result) + # print('转化后result:', result) + + # 找到概率值最大的索引 + predict_class = np.argmax(result) + # print('概率值最大的索引:', predict_class) + + # 返回类别和所属类别的概率 + return classes[int(predict_class)], result[predict_class] + +# 对整个文件夹的图片进行预测 +def predict_directory(file_path): + classes_pred=[] + classes_true=[] + probs=[] + for file in os.listdir(file_path): + # 测试图片完整路径 + file_dir=os.path.join(file_path,file) + # 打印文件路径 + print(file_dir) + # 传入文件路径进行预测 + preds,prob=predict_single_image(file_dir) + + # 取出图片的真实标签(_前面的部分为标签值) + # label_true=file.split('_')[0].title() + label_true=file_dir.split('\\')[0].split('/')[-1] + # 保存真实值和预测值结果 + classes_true.append(label_true) + classes_pred.append(preds) + probs.append(prob) + return classes_pred,classes_true,probs + +# img_path = 'Gemstones/train/Almandine/almandine_0.jpg' +# classes, prob = predict_single_image(img_path) +# print(classes, prob) + +file_path='data/test/flower0' +classes_pred,classes_true,probs=predict_directory(file_path) +print(classes_pred) +print(classes_true) +print(probs) \ No newline at end of file diff --git "a/\345\233\276\345\203\217\350\257\206\345\210\253/\350\212\261\346\234\265\350\257\206\345\210\253/ResNet50(\350\277\201\347\247\273\345\255\246\344\271\240).py" "b/\345\233\276\345\203\217\350\257\206\345\210\253/\350\212\261\346\234\265\350\257\206\345\210\253/ResNet50(\350\277\201\347\247\273\345\255\246\344\271\240).py" new file mode 100644 index 0000000000000000000000000000000000000000..1278e1c465e1307ecb818245252782b269498e3b --- /dev/null +++ "b/\345\233\276\345\203\217\350\257\206\345\210\253/\350\212\261\346\234\265\350\257\206\345\210\253/ResNet50(\350\277\201\347\247\273\345\255\246\344\271\240).py" @@ -0,0 +1,129 @@ +import tensorflow as tf +import numpy as np +import matplotlib.pyplot as plt +from tensorflow.keras.preprocessing.image import ImageDataGenerator +from tensorflow.keras import layers +from tensorflow.keras.models import Model +from tensorflow.keras.applications import ResNet50 +from tensorflow.keras.callbacks import LearningRateScheduler + +model=ResNet50(include_top=False,input_shape=(224,224,3)) +model.summary() + +# 类别数 +num_classes=17 +# 批次大小 +batch_size=32 +# 周期数 +epochs=100 +# 图片大小 +image_size=224 + +model=tf.keras.Sequential([ + model, + layers.GlobalAveragePooling2D(), + layers.Dense(num_classes,activation='softmax') +]) +model.summary() + +# 训练集数据进行数据增强 +train_datagen = ImageDataGenerator( + rotation_range=20, # 随机旋转度数 + width_shift_range=0.1, # 随机水平平移 + height_shift_range=0.1, # 随机竖直平移 + rescale=1 / 255, # 数据归一化 + shear_range=10, # 随机错切变换 + zoom_range=0.1, # 随机放大 + horizontal_flip=True, # 水平翻转 + brightness_range=(0.7, 1.3), # 亮度变化 + fill_mode='nearest', # 填充方式 +) +# 测试集数据只需要归一化就可以 +test_datagen = ImageDataGenerator( + rescale=1 / 255, # 数据归一化 +) + +# 训练集数据生成器,可以在训练时自动产生数据进行训练 +# 从'data/train'获得训练集数据 +# 获得数据后会把图片resize为image_size×image_size的大小 +# generator每次会产生batch_size个数据 +train_generator = train_datagen.flow_from_directory( + 'data/花朵分类(17)/train', + target_size=(image_size, image_size), # 调整图像尺寸 + batch_size=batch_size, +) + +# 测试集数据生成器 +test_generator = test_datagen.flow_from_directory( + 'data/花朵分类(17)/test', + target_size=(image_size, image_size), + batch_size=batch_size, +) +# 字典的键为17个文件夹的名字,值为对应的分类编号 +print(train_generator.class_indices) + + +# 学习率调节函数,逐渐减小学习率 +def adjust_learning_rate(epoch): + # 前40周期 + if epoch<=40: + lr = 1e-4 + # 前40到80周期 + elif 40 < epoch <= 80: + lr = 1e-5 + # 80到100周期 + else: + lr = 1e-6 + return lr + +# 定义优化器 +adam = Adam(lr=1e-4) + +# 读取模型 +checkpoint_save_path = "./checkpoint/ResNet50-花朵分类(17).ckpt" +if os.path.exists(checkpoint_save_path + '.index'): + print('-------------load the model-----------------') + model.load_weights(checkpoint_save_path) +# 保存模型 +cp_callback = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_save_path, + save_weights_only=True, + save_best_only=True) + +# 定义学习率衰减策略 +callbacks = [] +callbacks.append(LearningRateScheduler(adjust_learning_rate)) +callbacks.append(cp_callback) + +# 定义优化器,loss function,训练过程中计算准确率 +model.compile(optimizer=adam,loss='categorical_crossentropy',metrics=['accuracy']) +# 训练 +history = model.fit(x=train_generator,epochs=epochs,validation_data=test_generator,callbacks=callbacks) + +# 保存模型 +# model.save('model/ResNet50(迁移学习)-花朵分类(17).h5') + +# 画出训练集准确率曲线图 +plt.plot(np.arange(epochs),history.history['accuracy'],c='b',label='train_accuracy') +# 画出验证集准确率曲线图 +plt.plot(np.arange(epochs),history.history['val_accuracy'],c='y',label='val_accuracy') +# 图例 +plt.legend() +# x坐标描述 +plt.xlabel('epochs') +# y坐标描述 +plt.ylabel('accuracy') +# 显示图像 +plt.show() + +# 画出训练集loss曲线图 +plt.plot(np.arange(epochs),history.history['loss'],c='b',label='train_loss') +# 画出验证集loss曲线图 +plt.plot(np.arange(epochs),history.history['val_loss'],c='y',label='val_loss') +# 图例 +plt.legend() +# x坐标描述 +plt.xlabel('epochs') +# y坐标描述 +plt.ylabel('loss') +# 显示图像 +plt.show() \ No newline at end of file