阿里云天池龙珠计划深度学习训练营打卡-DCGAN生成手写数字图片实战

本笔记为阿里云天池龙珠计划深度学习训练营的学习内容,链接为:

https://tianchi.aliyun.com/specials/promotion/aicampdl

目录

  1. 原理简介

  2. 运行环境与数据集准备
    1. 加载和准备数据集

  3. 创建模型
    1. 生成器
    2. 判别器
    3. 生成器与判别器初始化

  4. 定义损失函数和优化器

  5. 训练阶段

  6. 可视化
    1. 生成器与判别器损失函数曲线
    2. 训练过程展示
    3. 真(训练集中的)——假(网络生成的)图片对比

本任务将在 MNIST 数据集上完成一个 DCGAN 的项目。

下方动画展示了当训练了 50 个epoch (全部数据集迭代50次) 时生成器所生成的一系列图片。图片从随机噪声开始,随着时间的推移越来越像手写数字。

dcgan

接下来我们进⾏实践,选择 PyTorch 框架,下⾯详解具体的⼯程代码,主要包括:

  • 运行环境与数据集准备
  • 创建模型
  • 定义损失函数与优化器
  • 训练模型
  • 可视化

运行环境与数据集准备

  1. 在加载该 NoteBook 文件时,会自动加载数据集至 ./download/DCGAN_PyTorch_MNIST_DATASET 文件夹下。若没有自动加载数据集,则需要手动加载,手动加载方式如下:

点击本页面左方 天池 按钮(需要在 CPU 环境下),点击 DCGAN_PyTorch_MNIST_DATASET 旁边的下载按钮,就会自动加载数据集了!

Image

运行下面代码,对数据集进行解压

# 这个命令在GPU下无法执行,没有关系,后面加载数据时会从网络下载

!unzip DCGAN_PyTorch_MNIST_DATASET.zip -d ./DCGAN_PyTorch_MNIST_DATASET
  1. 同时该实战需要在 GPU 环境下才能运行,GPU 环境的切换方法如下:

点击本页面右侧 < 键,会调出以下页面,然后点击切换即可切换至 GPU,切换时间会稍微长一点,请耐心等候!

Image

import time        # 导入time模块,记录系统时间
import torch        # 导入torch库
import torch.nn as nn        # 导入nn模块,构建神经网络
from torch.utils.data import DataLoader        # 通过DataLoader对数据集进行分批加载
# datasets下载和管理公开数据集,transforms对数据集进行预处理和格式转换
from torchvision import utils, datasets, transforms        
import matplotlib.pyplot as plt        # 画图库
import matplotlib.animation as animation        # 绘制动态图
from IPython.display import HTML  # 在HTML中展示动画

1. 加载和准备数据集

本项目使用 MNIST 数据集来训练生成器和判别器。生成器将生成类似于 MNIST 数据集的手写数字。 首先加载数据集,并设置初始参数。

在加载该 NoteBook 文件时,会自动加载数据集至 DCGAN_PyTorch_MNIST_DATASET 文件夹下

dataroot = "./DCGAN_PyTorch_MNIST_DATASET/"  # 数据集所在的路径
workers = 10  # 数据加载时的进程数
batch_size = 100  # 生成器输入的大小,既批量数据集大小
image_size = 64  # 训练图像的大小
nc = 1  # 训练图像的通道数(灰色图),彩色图像的话就是 3
nz = 100  # 输入是100 维的随机噪声z,看作是100个channel,每个特征图宽高是 1*1
ngf = 64  # 生成器中特征图的大小
ndf = 64  # 判别器中特征图的大小
num_epochs = 10  # 训练的轮次
lr = 0.0002  # 学习率大小
beta1 = 0.5  # Adam优化器的参数
ngpu = 1  # 可用 GPU  的个数,0 代表使用 CPU
# 训练集加载并进行归一化等操作
train_data = datasets.MNIST(
    root=dataroot,
    train=True,
    transform=transforms.Compose([
        transforms.Resize(image_size),  # 将图像调整为64*64
        transforms.ToTensor(),  # 将图像数据格式化为张量,形状为C*W*H
        transforms.Normalize((0.5, ), (0.5, ))  # 按通道归一化数据,mean=0.5,std=0.5
    ]),
    download=True  # 从互联网下载,如果已经下载的话,就直接使用
)
# 测试集加载并进行归一化等操作
test_data = datasets.MNIST(root=dataroot,
                           train=False,
                           transform=transforms.Compose([
                               transforms.Resize(image_size),
                               transforms.ToTensor(),
                               transforms.Normalize((0.5, ), (0.5, ))
                           ]))
