飞桨机器学习数据处理

228 阅读7分钟

「这是我参与2022首次更文挑战的第26天,活动详情查看:2022首次更文挑战」。

0 介绍

  通常,我们的机器学习任务都是属于监督学习一类,监督模型的最终学习结果优劣主要取决于两个因素:数据质量和数据中蕴含的有价值信息数量,所以对训练数据做定义和清洗,是进行模型训练和提高模型评估指标的必要条件。

  推荐的数据集中主要包含三大领域:计算机视觉(CV)、自然语言处理(NLP)和推荐系统(RS),但从狭义视角来区分,你所选择的数据集可能分别是图片、文本或表格格式。本次作业的任务即为数据的定义、清洗与处理,以方便后续直接进行训练的编码或调用相关套件的接口。

1 数据准备指引

  在完成基本的数据清洗工作之后,我们通常会选择飞桨工具与套件进行端到端的开发,也可能会使用飞桨基础接口进行开发。以下内容可作为你所使用的数据集如何进行整理和准备的参考。

1.1 开发套件/工具

  (1)PaddleX - 数据格式说明

  (2)PaddleClas - 数据准备

  (3)PaddleSeg - 数据格式说明

  (4)PaddleDetection - 数据准备

1.2 飞桨基础接口

  关于使用飞桨基础接口定义数据读取器(API文档底部有相关的调用样例,可供大家递归参考)。

  (1)数据集定义与加载

  (2)开发流程 - 数据处理

  (3)paddle.io.Dataset

  (4)paddle.io.DataLoader

  (5)飞桨文档搜索*

  (6)开发者案例 - Paddle2.0 数据加载与处理*

  (7)开发者案例 - 反欺诈竞赛数据处理(表格数据)*

2 作业书写区

  评分标准:

  (1)数据集清洗与介绍(解压数据集、tree命令查看目录结构、样本的可视化展示等),30分。

  (2)图像数据集:计算该数据集的均值和方差;文本数据集:使用jieba分词并统计词频,30分。

  (3)数据集类的定义(继承paddle.io.Dataset的类),30分。

  (4)数据集类的测试(调用定义好的数据集类,参考章节[1.2]的文档示例),10分。


  提示:

  (1)若代码块无效输出很长,例如pip安装了某个包,对此可以点击单元格右上角的“清空输出”保持整洁。

  (2)以下代码样例中,若和你的作业内容无关,请参考后删除该代码块,只留下自己的作业部分。

  (3)提交作业时,请记得在左侧栏中选择“版本->生成新版本->自拟版本名称和文件”生成版本,然后在作业的提交页面中选择指定的版本。

  (4)点击该链接可查看本环境基本用法:ai.baidu.com/docs#/AIStu…

2.1 数据集的准备与介绍(30分)

# 样例:解压你所挂载的数据集在同级目录下
# !unzip -oq data/xxx/xxx.zip -d data/xxx

# 查看数据集的目录结构
# !tree data/xxx/xxx -d
! tree samples -d
samples
├── images
├── labels
└── nlp

3 directories
# 数据集介绍可参考该内容(数据来源、归类领域、数据类型、保存格式、样本数量、类别等具体信息):
# https://aistudio.baidu.com/aistudio/competition/detail/63/0/task-definition
# 样例:语义分割数据集抽样可视化
import cv2
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
%matplotlib inline

image_path_list = ['samples/images/H0002.jpg', 'samples/images/H0005.jpg']
label_path_list = [path.replace('images', 'labels').replace('jpg', 'png')
                   for path in image_path_list]

plt.figure(figsize=(8, 8))
for i in range(len(image_path_list)):
    plt.subplot(len(image_path_list), 2, i*2+1)
    plt.title(image_path_list[i])
    plt.imshow(cv2.imread(image_path_list[i])[:, :, ::-1])

    plt.subplot(len(image_path_list), 2, i*2+2)
    plt.title(label_path_list[i])
    plt.imshow(cv2.imread(label_path_list[i], cv2.IMREAD_GRAYSCALE))
plt.tight_layout()
plt.show()

output_9_0.png

2.2 图像/文本数据的统计分析(30分)

# 计算图像数据整体均值和方差
import glob
import numpy as np


