在图片分类和目标检测中创建train/val/test

1.在一个文件夹划分train、val

本来只有一个flower_photos文件夹
经过处理后,出现了train、val文件夹
在这里插入图片描述
并且train和val文件夹如下
在这里插入图片描述
对目录下的文件名随机采样,生成列表 eval_index = random.sample(images, k=int(num*split_rate))

得到路径名后,copy


eval_index = random.sample(images, k=int(num*split_rate))

for index, image in enumerate(images):
	if image in eval_index:
	    # 将分配至验证集中的文件复制到相应目录
	    image_path = os.path.join(cla_path, image)
	    new_path = os.path.join(val_root, cla)
	    copy(image_path, new_path)
	else:
	    # 将分配至训练集中的文件复制到相应目录
	    image_path = os.path.join(cla_path, image)
	    new_path = os.path.join(train_root, cla)
	    copy(image_path, new_path)

下面的assert多次使用了,要注意用法

import os
from shutil import copy, rmtree
import random


def mk_file(file_path: str):
    if os.path.exists(file_path):
        # 如果文件夹存在,则先删除原文件夹在重新创建
        rmtree(file_path)
    os.makedirs(file_path)


def main():
    # 保证随机可复现
    random.seed(0)

    # 将数据集中10%的数据划分到验证集中
    split_rate = 0.1

    # 指向你解压后的flower_photos文件夹
    cwd = os.getcwd()
    data_root = os.path.join(cwd, "flower_data")
    origin_flower_path = os.path.join(data_root, "flower_photos")
    assert os.path.exists(origin_flower_path)
    flower_class = [cla for cla in os.listdir(origin_flower_path)
                    if os.path.isdir(os.path.join(origin_flower_path, cla))]

    # 建立保存训练集的文件夹
    train_root = os.path.join(data_root, "train")
    mk_file(train_root)
    for cla in flower_class:
        # 建立每个类别对应的文件夹
        mk_file(os.path.join(train_root, cla))

    # 建立保存验证集的文件夹
    val_root = os.path.join(data_root, "val")
    mk_file(val_root)
    for cla in flower_class:
        # 建立每个类别对应的文件夹
        mk_file(os.path.join(val_root, cla))

    for cla in flower_class:
        cla_path = os.path.join(origin_flower_path, cla)
        images = os.listdir(cla_path)
        num = len(images)
        # 随机采样验证集的索引
        eval_index = random.sample(images, k=int(num*split_rate))
        for index, image in enumerate(images):
            if image in eval_index:
                # 将分配至验证集中的文件复制到相应目录
                image_path = os.path.join(cla_path, image)
                new_path = os.path.join(val_root, cla)
                copy(image_path, new_path)
            else:
                # 将分配至训练集中的文件复制到相应目录
                image_path = os.path.join(cla_path, image)
                new_path = os.path.join(train_root, cla)
                copy(image_path, new_path)
            print("\r[{}] processing [{}/{}]".format(cla, index+1, num), end="")  # processing bar
        print()

    print("processing done!")


if __name__ == '__main__':
    main()

代码来源:大佬github

2. 目标检测中,都是划分后放在txt文件下

最终的效果图
在这里插入图片描述
一个是对所有路径名进行random.sample
一个则是对 range() 后的数字,进行sample

import os
import random

"""
训练集+验证集: 0.9 。其中训练集 0.9*0.9 = 0.81 验证集 0.9*0.1 = 0.09

测试集 :0.1 
"""
# 保证结果可以复现
random.seed(0)

trainval_percent = 0.9
train_percent = 0.9
xmlfilepath = 'Annotations'
txtsavepath = 'ImageSets\Main'
total_xml = os.listdir(xmlfilepath)

num = len(total_xml)  # num : 17125
num_list = range(num)  # num_list, 就是由range(17125)构成的多个数(应该不是list,就是索引而已), 0、1、2....17124
"""
print(rang(10)) :  >>> range(0,10)

for i in range(10):
    print(i)       >>>   0  1  2  3  4  ...  9
"""
# tr是从tv中的0.9
# tv = int(17124*0.9) = 15412
# tr = int(15412 *0.9) = 13870
tv = int(num * trainval_percent)
tr = int(tv * train_percent)
"""
random.sample:多用于截取列表中指定长度的随机数字,构成新list,但是不会改变原列表本身的排序:

list = [0,1,2,3,4]
rs = random.sample(list, 2)
print(rs)
print(list)

》》》[2, 4]    #此数组随着不同的执行,里面的元素随机,但都是两个
》》》[0, 1, 2, 3, 4]
"""
# trainval得到的是很多个数字,应该用于后面充当索引
trainval = random.sample(num_list, tv)
train = random.sample(trainval, tr)