# 把 MNIST 的训练集和测试集都用来做训练
# train_data和test_data为MNIST数据集,dataset为ConcatDataset类型,既不是Iterator,也不可Iterable
dataset = train_data + test_data
print(f'Total Size of Dataset: {len(dataset)}')
# 数据加载器,训练过程中不断产生数据
dataloader = DataLoader(dataset=dataset,
                        batch_size=batch_size,
                        shuffle=True,
                        num_workers=workers)
# 看是否存在可用的 GPU
device = torch.device('cuda:0' if (
    torch.cuda.is_available() and ngpu > 0) else 'cpu')
# 权重初始化函数
def weights_init(m):
    classname = m.__class__.__name__
    if classname.find('Conv') != -1:
        nn.init.normal_(m.weight.data, 0.0, 0.02)  # 使用正态化分布随机数据初始化卷积层权重
    elif classname.find('BatchNorm') != -1:
        nn.init.normal_(m.weight.data, 1.0, 0.02)
        nn.init.constant_(m.bias.data, 0)  # 使用0值初始化偏置
Total Size of Dataset: 70000

以下的代码用做读取部分数据集进行展示,看看我们原始输入的数据是怎么样的。

inputs = next(iter(dataloader))[0]  # 使用iter方法把dataloader转变为Iterator,并使用next()读入100个图像
plt.figure(figsize=(10, 10))  # 定义画布大小为10*10英寸
plt.title("Training Images")  # 定义标题
plt.axis('off')  # 去掉坐标轴

   # inputs里的数据取值范围从[-1,1]调整为[0,1],并合成一个网格图像,每行显示10个图像

inputs = utils.make_grid(inputs[:100] * 0.5 + 0.5, nrow=10) 
plt.imshow(inputs.permute(1, 2, 0))  # 将inputs转换维度后画图

[3]:

<matplotlib.image.AxesImage at 0x7f9ed8c73e10>

创建模型

1. 生成器

生成器使用 torch.nn.ConvTranspose2d (上采样)层来从种子(随机噪声)中产生图片。以一个使用该种子作为输入的 Dense 层开始,然后多次上采样直到达到所期望的 64x64x1 的图片尺寸。注意除了输出层使用 tanh 之外,其他每层均使用 torch.nn.functional.relu 作为激活函数。

下面定义一个生成器的类,读者可以依照生成器网络配置理解以下代码

class Generator(nn.Module):
    def __init__(self, ngpu):
        super(Generator, self).__init__()
        self.ngpu = ngpu

                  # 创建一个Sequential容器,存放各网络层

        self.main = nn.Sequential(
            # input is Z, going into a convolution
            nn.ConvTranspose2d(in_channels=nz,  # 输入特征数64
                               out_channels=ngf * 8,  # 输出特征数64*8
                               kernel_size=4,  # 卷积核尺寸4*4
                               stride=1,  # 步幅1
                               padding=0,  # 不填充
                               bias=False),  # 不添加偏置
            nn.BatchNorm2d(ngf * 8),  # 批量归一化
            nn.ReLU(True),  # ReLU激活
            # 当前特征图大小  (ngf*8) x 4 x 4,转置卷积过程中产生的临时图片尺寸为:1*1,卷积核为:size:3*3,stride:1,padding:4-0-1=3
            nn.ConvTranspose2d(ngf * 8, ngf * 4, 4, 2, 1, bias=False),
            nn.BatchNorm2d(ngf * 4),
            nn.ReLU(True),
            # 当前特征图大小 (ngf*4) x 8 x 8
            nn.ConvTranspose2d(ngf * 4, ngf * 2, 4, 2, 1, bias=False),
            nn.BatchNorm2d(ngf * 2),
            nn.ReLU(True),
            # 当前特征图大小 (ngf*2) x 16 x 16
            nn.ConvTranspose2d(ngf * 2, ngf, 4, 2, 1, bias=False),
            nn.BatchNorm2d(ngf),
            nn.ReLU(True),
            # 当前特征图大小 (ngf) x 32 x 32
            nn.ConvTranspose2d(ngf, nc, 4, 2, 1, bias=False),
            nn.Tanh()  # 输出层使用Tanh激活,将值范围从[0,1]调整为[-1,1]
            # 当前特征图大小 (nc) x 64 x 64,与MNIST数据集中图像的尺寸一致,取值范围也一致
        )
    def forward(self, input):
        return self.main(input)