def get_mean_std(image_path_list):
    print('Total images:', len(image_path_list))
    max_val, min_val = np.zeros(3), np.ones(3) * 255
    mean, std = np.zeros(3), np.zeros(3)
    for image_path in image_path_list:
        image = cv2.imread(image_path)
        for c in range(3):
            mean[c] += image[:, :, c].mean()
            std[c] += image[:, :, c].std()
            max_val[c] = max(max_val[c], image[:, :, c].max())
            min_val[c] = min(min_val[c], image[:, :, c].min())

    mean /= len(image_path_list)
    std /= len(image_path_list)

    mean /= max_val - min_val
    std /= max_val - min_val

    return mean, std


mean, std = get_mean_std(glob.glob('samples/images/*.jpg'))
print('mean:', mean)
print('std:', std)
Total images: 2
mean: [0.13558718 0.16853207 0.24522167]
std: [0.09351342 0.10932762 0.17109555]
# jieba进行文本数据的分词
import jieba

with open('samples/nlp/words.txt', mode='r', encoding='utf-8') as f:
    text = f.read()
    seg_list = jieba.cut(text, cut_all=True)
    print("[Full Mode]" + "/ ".join(seg_list))     # 全模式

    seg_list = jieba.cut(text, cut_all=False)
    print("[Default Mode]" + "/ ".join(seg_list))  # 精确模式

    seg_list = jieba.cut_for_search(text)          # 搜索引擎模式
    print("[Search Mode]" + "/ ".join(seg_list))
Building prefix dict from the default dictionary ...
Dumping model to file cache /tmp/jieba.cache
Loading model cost 0.807 seconds.
Prefix dict has been built successfully.


[Full Mode]自然/ 自然语言/ 语言/ 处理/ (/ Natural/ /  / / Language/ /  / / Processing/ ,/ 简称/ NLP/ )/ 被誉为/ 誉为/ 人工/ 人工智能/ 智能/ 皇冠/ 上/ 的/ 明珠/ ,/ 是/ 计算/ 计算机/ 计算机科学/ 算机/ 科学/ 和/ 人工/ 人工智能/ 智能/ 领域/ 的/ 一个/ 重要/ 方向/ 。/ 它/ 主要/ 研究/ 人/ 与/ 计算/ 计算机/ 算机/ 之间/ ,/ 使用/ 自然/ 自然语言/ 语言/ 进行/ 有效/ 通信/ 的/ 各种/ 理论/ 和/ 方法/ 。/ 简单/ 来说/ ,/ 计算/ 计算机/ 算机/ 以/ 用户/ 的/ 自然/ 自然语言/ 语言/ 数据/ 作为/ 输入/ ,/ 在/ 其内/ 内部/ 通过/ 定义/ 的/ 算法/ 进行/ 加工/ 、/ 计算/ 等/ 系列/ 操作/ 后/ (/ 用以/ 模拟/ 拟人/ 人类/ 对/ 自然/ 自然语言/ 语言/ 的/ 理解/ ),/ 再/ 返回/ 回用/ 用户/ 所/ 期望/ 的/ 结果/ 。
[Default Mode]自然语言/ 处理/ (/ Natural/  / Language/  / Processing/ ,/ 简称/ NLP/ )/ 被誉为/ 人工智能/ 皇冠/ 上/ 的/ 明珠/ ,/ 是/ 计算机科学/ 和/ 人工智能/ 领域/ 的/ 一个/ 重要/ 方向/ 。/ 它/ 主要/ 研究/ 人/ 与/ 计算机/ 之间/ ,/ 使用/ 自然语言/ 进行/ 有效/ 通信/ 的/ 各种/ 理论/ 和/ 方法/ 。/ 简单/ 来说/ ,/ 计算机/ 以/ 用户/ 的/ 自然语言/ 数据/ 作为/ 输入/ ,/ 在/ 其/ 内部/ 通过/ 定义/ 的/ 算法/ 进行/ 加工/ 、/ 计算/ 等/ 系列/ 操作/ 后/ (/ 用以/ 模拟/ 人类/ 对/ 自然语言/ 的/ 理解/ )/ ,/ 再/ 返回/ 用户/ 所/ 期望/ 的/ 结果/ 。
[Search Mode]自然/ 语言/ 自然语言/ 处理/ (/ Natural/  / Language/  / Processing/ ,/ 简称/ NLP/ )/ 誉为/ 被誉为/ 人工/ 智能/ 人工智能/ 皇冠/ 上/ 的/ 明珠/ ,/ 是/ 计算/ 算机/ 科学/ 计算机/ 计算机科学/ 和/ 人工/ 智能/ 人工智能/ 领域/ 的/ 一个/ 重要/ 方向/ 。/ 它/ 主要/ 研究/ 人/ 与/ 计算/ 算机/ 计算机/ 之间/ ,/ 使用/ 自然/ 语言/ 自然语言/ 进行/ 有效/ 通信/ 的/ 各种/ 理论/ 和/ 方法/ 。/ 简单/ 来说/ ,/ 计算/ 算机/ 计算机/ 以/ 用户/ 的/ 自然/ 语言/ 自然语言/ 数据/ 作为/ 输入/ ,/ 在/ 其/ 内部/ 通过/ 定义/ 的/ 算法/ 进行/ 加工/ 、/ 计算/ 等/ 系列/ 操作/ 后/ (/ 用以/ 模拟/ 人类/ 对/ 自然/ 语言/ 自然语言/ 的/ 理解/ )/ ,/ 再/ 返回/ 用户/ 所/ 期望/ 的/ 结果/ 。
# jieba词频统计
from jieba import analyse

