深度学习 视觉处理(CNN) day_03

1. 数据获取方法

1.1 数据集分类

        - 分类数据:图像分类,一般是以目录的形式分开
        - 标注数据:目标检测和图像分割,是有标注数据的

1.2 开源数据集

        优点:免费,成本低

  1. PyTorch: Datasets — Torchvision 0.22 documentation

  2. kaggle数据集下载网址:Find Open Datasets and Machine Learning Projects | Kaggle

  3. Hugging Face数据集:https://huggingface.co/datasets

  4. 各种网站:

    Computer Vision Datasets

    https://zhuanlan.zhihu.com/p/648720525

    极市开发者平台-计算机视觉算法开发落地平台-极市科技

1.3 外包平台

        优点:效果好,成本高

        外包平台(Amazon Mechanical Turk,阿里众包,百度数据众包,京东微工等)

1.4 自己采集和标注

        优点:质量高、效率低、成本高。
        工具:labelimg、labelme
工具的使用。

pip install labelimg

1.5 通过网络爬虫获取

        爬虫工具:request,selenium ...

2. 数据本地化

        使用公开数据集时,会自动保存到本地。如果已下载,就不会重复下载。如果需要以图片的形式保存到本地以方便观察和重新处理,可以按照如下方式处理。

2.1 图片本地化

        使用一下代码保存图片到本地:

dir = os.path.dirname(__file__)
def save2local():
    trainimgsdir = os.path.join(dir, "MNIST/trainimgs")
    testimgsdir = os.path.join(dir, "MNIST/testimgs")
    if not os.path.exists(trainimgsdir):
        os.makedirs(trainimgsdir)
    if not os.path.exists(testimgsdir):
        os.makedirs(testimgsdir)

    trainset = torchvision.datasets.MNIST(
        root=datapath,
        train=True,
        download=True,
        transform=transforms.Compose([transforms.ToTensor()]),
    )
    for idx, (img, label) in enumerate(trainset):
        labdir = os.path.join(trainimgsdir, str(label))
        os.makedirs(labdir, exist_ok=True)
        pilimg = transforms.ToPILImage()(img)
        # 保存成单通道的灰度图
        pilimg = pilimg.convert("L")
        pilimg.save(os.path.join(labdir, f"{idx}.png"))

    # 加载测试集
    testset = torchvision.datasets.MNIST(
        root=datapath,
        train=False,
        download=True,
        transform=transforms.Compose([transforms.ToTensor()]),
    )
    for idx, (img, label) in enumerate(testset):
        labdir = os.path.join(testimgsdir, str(label))
        os.makedirs(labdir, exist_ok=True)
        pilimg = transforms.ToPILImage()(img)
        # 保存成单通道的灰度图
        pilimg = pilimg.convert("L")
        pilimg.save(os.path.join(labdir, f"{idx}.png"))

    print("所有图片保存成功")

2.2 加载图片数据集

        直接下载的图片文件目录也可以直接使用:

trainpath = os.path.join(dir, "MNIST/trainimgs")
trainset = torchvision.datasets.ImageFolder(root=trainpath, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=32, shuffle=True)

3. 过拟合处理

3.1 数据增强

        可以使用transform完成对图像的数据增强,防止过拟合发生:https://pytorch.org/vision/stable/transforms.html

3.1.1 数据增强的方法

        1. 随机旋转

        2. 镜像

        3. 缩放
        4. 图像模糊

        5. 裁剪


        6. 翻转
        7. 饱和度、亮度、灰度、色相


        8. 噪声、锐化、颜色反转


        9. 多样本增强
        SamplePairing操作:随机选择两张图片分别经过基础数据增强操作处理后,叠加合成一个新的样本,标签为原样本标签中的一种。

        ①、多样本线性插值:Mixup 标签更平滑

        ②、直接复制:CutMix, Cutout,直接复制粘贴样本

        ③、Mosic:四张图片合并到一起进行训练

3.1.2 数据增强的好处

        查出更多训练数据:大幅度降低数据采集和标注成本;

​        提升泛化能力:模型过拟合风险降低,提高模型泛化能力

3.2 标准化

3.3 DROP-OUT

        用于处理过拟合问题。
 

3.4 欠拟合注意事项

        如果模型在训练集和验证集上表现都不够好,考虑增加模型的层级或训练更多的周期。

4. 训练过程可视化

4.1 wandb.ai

        可在控制台看到训练进度。
        官方文档有清晰简单的代码及思路,直接使用即可:https://wandb.ai/

4.1.1 安装

pip install wandb

4.1.2 登录

wandb login

        复制平台提供的 API key粘贴回车即可(粘贴之后看不到的)。

4.1.3 初始化配置

        示例:

import random