2. 判别器

判别器是一个基于 CNN 的图片分类器。

class Discriminator(nn.Module):
    def __init__(self, ngpu):
        super(Discriminator, self).__init__()  # 继承父类的__init__方法
        self.ngpu = ngpu
        self.main = nn.Sequential(
            # 输入 (nc) x 64 x 64
            nn.Conv2d(nc, ndf, 4, 2, 1, bias=False),
            nn.LeakyReLU(0.2, inplace=True),  # 此处的激活函数与生成器中不同,是带有负斜率的修正线性单元
            # 当前特征图大小 (ndf) x 32 x 32
            nn.Conv2d(ndf, ndf * 2, 4, 2, 1, bias=False),
            nn.BatchNorm2d(ndf * 2),
            nn.LeakyReLU(0.2, inplace=True),
            # 当前特征图大小 (ndf*2) x 16 x 16
            nn.Conv2d(ndf * 2, ndf * 4, 4, 2, 1, bias=False),
            nn.BatchNorm2d(ndf * 4),
            nn.LeakyReLU(0.2, inplace=True),
            # 当前特征图大小 (ndf*4) x 8 x 8
            nn.Conv2d(ndf * 4, ndf * 8, 4, 2, 1, bias=False),
            nn.BatchNorm2d(ndf * 8),
            nn.LeakyReLU(0.2, inplace=True),
            # 当前特征图大小 (ndf*8) x 4 x 4
            nn.Conv2d(ndf * 8, 1, 4, 1, 0, bias=False),
            # 当前特征图大小 (1) x 1 x 1
            nn.Sigmoid())  # 输出层使用Sigmoid激活

    def forward(self, input):
        return self.main(input)

3. 生成器与判别器初始化

# 创建一个生成器对象,并拷贝至GPU
netG = Generator(ngpu).to(device)
# 多卡并行,如果有多卡的话
if device.type == 'cuda' and ngpu > 1:
    netG = nn.DataParallel(netG, list(range(ngpu)))
# 初始化权重  其中,mean=0, stdev=0.2. apply的作用是在netG各个网络层上运用初始化,转置卷积层使用正态分布的随机数初始化权重,无偏置;归一化层使用正态分布的随机数初始化权重,使用0初始化偏置
netG.apply(weights_init)
# 创建一个判别器对象
netD = Discriminator(ngpu).to(device)
# 多卡并行,如果有多卡的话
if device.type == 'cuda' and ngpu > 1:
    netD = nn.DataParallel(netD, list(range(ngpu)))
# 初始化权重  其中,mean=0, stdev=0.2.
netD.apply(weights_init)

[6]:

Discriminator(
,  (main): Sequential(
,    (0): Conv2d(1, 64, kernel_size=(4, 4), stride=(2, 2), padding=(1, 1), bias=False)
,    (1): LeakyReLU(negative_slope=0.2, inplace=True)
,    (2): Conv2d(64, 128, kernel_size=(4, 4), stride=(2, 2), padding=(1, 1), bias=False)
,    (3): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
,    (4): LeakyReLU(negative_slope=0.2, inplace=True)
,    (5): Conv2d(128, 256, kernel_size=(4, 4), stride=(2, 2), padding=(1, 1), bias=False)
,    (6): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
,    (7): LeakyReLU(negative_slope=0.2, inplace=True)
,    (8): Conv2d(256, 512, kernel_size=(4, 4), stride=(2, 2), padding=(1, 1), bias=False)
,    (9): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
,    (10): LeakyReLU(negative_slope=0.2, inplace=True)
,    (11): Conv2d(512, 1, kernel_size=(4, 4), stride=(1, 1), bias=False)
,    (12): Sigmoid()
,  )
,)