# 下面四行,应该是用于创建新的txt文件
ftrainval = open('ImageSets/Main/trainval.txt', 'w')
ftest = open('ImageSets/Main/test.txt', 'w')
ftrain = open('ImageSets/Main/train.txt', 'w')
fval = open('ImageSets/Main/val.txt', 'w')

for i in num_list:
    # total_xml中存入了所有xml的文件名
    # 这一句话是把200700027.xml中的200700027取出来,不用.xml;
    # 因为,这是一个大的for循环,将文件名存入对应的txt中,需要每次都换行
    name = total_xml[i][:-4] + '\n'
    """
    file_name,file_extend=os.path.splitext(total_xml[i])
    分成了一个元组,由两部分组成
    >>> ('D:\\pycharm\\pytorch相关\\labelImg-master\\ori_image\\2021_000008', '.jpg')
    """
    # i只是一个索引 0~17124中的单个数字
    if i in trainval:
        ftrainval.write(name)
        if i in train:
            ftrain.write(name)
        else:
            fval.write(name)
    else:
        ftrain.write(name)

ftrainval.close()
ftrain.close()
fval.close()
ftest.close()

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
好的,你的问题是关于KNN分类模型的。我可以帮你回答。 首先,你需要导入必要的库和模块: ```python import numpy as np import cv2 import os from sklearn.neighbors import KNeighborsClassifier from sklearn.model_selection import cross_val_score ``` 接下来,你需要定义一些变量来存储图片的路径和标签: ```python train_cats_dir = "path/to/train/cats" train_dogs_dir = "path/to/train/dogs" validation_cats_dir = "path/to/validation/cats" validation_dogs_dir = "path/to/validation/dogs" test_cats_dir = "path/to/test/cats" test_dogs_dir = "path/to/test/dogs" X_train = [] y_train = [] X_validation = [] y_validation = [] X_test = [] y_test = [] ``` 然后,你需要编写一个函数来读取图片并将其转换为向量,这里使用OpenCV库: ```python def read_image(file_path): img = cv2.imread(file_path) img = cv2.resize(img, (32, 32), interpolation=cv2.INTER_CUBIC) img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img = img.flatten() return img ``` 接下来,你需要遍历图片目录并读取图片,并将其添加到训练集、验证集和测试集: ```python for file_name in os.listdir(train_cats_dir): file_path = os.path.join(train_cats_dir, file_name) X_train.append(read_image(file_path)) y_train.append(0) for file_name in os.listdir(train_dogs_dir): file_path = os.path.join(train_dogs_dir, file_name) X_train.append(read_image(file_path)) y_train.append(1) for file_name in os.listdir(validation_cats_dir): file_path = os.path.join(validation_cats_dir, file_name) X_validation.append(read_image(file_path)) y_validation.append(0) for file_name in os.listdir(validation_dogs_dir): file_path = os.path.join(validation_dogs_dir, file_name) X_validation.append(read_image(file_path)) y_validation.append(1) for file_name in os.listdir(test_cats_dir): file_path = os.path.join(test_cats_dir, file_name) X_test.append(read_image(file_path)) y_test.append(0) for file_name in os.listdir(test_dogs_dir): file_path = os.path.join(test_dogs_dir, file_name) X_test.append(read_image(file_path)) y_test.append(1) ``` 然后,你需要将训练集和验证集合并,并训练KNN分类器,通过交叉验证来选择最佳的K值: ```python X_train_validation = X_train + X_validation y_train_validation = y_train + y_validation k_scores = [] k_range = range(1, 31) for k in k_range: knn = KNeighborsClassifier(n_neighbors=k) scores = cross_val_score(knn, X_train_validation, y_train_validation, cv=10, scoring='accuracy') k_scores.append(scores.mean()) best_k = k_range[np.argmax(k_scores)] ``` 最后,你可以使用测试集评估模型的准确率: ```python knn = KNeighborsClassifier(n_neighbors=best_k) knn.fit(X_train_validation, y_train_validation) accuracy = knn.score(X_test, y_test) print(f"最佳的K值为:{best_k}") print(f"测试集准确率为:{accuracy}") ``` 这样就完了KNN分类模型的建立、交叉验证和评估。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值