# start a new wandb run to track this script
wandb.init(
    # set the wandb project where this run will be logged
    project="my-awesome-project",

    # track hyperparameters and run metadata
    config={
    "learning_rate": 0.02,
    "architecture": "CNN",
    "dataset": "CIFAR-100",
    "epochs": 10,
    }
)

4.1.4 写入训练日志

        示例:

# log metrics to wandb
wandb.log({"acc": correct / samp_num, "loss": total_loss / samp_num})

4.1.5 添加模型记录

        示例:

# 添加wandb的模型记录
wandb.watch(model, log="all", log_graph=True)

4.1.6 完成

        示例:

# [optional] finish the wandb run, necessary in notebooks
wandb.finish()

4.1.7 查看

        根据控制台提供的访问地址去查看训练过程数据即可。

        数据简单说明:

1. Process GPU Power Usage (W):GPU功率使用情况,以瓦特(W)为单位。
2. Process GPU Power Usage (%):GPU功率使用占GPU总功率的百分比。
3. Process GPU Memory Allocated (bytes):分配给训练过程的GPU内存量,以字节为单位。
4. Process GPU Memory Allocated (%):分配给训练过程的GPU内存占GPU总内存的百分比。
5. Process GPU Time Spent Accessing Memory (%):训练过程中访问GPU内存的时间百分比。
6. Process GPU Temp (°C):GPU温度,以摄氏度(°C)为单位。

4.2 Tensor Board

        官方文档:https://pytorch.org/docs/stable/tensorboard.html

4.2.1 准备工作

        导入tensorboard操作模块

from torch.utils.tensorboard import SummaryWriter

        指定tensorboard日志保存路径:可以指定多个实例对象

dir = os.path.dirname(__file__)
tbpath = os.path.join(dir, "tensorboard")
# 指定tensorboard日志保存路径
writer = SummaryWriter(log_dir=tbpath)

4.2.2 保存训练过程曲线

        记录训练数据

# 记录训练数据到可视化面板
writer.add_scalar("Loss/train", loss, epoch)
writer.add_scalar("Accuracy/train", acc, epoch)

        训练完后记得关闭

writer.close()

4.2.3 曲线查看

        安装:安装的是执行指令,是一个本地化的服务器

pip install tensorboard

        在训练完成后,查看训练结果,在当前目录下,打开控制台窗口:

tensorboard --logdir=runs

        控制台会提示一个访问地址,用浏览器直接访问即可。http://localhost:6006/

4.2.4 保存网络结构

        保存网络结构到tensorboard

# 保存模型结构到tensorboard
writer.add_graph(net, input_to_model=torch.randn(1, 1, 28, 28))
writer.close()

        启动tensorboard,在graphs菜单即可看到模型结构

4.2.5 模型参数可视化

# 获取模型参数并循环记录
params = net.named_parameters()
for name, param in params:
	writer.add_histogram(f"{name}_{i}", param.clone().cpu().data.numpy(), epoch)

4.2.6 记录训练数据

        tensorboard中的add_image函数用于将图像数据记录到TensorBoard,以便可视化和分析。这对于查看训练过程中生成的图像、调试和理解模型的行为非常有用,如帮助检查预处理是否生效。

#查看预处理的旋转是否生效
for i, data in enumerate(trainloader, 0):
    inputs, labels = data
    if i % 100 == 0:
        img_grid = torchvision.utils.make_grid(inputs)
        writer.add_image(f"r_m_{epoch}_{i * 100}", img_grid, epoch * len(trainloader) + i)

4.2.7 避坑指南

        尽可能使用新版本的pytorch。

pip install tensorboard

        在创建实例对象时使用默认值。

# 导入训练过程可视化工具tensorboard
from torch.utils.tensorboard import SummaryWriter
# Writer will output to ./runs/ directory by default
writer = SummaryWriter()

        启动tensorboard:

tensorboard --logdir=runs

        注意:不要在IDE(如vsCode)里面安装tensorboard插件。

5. 验证结果数据化

        我们可以把预测结果全部记录下来,以观察其效果,用于分析和评估我们的模型情况。

5.1 数据结果Excel

        导入数据分析模块pandas:

import pandas as pd

        把推理结果softmax化,并放到全局的列表里面:

#定义全局的 pd_data :10分类,加了分类id 和  分类名称, 12个
pd_data = np.empty((0, 12))

#在训练的过程中把训练结果整理进来
out_softmax = torch.softmax(out, dim=1).cpu().detach().numpy()
target_y = y.cpu().detach().numpy()
#根据目标值找到分类名
target_name = np.array([vaild_dataset.classes[i] for i in target_y])
# 把真实所属分类追加到数据中
out_softmax = np.concatenate(
    (out_softmax, target_y.reshape(-1, 1), target_name.reshape(-1, 1)), axis=1
)
#数据追加
pd_data = np.concatenate((pd_data, out_softmax), axis=0)

        保存数据到CSV:

# 数据有了,找到列名:和前面追加的目标值及类名要呼应上
columnsn = np.concatenate(
    (vaild_dataset.classes, np.array(["target", "真实值"])), axis=0
)
pd_data_df = pd.DataFrame(pd_data, columns=columnsn)

# 把数据保存到Excel:CSV
csvpath = os.path.join(dir, "vaild")
if not os.path.exists(csvpath):
    os.makedirs(csvpath)

pd_data_df.to_csv(os.path.join(csvpath, "vaild.csv"), encoding="GBK")

5.2 模型指标矩阵化

5.2.1 混淆矩阵

        混淆矩阵是一种特定的表格布局,用于可视化监督学习算法的性能,特别是分类算法。在这个矩阵中,每一行代表实际类别,每一列代表预测类别。矩阵的每个单元格则包含了在该实际类别和预测类别下的样本数量。通过混淆矩阵,我们不仅可以计算出诸如准确度、精确度和召回率等评估指标,还可以更全面地了解模型在不同类别上的性能。

        混淆矩阵的四个基本组成部分是:

  1. True Positives(TP):当模型预测为正类,并且该预测是正确的,我们称之为真正(True Positive);

  2. True Negatives(TN):当模型预测为负类,并且该预测是正确的,我们称之为真负(True Negative);

  3. False Positives(FP):当模型预测为正类,但该预测是错误的,我们称之为假正(False Positive);

  4. False Negatives(FN):当模型预测为负类,但该预测是错误的,我们称之为假负(False Negative)

5.2.2 常见指标

        参考下图

5.2.3 理解对角线

        对角线上的元素越大越好

5.2.4 模型指标计算及可视化

        1. 分类报告:

csvpath = os.path.join(dir, "vaild")
# 读取CSV数据
csvdata = pd.read_csv(
    os.path.join(csvpath, "vaild.csv"), encoding="GBK", index_col=0
)
# 拿到真实标签
true_label = csvdata["target"].values
print(true_label, type(true_label), len(true_label))

# 获取预测标签
predict_label = csvdata.iloc[:, :-2].values
print(predict_label, predict_label.shape)
# 预测分类及分数的提取
predict_label_ind = np.argmax(predict_label, axis=1)
predict_label_score = np.max(predict_label, axis=1)
print(predict_label_ind, predict_label_score)
# 根据预测值和真实值生成分类报告
report = classification_report(y_true=true_label, y_pred=predict_label_ind)
print(report)

        效果:

        2. 准确度(Accuracy):

# 获取准确度
acc = accuracy_score(y_true=true_label, y_pred=predict_label_ind)
print("准确度:", acc)

        3. 精确度(Precision):

# 获取精确度Precision
precision = precision_score(y_true=true_label, y_pred=predict_label_ind, average="macro")
print("精确度:", precision)

        4. 召回率(Recall):

#召回率(Recall)
recall = recall_score(y_true=true_label, y_pred=predict_label_ind, average="macro")
print("召回率:", recall)

        5. F1分数(F1-Score):

#### F1分数(F1-Score)
f1 = f1_score(y_true=true_label, y_pred=predict_label_ind, average="macro")
print("F1分数:", f1)

        6. 混淆矩阵及可视化:

import os
from sklearn.metrics import *
import pandas as pd
from matplotlib import pyplot as plt

# plt中文乱码问题
plt.rcParams["font.sans-serif"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False

# 路径兼容处理
current_path = os.path.dirname(__file__)
excel_path = os.path.relpath(
    os.path.join(current_path, r"./metrics", "validation_metrics.xlsx")
)


def report():
    # 读取Excel数据

    excel_data = pd.read_excel(excel_path)
    label = excel_data["label"].values
    predict = excel_data["predict"].values
    # 整体报表
    labels = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    matrix = confusion_matrix(label, predict)
    print(matrix)
    # 下面的代码就是简单的plt绘制过程
    plt.matshow(matrix, cmap=plt.cm.Greens)
    # 显示颜色条
    plt.colorbar()
    # 显示具体的数字的过程
    for i in range(len(matrix)):
        for j in range(len(matrix)):
            plt.annotate(
                matrix[i, j],
                xy=(j, i),
                horizontalalignment="center",
                verticalalignment="center",
            )
    # 美化的东西
    plt.xlabel("Pred labels")
    plt.ylabel("True labels")
    plt.xticks(range(len(labels)), labels, rotation=45)
    plt.yticks(range(len(labels)), labels)
    plt.title("训练结果混淆矩阵视图")

    plt.show()


if __name__ == "__main__":
    report()

        效果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值