定义损失函数和优化器

为两个模型定义损失函数和优化器。

criterion = nn.BCELoss()  # 定义损失函数,适用于二分类问题
# 创建一批潜在向量,我们将使用它们来可视化生成器的生成过程
fixed_noise = torch.randn(100, nz, 1, 1, device=device)
real_label = 1.  # “真”标签
fake_label = 0.  # “假”标签
# 为生成器和判别器定义优化器
optimizerG = torch.optim.Adam(netG.parameters(), lr=lr, betas=(beta1, 0.999))
optimizerD = torch.optim.Adam(netD.parameters(), lr=lr, betas=(beta1, 0.999))

训练阶段

DCGAN 的训练过程如下:

1、首先固定 Generator,训练 Discriminator

  • 输入:真实数据 x,Generator 生成的数据 G(x)
  • 输出:二分类概率

从噪声分布中随机采样噪声 z,经过 Generator 生成 G(z)。G(z)和 x 输入到 Discriminator 得到 D(x) 和 D(G(z)),损失函数为

这里是最大化损失函数,因此使用梯度上升法更新参数。(目的是Discriminator可以区分真实数据和假数据)

2、固定 Discriminator,训练 Generator。

  • 输入:随机噪声 z
  • 输出:分类概率 D(G(z)),目的是使 D(G(z))=1(既判定假数据为真)

从噪声分布中重新随机采样噪声 z,经过 Generator 生成 G(z)。G(z)输入到 Discriminator 得到 D(G(z)),损失函数为

这里是最小化损失函数,使用梯度下降法更新参数。(目的是Generator假数据接近真实数据)