extract_tags = analyse.extract_tags(text, withWeight=True)
for i, j in extract_tags:
    print(i, j)
自然语言 0.7589048544872727
人工智能 0.3439282325632727
用户 0.248084948088
计算机 0.24744670657745454
Natural 0.21735940914363636
Language 0.21735940914363636
Processing 0.21735940914363636
NLP 0.21735940914363636
计算机科学 0.1774098713741818
皇冠 0.1603504233998182
算法 0.15802166362054546
明珠 0.15355193702945455
模拟 0.13865301146781817
被誉为 0.13848260892545455
进行 0.135531810728
期望 0.13548705923327273
定义 0.13079664209763636
输入 0.12836602041254544
用以 0.1283465850090909
返回 0.12081975232218183
!pip install wordcloud
# 词云可视化
from wordcloud import WordCloud

result = {}
for word in extract_tags:
    result[word[0]] = word[1]

wordcloud = WordCloud(
    background_color="white",
    max_font_size=50,
    font_path='samples/nlp/simkai.ttf')
wordcloud.generate_from_frequencies(result)

plt.figure()
plt.axis('off')
plt.imshow(wordcloud)
plt.show()

output_15_0.png

2.3 数据集类的定义(30分)

# 可以参考章节[1.2]推荐链接中的内容
import paddle
import numpy as np
import paddle.vision.transforms as T


class MyImageNetDataset(paddle.io.Dataset):
    def __init__(self,
                 num_samples,
                 num_classes):
        super(MyImageNetDataset, self).__init__()

        self.num_samples = num_samples
        self.num_classes = num_classes
        self.transform = T.Compose([
            T.Resize(size=(224, 224)),
            T.ToTensor(),
            T.Normalize(mean=127.5, std=127.5)])

    def __getitem__(self, index):
        image = np.random.randint(low=0, high=256, size=(512, 512, 3))
        label = np.random.randint(low=0, high=self.num_classes, size=(1,))

        image = image.astype('float32')
        label = label.astype('int64')

        image = self.transform(image)

        return image, label

    def __len__(self):
        return self.num_samples

2.4 数据集类的测试(10分)

train_dataset = MyImageNetDataset(num_samples=1200, num_classes=1000)
print(len(train_dataset))

image, label = train_dataset[0]
print(image.shape, label.shape)


for image, label in train_dataset:
    print(image.shape, label.shape)
    break
1200
[3, 224, 224] (1,)
[3, 224, 224] (1,)
train_dataloader = paddle.io.DataLoader(
    train_dataset,
    batch_size=128,
    shuffle=True,
    drop_last=False)

for step, data in enumerate(train_dataloader):
    image, label = data
    print(step, image.shape, label.shape)
0 [128, 3, 224, 224] [128, 1]
1 [128, 3, 224, 224] [128, 1]
2 [128, 3, 224, 224] [128, 1]
3 [128, 3, 224, 224] [128, 1]
4 [128, 3, 224, 224] [128, 1]
5 [128, 3, 224, 224] [128, 1]
6 [128, 3, 224, 224] [128, 1]
7 [128, 3, 224, 224] [128, 1]
8 [128, 3, 224, 224] [128, 1]
9 [48, 3, 224, 224] [48, 1]