# 定义一些变量,用来存储每轮的相关值
img_list = []
G_losses = []
D_losses = []
D_x_list = []
D_z_list = []
loss_tep = 10
print("Starting Training Loop...")
# 迭代
for epoch in range(num_epochs):
    beg_time = time.time()  # 每一轮开始时间
    # 数据加载器读取数据
    for i, data in enumerate(dataloader):
        ############################
        # (1) Update D network: maximize log(D(x)) + log(1 - D(G(z)))
        ###########################
        # 用所有的真数据进行训练
        netD.zero_grad()  # 每个批量训练开始之前,将D网络的所有参数梯度清0
        # Format batch
        real_cpu = data[0].to(device)  # data[0]为训练数据,data[1]为数据标签
        b_size = real_cpu.size(0)
        label = torch.full((b_size, ),
                           real_label,  # 标识所有训练数据的标签均为真
                           dtype=torch.float,
                           device=device)
        # 判别器推理,只输入真实数据
        output = netD(real_cpu).view(-1)
        # Calculate loss on all-real batch
        # 计算所有真标签的损失函数
        errD_real = criterion(output, label)
        # Calculate gradients for D in backward pass
        errD_real.backward()  # 计算判别器网络的所有参数梯度

                  # 此处计算梯度后不更新参数,等输入假数据后梯度累加,再更新参数

        D_x = output.mean().item()  # 判别器批量真数据上输出的均值
        # 生成假数据并进行训练
        noise = torch.randn(b_size, nz, 1, 1, device=device)   # (100, 100, 1, 1)
        # 用生成器生成假图像
        fake = netG(noise)
        label.fill_(fake_label)  # 标签值全0
        # Classify all fake batch with D
        output = netD(fake.detach()).view(-1)  # fake.detach()的作用是不对G网络的参数求梯度和更新参数
        # 计算判别器在假数据上的损失
        errD_fake = criterion(output, label)
        errD_fake.backward()  # 计算D网络的所有参数梯度
        D_G_z1 = output.mean().item()  # D网络在批量假数据上输出的均值
        # Add the gradients from the all-real and all-fake batches
        errD = errD_real + errD_fake
        # Update D
        optimizerD.step()  # 更新D网络的参数
        ############################
        # (2) Update G network: maximize log(D(G(z)))
        ###########################
        netG.zero_grad()  # 将G网络所有参数的梯度置0
        label.fill_(real_label)  # fake labels are real for generator cost
        # Since we just updated D, perform another forward pass of all-fake batch through D
        output = netD(fake).view(-1)  # 因为要更新G网络的参数,所以要计算G网络的梯度
        # Calculate G's loss based on this output
        errG = criterion(output, label)
        # Calculate gradients for G
        errG.backward()  # 同时计算G网络和D网络参数的梯度
        D_G_z2 = output.mean().item()
        # Update G
        optimizerG.step()  # 更新G网络的参数
        # Output training stats
        end_time = time.time()
        run_time = round(end_time - beg_time)
        print(f'Epoch: [{epoch+1:0>{len(str(num_epochs))}}/{num_epochs}]',
              f'Step: [{i+1:0>{len(str(len(dataloader)))}}/{len(dataloader)}]',
              f'Loss-D: {errD.item():.4f}',
              f'Loss-G: {errG.item():.4f}',
              f'D(x): {D_x:.4f}',
              f'D(G(z)): [{D_G_z1:.4f}/{D_G_z2:.4f}]',
              f'Time: {run_time}s',
              end='\r')
        # Save Losses for plotting later
        G_losses.append(errG.item())
        D_losses.append(errD.item())
        # Save D(X) and D(G(z)) for plotting later
        D_x_list.append(D_x)  # 输入真实数据时D网络的输出
        D_z_list.append(D_G_z2)  # 输入假数据时D网络的输出
        # 保存最好的模型
        if errG < loss_tep:
            torch.save(netG.state_dict(), 'model.pt')
            temp = errG
    # Check how the generator is doing by saving G's output on fixed_noise
    with torch.no_grad():  # 上下文中生成的张量不需要计算梯度
        fake = netG(fixed_noise).detach().cpu()  # detach确保G网络的参数不被更新
    img_list.append(utils.make_grid(fake * 0.5 + 0.5, nrow=10))  # fake*0.5+0.5是为了将图像像素值从范围[-1, 1]调整为[0,1]
    print()
Starting Training Loop...

Epoch: [01/10] Step: [700/700] Loss-D: 0.4350 Loss-G: 2.9547 D(x): 0.7841 D(G(z)): [0.1346/0.0773] Time: 108s

Epoch: [02/10] Step: [700/700] Loss-D: 0.4743 Loss-G: 0.9218 D(x): 0.6646 D(G(z)): [0.0194/0.4482] Time: 112s

Epoch: [03/10] Step: [700/700] Loss-D: 0.0687 Loss-G: 3.8681 D(x): 0.9497 D(G(z)): [0.0155/0.0298] Time: 112s

Epoch: [04/10] Step: [700/700] Loss-D: 0.3206 Loss-G: 3.1840 D(x): 0.8709 D(G(z)): [0.1496/0.0575] Time: 112s

Epoch: [05/10] Step: [700/700] Loss-D: 0.0596 Loss-G: 4.5093 D(x): 0.9767 D(G(z)): [0.0343/0.0166] Time: 110s

Epoch: [06/10] Step: [700/700] Loss-D: 0.2968 Loss-G: 2.6771 D(x): 0.9515 D(G(z)): [0.2015/0.0979] Time: 110s

Epoch: [07/10] Step: [700/700] Loss-D: 0.5452 Loss-G: 1.7598 D(x): 0.7117 D(G(z)): [0.1462/0.2073] Time: 109s

Epoch: [08/10] Step: [700/700] Loss-D: 0.1074 Loss-G: 3.9390 D(x): 0.9226 D(G(z)): [0.0230/0.0279] Time: 112s

Epoch: [09/10] Step: [700/700] Loss-D: 1.0417 Loss-G: 4.9647 D(x): 0.9736 D(G(z)): [0.5448/0.0107] Time: 115s

Epoch: [10/10] Step: [700/700] Loss-D: 0.0346 Loss-G: 4.9161 D(x): 0.9926 D(G(z)): [0.0263/0.0111] Time: 117s

模型训练完毕后,会保存成一个 model.pt 文件

在运行过程中,可以打开终端,查看 GPU 运行情况

enter image description here

然后在终端运行以下命令!

watch -n 0.1 nvidia-smi

Image

可视化

1. 生成器与判别器损失函数曲线

plt.title("Generator and Discriminator Loss During Training")
plt.plot(G_losses[::100], label="G")
plt.plot(D_losses[::100], label="D")
plt.xlabel("iterations")
plt.ylabel("Loss")
plt.axhline(y=0, label="0", c="g")  # asymptote,水平参考线
plt.legend()

[9]:

<matplotlib.legend.Legend at 0x7f9ed3870438>

2. 训练过程展示

fig = plt.figure(figsize=(10, 10))  # 创建一个画布对象,设置图像尺寸为10*10尺寸
plt.axis("off")  # 取消坐标轴

  # 调整存储在img_list中图像维度的顺序为H*W*C,plt才可以正确显示

ims = [[plt.imshow(item.permute(1, 2, 0), animated=True)] for item in img_list]
ani = animation.ArtistAnimation(fig,
                                ims,
                                interval=1000,
                                repeat_delay=1000,
                                blit=True)
HTML(ani.to_jshtml())  # 将动画对象转换为html格式,并使用html展示

[10]:

, , , , , ,,  ,,  ,

,  ,  , , ,  , ,  ,  , ,  , ,  , ,  , ,  ,

,

,  , Once ,  , Loop ,  , Reflect ,

,,, , ,

3. 真(训练集中的)——假(网络生成的)图片对比

# Size of the Figure
plt.figure(figsize=(20, 10))
# Plot the real images
plt.subplot(1, 2, 1)  # 在第一个子图中展示真实数据图像
plt.axis("off")
plt.title("Real Images")
real = next(iter(dataloader))
plt.imshow(
    utils.make_grid(real[0][:100] * 0.5 + 0.5, nrow=10).permute(1, 2, 0))
# Load the Best Generative Model
netG = Generator(0)  # 使用CPU
netG.load_state_dict(torch.load('model.pt', map_location=torch.device('cpu')))
netG.eval()  # 将G网络设置为评估模型,既不进行梯度计算
# Generate the Fake Images
with torch.no_grad():
    fake = netG(fixed_noise.cpu())
# Plot the fake images
plt.subplot(1, 2, 2)  # 在第二个子图中展示生成数据图像
plt.axis("off")
plt.title("Fake Images")
fake = utils.make_grid(fake * 0.5 + 0.5, nrow=10)
plt.imshow(fake.permute(1, 2, 0))
# Save the comparation result
plt.savefig('result.jpg', bbox_inches='tight')


-- By:有三AI 团队

聚焦于让大家能够系统性地完成AI各个领域所需的专业知识的学习,实现三人行必有AI,三人行必有我师的愿景。

  • 21
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 阿里云天池大赛是一个非常有名的数据科学竞赛平台,其中机学习竞赛是其中的一个重要组成部分。在这个竞赛中,参赛者需要使用机学习算法来解决各种各样的问题,例如图像识别、自然语言处理、推荐系统等等。 机学习竞赛的解题过程通常包括以下几个步骤: 1. 数据预处理:参赛者需要对提供的数据进行清洗、特征提取、数据转换等操作,以便于后续的建模和训练。 2. 模型选择:参赛者需要选择适合当前问题的机学习算法,并对其进行调参和优化。 3. 模型训练:参赛者需要使用训练数据对模型进行训练,并对训练过程进行监控和调整。 4. 模型评估:参赛者需要使用测试数据对模型进行评估,以确定其在实际应用中的性能表现。 5. 结果提交:参赛者需要将最终的模型结果提交到竞赛平台上进行评估和排名。 在机学习竞赛中,成功的关键在于对问题的深入理解和对机学习算法的熟练掌握。同时,参赛者还需要具备良好的团队合作能力和沟通能力,以便于在竞赛中取得更好的成绩。 ### 回答2: 阿里云天池大赛是一个非常受欢迎的机学习竞赛平台,它汇集了大量来自世界各地的数据科学家,分享了一系列有趣的竞赛和可用的数据集,供参赛选手使用。机学习篇中,我们将解析一些常见的阿里云天池大赛题目,让大家对机学习竞赛有更深入的了解。 一、赛题选取 阿里云天池大赛的赛题通常与商业、医疗等复杂领域相关,选择数据集时要了解行业背景和数据质量,以准确地判断模型的准确性和适用性。此外,在选择赛题时,还要考虑与参赛选手一起合作的可能性,以及他们可能使用的算法和技术。因此,为了成功解决赛题,参赛者应当仔细研究题目的背景、数据、分析目标等内容,有助于更好地理解问题及其解决方案。 二、数据清洗 参赛者在使用数据时,需要对其进行实质性的预处理和清洗工作,以减少不准确的数据对结果的影响。预处理和清洗包括基本的数据处理,例如缺失值、异常值和重复值的处理,还需要利用可视化和探索性数据分析等技术来检查数据的分布情况、相互关系和异常值等问题。 三、特征选择 在构建模型之前,参赛选手必须确定哪些特征会对问题的解决产生实际影响。这个过程称为特征选择,它旨在通过保留最相关的特征来减少模型复杂性,提高准确性,并且还有助于减少数据集的维数。特征选择包括基于统计学和机学习的算法,同时应该考虑特征的相关性和重要性。 四、建模和评估 参赛者在解决问题时,需要考虑使用何种算法,以及如何构建对应的模型。此外,还需在不同的算法和模型之间进行比较,并选择最优模型。最后,应该针对模型进行评估,以确保各种重要性能指标(例如准确性,召回率,精确度等)都得到最佳表现。 总的来说,机学习是一种复杂而令人兴奋的技术,参赛者要考虑数据质量、数据清洗、特征选择、建模和评估等诸多因素。通过参加阿里云天池大赛,大家可以不断学习和练习,不仅提升自己的技能,同时还有机会获得丰厚的奖励。 ### 回答3: 阿里云天池大赛是一个集数据竞赛、人才选拔、行业交流、技术分享、产学研合作等多种功能于一体的大型平台。其中,机学习篇的赛题挑战包括了各种典型机学习场景,旨在挖掘数据中价值,提高数据应用和解决实际问题的能力。 在机学习篇的赛题中,常见的任务包括分类、回归、聚类、推荐等,其中分类问题是最常见的任务之一。分类可以分为二分类、多分类、超大规模分类等多个子类型。对于分类问题,大家需要学习分类算法,如KNN、NB、SVM、LR、GBDT、XGBoost等,并熟悉如何调参等技巧。 回归问题主要是根据给定的样本数据,预测一个连续的数值。回归问题旨在找到独立变量(X)和连续依赖变量(Y)之间的关系,以便使用该模型来预测连续依赖变量的值。对于回归问题,大家需要掌握线性回归、岭回归、Lasso回归、ElasticNet回归等算法。 聚类问题是将相似的数据划分到同一类别中,相似度较高,不同类别之间相似度较低。对于聚类问题,大家需要学习如何使用K-means、DBSCAN、Hierarchical聚类算法。 推荐问题是根据用户的行为习惯,预测用户的需求,以便将相应的内容推荐给用户。推荐问题的数据通常包括用户的行为、物品的属性和用户的评分。推荐问题常用的算法包括CF、ALS、LFM等。除此之外,还有深度学习在图像识别、语音识别、自然语言处理、推荐、游戏AI等方面具有广泛的应用,如CNN、RNN、LSTM、GAN等。 总之,机学习篇的赛题挑战涉及到各种典型机学习算法和应用场景,需要大家掌握基础理论和实践技巧,并多参加实战项目和比赛练习,不断提升自己的能力和水平。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值