前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >开源图书《Python完全自学教程》12.6机器学习案例12.6.2猫狗二分类

开源图书《Python完全自学教程》12.6机器学习案例12.6.2猫狗二分类

作者头像
老齐
发布于 2022-12-09 12:26:58
发布于 2022-12-09 12:26:58
76300
代码可运行
举报
文章被收录于专栏:老齐教室老齐教室
运行总次数:0
代码可运行

12.6.2 猫狗二分类

深度学习机器学习的一个分支,目前常用的深度学习框架有 TensorFlow、PyTorch和飞桨等(飞桨,即 PaddlePaddle,全中文的官方文档,让学习者不为语言而担忧)。本小节中将以 PyTorch 演示一个经典的案例,让初学 Python 的读者对深度学习有感性地认识。所以,以下代码可不求甚解,只要能认识到所涉及到的基础知识并不陌生即可——除了 PyTorch 部分。

“Dogs vs. Cats”是一个传统的二分类问题,下面示例所用的数据集来自于 kaggle.com ,在项目网页(https://www.kaggle.com/c/dogs-vs-cats-redux-kernels-edition/)上可以看到两个压缩包(登录网站之后可以下载),train.zip 用作训练集(其中一部分作为验证集),test.zip 用作测试集。在训练集中(将所下载的 train.zip ,解压缩之后,放到 ./data/train 目录中),所有图片都是用 cat.<id>.jpgdog.<id>.jpg 格式命名,用图片文件的名称作为每张图片的标签(如图12-6-2所示)。

图12-6-2 训练集中的图片

1. 组织数据

将所下载的压缩包 train.zip 在目录 ./data 中解压缩。并在 ./data/train 中创建两个子目录,即 ./data/train/cats./data/train/dogs 。然后创建子目录 ./data/val ,在其中也创建另两个子目录 ./data/val/dogs./data/val/cats 。将 ./data/train 中的数据称为训练集./data/val 中的称为验证集

将所下载的压缩包 test.zip 也在 ./data 中解压缩,得到子目录 ./data/test ,此目录中的数据称为测试集

经过上述操作之后,得到了如下所示的目录结构:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
% tree data -d
data
├── test
├── train
│   ├── cats
│   └── dogs
└── val
    ├── cats
    └── dogs

7 directories

然后写一段代码,按照前述要求,将本来已经存在 ./data/train 中的图片,按照文件名中所标示出的 dogcat 分别移动到 ./data/train/cats./data/train/dogs 目录中。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[11]: import re
      import shutil
      import os

      # 训练集目录
      train_dir = "./data/train"
      train_dogs_dir = f"{train_dir}/dogs"
      train_cats_dir = f"{train_dir}/cats"
      # 验证集目录
      val_dir = "./data/val"
      val_dogs_dir = f"{val_dir}/dogs"
      val_cats_dir = f"{val_dir}/cats"

      files = os.listdir(train_dir) 
      for f in files:
          cat_search = re.search('cat', f)    # (1)
          dog_search = re.search('dog', f)
          if cat_search:
              shutil.move(f'{train_dir}/{f}', train_cats_dir)  # (2)
          if dog_search:
              shutil.move(f"{train_dir}/{f}", train_dogs_dir)

在代码 [11] 中将前面所创建的目录结构分别用变量引用,并且实现了图片移动。注释(1)中使用了标准库中的 re 模块,用正则表达式判断字符串 cat 是否在文件名中。例如(在 Python 交互模式中演示):

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> import re
>>> bool(re.search('cat', 'cat.5699.jpg'))
True
>>> bool(re.search('cat', 'dog.10149.jpg'))
False

关于模块 re 的更多内容,可以参考官方文档(https://docs.python.org/3/library/re.html)。

注释(2)中使用的 shutil 模块也是 Python 标准库的一员,函数 shutil.move() 能够将文件移动到指定目录中( shutil 模块的官方文档地址:https://docs.python.org/3/library/shutil.html)。

运行代码块 [11] 后,将猫和狗的图片分别放在了两个不同的目录中,在 Jupyter 中可以这样查看( lsLinux 命令):

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[12]: print("目录 train_dir 中已经没有图片")
      !ls {train_dir} | head -n 5

      print("目录 train_dogs_dir 中是狗图片(显示5个)")
      !ls {train_dogs_dir} | head -n 5

      print("目录 train_cats_dir 中是猫图片(显示5个)")
      !ls {train_cats_dir} | head -n 5
      
# 输出
      目录 train_dir 中已经没有图片
      cats
      dogs
      目录 train_dogs_dir 中是狗图片(显示5个)
      dog.0.jpg
      dog.1.jpg
      dog.10.jpg
      dog.100.jpg
      dog.1000.jpg
      目录 train_cats_dir 中是猫图片(显示5个)
      cat.0.jpg
      cat.1.jpg
      cat.10.jpg
      cat.100.jpg
      cat.1000.jpg

./data/train/cats./data/train/dogs 两个目录中,各有 12500 张图片,再从每个目录中取一部分(此处取 1000 张)图片分别放到对应的验证集目录 ./data/val/cats./data/val/dogs 中。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[13]: dogs_files = os.listdir(train_dogs_dir)
      cats_files = os.listdir(train_cats_dir)

      for dog in dogs_files:
          val_dog_search = re.search("7\d\d\d", dog)
          if val_dog_search:
              shutil.move(f"{train_dogs_dir}/{dog}", val_dogs_dir)

      for cat in cats_files:
          val_cat_search = re.search("7\d\d\d", cat)
          if val_cat_search:
              shutil.move(f"{train_cats_dir}/{cat}", val_cats_dir)
        
      print("目录 val_dogs_dir 中是狗图片")
      !ls {val_dogs_dir} | head -n 5
      print("目录 val_cats_dir 中是狗图片")
      !ls {val_cats_dir} | head -n 5
# 输出:
      目录 val_dogs_dir 中是狗图片
      dog.7000.jpg
      dog.7001.jpg
      dog.7002.jpg
      dog.7003.jpg
      dog.7004.jpg
      目录 val_cats_dir 中是狗图片
      cat.7000.jpg
      cat.7001.jpg
      cat.7002.jpg
      cat.7003.jpg
      cat.7004.jpg

代码块 [13] 将文件名中 <id> 为 7000 至 7999 的图片移动到相应的验证集目录中。

2. 训练模型

数据已经组织好了,即将使用 PyTorch 创建并训练模型。PyTorch 的官方网站是:https://pytorch.org/ ,它提供了非常友好的 Python 接口,与其他第三方包一样,安装后即可使用。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
% pip install torch torchvision

安装完毕。如果在如下所演示的 Jupyter 代码中提示无法找到 torch ,可以关闭并退出当前的 Jupyter Lab 后,从新执行 jupyter-lab ——如果还找不到 torch ,请在网上搜索有关资料,并结合本地环境进行修改(导致“搜索路径”问题的因素较多,比如环境变量设置等,需要读者细心、耐心地解决)。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[14]: import numpy as np

      import torch
      import torch.nn as nn
      import torch.optim as optim
      from torch.optim import lr_scheduler

      import torchvision
      from torchvision import datasets, models, transforms

      import matplotlib.pyplot as plt
      import time
      import os
      import copy
      import math

      torch.__version__
[14]: '1.6.0'

按照代码块 [14] 将有关对象引入,此处所用的 PyTorch 版本是 1.6.0 ,读者所安装的若不低于这个版本,代码一般通用。

再次声明,本节不是 PyTorch 的完整学习资料,所以对代码不会做非常详尽地解释,读者囫囵吞枣也无妨,只需要有初步体验即可。

在深度学习项目中,数据扩充(或称“数据增强”、“数据增广”,data augmentataion)往往是不可避免的,这是由于缺少海量数据,为了保证模型的有效性,本着“一分钱掰成两半花”的精神而进行的。最简单的数据扩充方法包括翻转、旋转、尺度变换等等。另外,由于不同的图片大小各异,也需要将图片尺寸规范到限定的范围。还有就是要张量化,才能用于模型的张量运算(关于“张量”的基本概念,参阅拙作《机器学习数学基础》)。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[15]: data_transforms = {
          'train': transforms.Compose([
                       transforms.RandomRotation(5),
                       transforms.RandomHorizontalFlip(),
                       transforms.RandomResizedCrop(
                           224, 
                           scale=(0.96, 1.0), 
                           ratio=(0.95, 1.05)), 
                       transforms.ToTensor(),
                       transforms.Normalize(
                           [0.485, 0.456, 0.406], 
                           [0.229, 0.224, 0.225])]),
          'val': transforms.Compose([
                       transforms.Resize([224, 224]), 
                       transforms.ToTensor(), 
                       transforms.Normalize(
                           [0.485, 0.456, 0.406], 
                           [0.229, 0.224, 0.225])]),
      }

然后使用 data_transforms 定义训练集和验证集数据,以及必要的常量。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[16]: data_dir = 'data'
      CHECK_POINT_PATH = './data/checkpoint.tar'
      SUBMISSION_FILE = "./data/submission.csv"
      image_datasets = {x: datasets.ImageFolder(
                               os.path.join(data_dir, x), 
                               data_transforms[x]) for x in ['train', 'val']}
      dataloaders = {x: torch.utils.data.DataLoader(
                            image_datasets[x], 
                            batch_size=4, 
                            shuffle=True, 
                            num_workers=4) for x in ['train', 'val']}
      dataset_sizes = {x: len(image_datasets[x]) for x in ['train', 'val']}
      class_names = image_datasets['train'].classes

      device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')

      print(class_names)
      print(f"Train image size: {dataset_sizes['train']}")
      print(f"Validation image size: {dataset_sizes['val']}")
 
 # 输出:
      ['cats', 'dogs']
      Train image size: 23000
      Validation image size: 2000

现在训练集中的图片数量是 23000,验证集有 2000 张图片。在代码块 [16] 的 dataloaders 中设置 batch_size=4 (batch,常译为“批”),下面就显示训练集中由 4 张图片组成的“1批”(随机抽取)。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[17]: def imshow(inp, title=None):
          inp = inp.numpy().transpose((1, 2, 0))
          mean = np.array([0.485, 0.456, 0.406])
          std = np.array([0.229, 0.224, 0.225])
          inp = std * inp + mean
          inp = np.clip(inp, 0, 1)
          plt.imshow(inp)
          if title is not None:
              plt.title(title)
          plt.pause(0.001)

      inputs, classes = next(iter(dataloaders['train']))
      sample_train_images = torchvision.utils.make_grid(inputs)
      imshow(sample_train_images, title=classes)

输出图像:

这批(batch)图片即对应于张量 tensor([1, 0, 1, 0])

下面编写训练模型的函数。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[18]: def train_model(model, criterion, optimizer, 
                      scheduler, num_epochs=2, checkpoint = None):
          since = time.time()

          if checkpoint is None:
              best_model_wts = copy.deepcopy(model.state_dict())
              best_loss = math.inf
              best_acc = 0.
          else:
              print(f'Val loss: {checkpoint["best_val_loss"]}, 
                      Val accuracy: {checkpoint["best_val_accuracy"]}')
              model.load_state_dict(checkpoint['model_state_dict'])
              best_model_wts = copy.deepcopy(model.state_dict())
              optimizer.load_state_dict(checkpoint['optimizer_state_dict'])
              scheduler.load_state_dict(checkpoint['scheduler_state_dict'])
              best_loss = checkpoint['best_val_loss']
              best_acc = checkpoint['best_val_accuracy']

          for epoch in range(num_epochs):
              print('Epoch {}/{}'.format(epoch, num_epochs - 1))
              print('-' * 10)

              # 每轮(epoch)含一次训练和验证
              for phase in ['train', 'val']:
                  if phase == 'train':
                      scheduler.step()
                      model.train()  
                  else:
                      model.eval()   
                  running_loss = 0.0
                  running_corrects = 0

                  # Iterate over data.
                  for i, (inputs, labels) in enumerate(dataloaders[phase]):
                      inputs = inputs.to(device)
                      labels = labels.to(device)

                      # 梯度归零
                      optimizer.zero_grad()
                
                      if i % 200 == 199:
                          print(f'[{epoch+1}, {i}] loss: 
                                  {running_loss/(i*inputs.size(0)):.3f}')

                      # 前向
                      # 跟踪训练过程
                      with torch.set_grad_enabled(phase == 'train'):
                          outputs = model(inputs)
                          _, preds = torch.max(outputs, 1)
                          loss = criterion(outputs, labels)

                          # 后向/反向,在训练过程中
                          if phase == 'train':
                              loss.backward()
                              optimizer.step()

                      # 统计
                      running_loss += loss.item() * inputs.size(0)
                      running_corrects += torch.sum(preds == labels.data)

                  epoch_loss = running_loss / dataset_sizes[phase]
                  epoch_acc = running_corrects.double() 
                              / dataset_sizes[phase]

                  print(f'{phase} Loss: {epoch_loss:.4f} Acc: 
                          {epoch_acc:.4f}')

                  # 深拷贝模型
                  if phase == 'val' and epoch_loss < best_loss:
                      print(f'New best model found!')
                      print(f'New record loss: {epoch_loss}, 
                              previous record loss: {best_loss}')
                      best_loss = epoch_loss
                      best_acc = epoch_acc
                      best_model_wts = copy.deepcopy(model.state_dict())

              print()

          time_elapsed = time.time() - since
          print(f'Training complete in 
                  {time_elapsed // 60:.0f}m {time_elapsed % 60:.0f}s')
          print(f'Best val Acc: {best_acc:.4f} Best val loss: 
                  {best_loss:.4f}')

          # 载入最佳的模型权重
          model.load_state_dict(best_model_wts)
          return model, best_loss, best_acc

代码块 [18] 的函数首先检查 checkpoint 的值,如果为 True 则会加载训练的模型,并在其基础上更新参数,否则会从头开始训练。在本示例中,我们提供了一个预训练的模型——在此基础上继续训练,可以减少训练时间——即代码块 [16] 中的 CHECK_POINT_PATH = './data/checkpoint.tar' (读者可以在本书的源码仓库中获得,代码仓库地址参阅 www.itdiffer.com 中关于本书的在线资料)。

之后载入卷积神经网络模型,它擅长于图像识别

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[19]: model_conv = torchvision.models.resnet50(pretrained=True)

当前的任务是二分类,故还要对此卷积神经网络模型进行个性化设置,如定义损失函数(交叉熵,nn.CrossEntropyLoss() )、优化器算法(随机梯度下降,SGD )、学习率( lr_scheduler.StepLR() )。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[20]: for param in model_conv.parameters():    # (3)
          param.requires_grad = False

      num_ftrs = model_conv.fc.in_features
      model_conv.fc = nn.Linear(num_ftrs, 2)

      model_conv = model_conv.to(device)

      criterion = nn.CrossEntropyLoss()

      optimizer_conv = optim.SGD(model_conv.fc.parameters(), 
                                 lr=0.001, momentum=0.9)

      exp_lr_scheduler = lr_scheduler.StepLR(optimizer_conv, 
                                             step_size=7, gamma=0.1)

在代码块 [20] 的注释(3)中,设置 param.requires_grad = False 旨在仅训练所导入的卷积神经网络 resnet50 模型的最后一层的参数。如果要训练所有层的所有参数,需要将代码做如下修改:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
for param in model_conv.parameters():
    param.requires_grad = True
    
model_conv = model_conv.to(device)

optimizer_ft = optim.SGD(model_conv.parameters(), lr=0.001, momentum=0.9)

下面进入实质化的训练过程(训练过程所用的时间会因本地计算机的性能和配置有所不同,但都要耗费一段时间,需要耐心等待)。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[21]: try:
          checkpoint = torch.load(CHECK_POINT_PATH)
          print("checkpoint loaded")
      except:
          checkpoint = None
          print("checkpoint not found")
      model_conv, best_val_loss, best_val_acc = 
                     train_model(model_conv,
                                 criterion,
                                 optimizer_conv,
                                 exp_lr_scheduler,
                                 num_epochs = 3,
                                 checkpoint = checkpoint)
      torch.save({'model_state_dict': model_conv.state_dict(),
                  'optimizer_state_dict': optimizer_conv.state_dict(),
                  'best_val_loss': best_val_loss,
                  'best_val_accuracy': best_val_acc,
                  'scheduler_state_dict' : exp_lr_scheduler.state_dict(),
                  }, CHECK_POINT_PATH)
# 输出
      Val loss: 0.03336585155675109, Val accuracy: 1.0
      Epoch 0/2
      ----------
      [1, 199] loss: 0.240
      ...  # 省略部分显示
      train Loss: 0.2325 Acc: 0.9055
      [1, 199] loss: 0.068
      [1, 399] loss: 0.068
      val Loss: 0.0699 Acc: 0.9770

      Epoch 1/2
      ----------
      [2, 199] loss: 0.196
      ...  # 省略部分显示
      train Loss: 0.2363 Acc: 0.9046
      [2, 199] loss: 0.054
      [2, 399] loss: 0.062
      val Loss: 0.0664 Acc: 0.9770

      Epoch 2/2
      ----------
      [3, 199] loss: 0.255
      ...  # 省略部分显示
      train Loss: 0.2341 Acc: 0.9040
      [3, 199] loss: 0.064
      [3, 399] loss: 0.065
      val Loss: 0.0651 Acc: 0.9760

      Training complete in 349m 52s      # 这是训练所用时间
      Best val Acc: 1.0000 Best val loss: 0.0334

当代码块 [21] 终于运行完毕——一般而言,这是一个漫长的过程——就训练好了一个具有识别猫、狗能力的模型 model_conv

然后编写如下代码,检验模型在验证集上的“识别”结果。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[22]: def visualize_model(model, num_images=2):
          was_training = model.training
          model.eval()
          images_so_far = 0
          fig = plt.figure()

          with torch.no_grad():
              for i, (inputs, labels) in enumerate(dataloaders['val']):
                  inputs = inputs.to(device)
                  labels = labels.to(device)
                  outputs = model(inputs)
                  _, preds = torch.max(outputs, 1)

                  for j in range(inputs.size()[0]):
                      images_so_far += 1
                      ax = plt.subplot(num_images//2, 2, images_so_far)
                      ax.axis('off')
                      ax.set_title(f'predicted: {class_names[preds[j]]}')
                      imshow(inputs.cpu().data[j])

                      if images_so_far == num_images:
                          model.train(mode=was_training)
                          return
              model.train(mode=was_training)
visualize_model(model_conv)

输出图示:

但这不是对模型的真正测试。

3. 测试模型

保存在子目录 ./data/test 里面的图片为“测试集” ,现在就用它们来检验模型的“识别”能力。测试集中的每个图片文件以 <id>.jpg 格式命名,从文件名上不知道它是猫还是狗。

本来,可以用 PyTorch 直接从 .data/test 中读入数据。但是,为了向读者多展示一些 Python 库的应用,此处改用另外的方式。首先,创建一个将图片转换为张量的函数(类似于代码块 [15] 的 data_transforms['val'] )。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[23]: def apply_test_transforms(inp):
          out = transforms.functional.resize(inp, [224,224])
          out = transforms.functional.to_tensor(out)
          out = transforms.functional.normalize(out, 
                                                [0.485, 0.456, 0.406], 
                                                [0.229, 0.224, 0.225])
          return out

Python 中关于图片的库被称为 Python Imageing Library ,简称 PIL ,其中 Pillow 是 PIL 的一个常用分支(同样是一个库),其官方网站是:https://pillow.readthedocs.io/。安装方法如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
% pip install Pillow

然后用 PIL 从测试集中读取文件(以下代码中显示其中的一张图片)。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[24]: from PIL import Image

      test_data_dir = f'{data_dir}/test'
      test_data_files = os.listdir(test_data_dir)
      im = Image.open(f'{test_data_dir}/{test_data_files[0]}')
      plt.imshow(im)

输出图示:

我们已经看到代码块 [24] 中的 im 所引用的图片是一只猫。下面将 im 传入代码块 [23] 定义的函数进行变换。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[25]: im_as_tensor = apply_test_transforms(im)
      print(im_as_tensor.size())
      minibatch = torch.stack([im_as_tensor])
      print(minibatch.size())
# 输出
      torch.Size([3, 224, 224])
      torch.Size([1, 3, 224, 224])

再将 minibatch 传给模型 model_conv ,让它“辨别”图片是猫还是狗。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[26]: preds = model_conv(minibatch)
      preds
[26]: tensor([[ 2.0083, -1.8386]], grad_fn=<AddmmBackward>)

返回值 preds 是一个张量,按照代码块 [26] 的张量输出结果,可知这张图片是猫(第一个数大于第二个数,则是猫)。如果用更直观地方式表述预测结果,可以:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[27]: soft_max = nn.Softmax(dim=1)
      probs = soft_max(preds)
      probs
[27]: tensor([[0.9791, 0.0209]], grad_fn=<SoftmaxBackward>)

将张量里面的数字转化为百分比,probs 的结果说明模型 model_conv “认为”这张图片是猫的概率为 97.91% 。

4. 参加 kaggle 比赛

本小节的项目来自于 kaggle.com ,这是一个著名的深度学习竞赛网站,如果读者也有打算参加,必须要按照网站要求提交 submission.csv 的文件(“Dogs vs. Cats”的竞赛项目已经结束,读者可以参考下述方法,以备参加其他项目),基本格式为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
id,label
1,0.5
2,0.5

其中 id 是测试集(./data/test )中所有图片的 <id>label 为该图片是狗的概率。为此,编写如下函数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[28]: def predict_dog(model, tensor):
          batch = torch.stack([tensor])
          softMax = nn.Softmax(dim = 1)
          preds = softMax(model(batch))
          return preds[0, 1].item()
          
      def test_data(fname):
          im = Image.open(f'{test_data_dir}/{fname}')
          return apply_test_transforms(im)
        
      import re
      def extract_file_id(fname):      # 从文件名中提取 id
          print("Extracting id from " + fname)
          return int(re.search('\d+', fname).group())

然后执行模型的测试函数,并生成一个以 <id> 为键(整数类型,便于排序),以“是狗”的概率为值的字典(下面的代码需要要执行一段时间,测试集中共计 12500 张图片)。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[29]: model_conv.eval()
      id_to_dog_prob = {extract_file_id(fname): 
                        predict_dog(model_conv,test_data(fname))
                        for fname in test_data_files}
# 输出
    Extracting id from 9733.jpg
    ...  # 省略余下显示内容

为了最终得到 .csv 文件,再用 Pandas 将字典对象 id_to_dog_prob 转化为 DataFrame 对象,并保存为 .csv 文件。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[30]: import pandas as pd

      ds = pd.Series({id : label 
                      for (id, label) in 
                      zip(id_to_dog_prob.keys(), id_to_dog_prob.values())})
      df = pd.DataFrame(ds, columns = ['label']).sort_index()
      df['id'] = df.index
      df = df[['id', 'label']]
      df.to_csv(SUBMISSION_FILE, index = False)

最后将 ./data/submission.csv 文件提交到 kaggle 网站即可——虽然此比赛项目已经结束,还可以自我辉煌战果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[31]: df.sample(5)     # 随机选出 5 条记录
[31]:        id    label
      5548 5548 0.999494
      8238 8238 0.998453
      8961 8961 0.999983
      4762 4762 0.003668
      2623 2623 0.000197

自学建议 如果读者有意将来从事机器学习有关的工作,所要学习的知识除了编程语言之外(最常用的编程语言是 Python ,此外还有 R 、Julia 等),还包括12.4节中科学计算的有关内容。除此之外,针对机器学习和深度学习都有一些库或开发框架,使用它们就相当于“站在巨人肩膀上”,或者说找到了“生产力工具”,比如 scikit-learn 、PyTorch、Tensorflow、飞桨(PaddlePaddle)等。 以上所列都是进入机器学习领域的技术准备,除了这些之外,还有一个前置的知识准备:足够的数学知识(参阅拙作《机器学习数学基础》,电子工业出版社)。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-08-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 老齐教室 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
985 博士真的会舍弃华为年薪接近 100 万 offer,去选择年薪 20 万的公务员吗?
喜欢做学术并且博士期间学术做得比较有成就的同学会选择做学术,其他同学(也有学术巨牛逼的,比如手握十几篇顶会,一作大几篇的)基本上都会选择业界就职,包括华为,Google,MSRA 这种技术公司和量化(国内 top 量化九坤的创始人就是我们院前辈,所以我们去九坤的很多),还有前几年比较好的区块链币圈或者美元基金。当然今年就业形势很差,选择华为的会比较多
用户6983566
2023/01/14
3.5K0
985 博士真的会舍弃华为年薪接近 100 万 offer,去选择年薪 20 万的公务员吗?
【职场】112家IT公司薪水一览表
作者是西电通院2013届毕业硕士,根据今年找工作的情况以及身边同学的汇总,总结各大公司的待遇如下,吐血奉献,公司比较全。以下绝对是各大公司2013届校招的数据,少数几个是2011、2012的数据,都已经特别注明,数据真实重要性高于一切!选进来的都是已经确认的信息,放心参考。 这里所说的待遇全部为税前,另外,年薪不是简单的*12,因为有年终奖。而互联网公司的待遇package,都是包含了年终奖的。 以下待遇无特别说明,默认都是硕士,本科的话会特别说明,关注软件的多一些。 1、华为:研发、服务、销售多数岗位 本
小莹莹
2018/04/20
2.7K0
留美博士生涌现回流中国潮!一是因为工资,二是因为特朗普
根据教育部4月发布的最新统计数据,去年中国有大约60万学生在海外留学,其中一半以上在美国学习。
新智元
2018/09/25
7140
留美博士生涌现回流中国潮!一是因为工资,二是因为特朗普
申请CS博士学位前,布朗大学Jeff Huang团队这份师资、排名和奖学金统计值得参考
机器之心报道 编辑:蛋酱 这是一份申请 CS 博士学位前可以认真参考的统计资料。 哪些机构获得了 CS 领域最多的最佳论文奖?申请计算机科学领域的博士学位,各大院校的津贴水平如何?不同院校的 CS 学科水平究竟排名如何?这些问题,想必很多正打算申请 CS 博士学位的人都非常关心。 近日,布朗大学副教授 Jeff Huang 团队总结了一份与 CS 博士学位有关的数据统计,包含师资、排名和奖学金等事项。 这篇文章将介绍相关的亮点内容,如下: CS 教授构成与招聘分析 对 5000 多名计算机科学教授的分析
机器之心
2022/05/06
4830
申请CS博士学位前,布朗大学Jeff Huang团队这份师资、排名和奖学金统计值得参考
年薪50万的人的生活方式
税后五十来万,另有一年十万左右的利息收入和三万多房租。我们住内环两房,限购也无法再买房。
用户3477080
2019/03/09
7K0
2020 程序员找工作指南
offer,录取意向,offer 分为口头 offer 和书面 offer,一般书面 offer 才算是正式 offer,例句
cnguu
2020/10/23
7160
现在想读博以后去高校,还值得吗?
每天给你送来NLP技术干货! ---- 本文来源:学术志(ID:xueshuzhi001)综合整理自知乎、小红书等 在2022年学位与研究生教育发表的论文《我国博士毕业生去向及就业特征分析——基于2015—2020年博士毕业生数据的分析》中,高校以45%的比例位居博士就业单位第一。 从这里不难看出,博士毕业,进入高校工作是他们的首选,当然也有很多同学,读博的目的就是为了进高校。那么直到现在,读博进高校还值得吗? 高校待遇如何? 小红书@Zzzzzz 高校老师入职offer分以下几个部分. 1.协议工资 2
zenRRan
2022/09/28
1.2K0
现在想读博以后去高校,还值得吗?
offer选择,我要为了1000块放弃大厂的offer吗?
最近在知乎上看到一个很有意思的问题:毕业生,在薪资差别不大的情况下,比如500-1000,大公司好还是小公司好?
TechFlow-承志
2023/03/02
3340
offer选择,我要为了1000块放弃大厂的offer吗?
互联网这口饭,是越来越难吃了
往年这个时候,互联网行业都会出现“晒年终奖”的情况,特别是游戏行业,几十个月甚至上百个月的年终奖,都不算稀罕。这样的“土豪年终奖”,让很多人成了柠檬精。
罗超频道
2020/02/14
4600
互联网这口饭,是越来越难吃了
哈哈哈,发年终奖啦,我要去斗鱼打赏最喜欢的妹子~
为了让你们这些 lsp 少踩点坑,小方同学思索许久才想到这个标题,我真是煞费苦心啊。
范蠡
2021/04/25
9220
计算机应届生月薪大多是多少?
月薪4k,6k,8k,10k的各占百分之多少呢,好对自己有个定位,现在听听那些亲身经历者说一说。
磐创AI
2020/03/05
6K0
2021 年互联网大厂职级对应薪资一览表
声明:本文数据部分来自所涉公司官方微信公众号(如:字节范儿),部分来自脉脉各公司职言区,另有部分知乎网友整理内容。除官微数据外,其他内容均来自网络,我们整理于此供大家参考,如有错漏,欢迎指正。
@超人
2021/02/26
39.1K0
2021 年互联网大厂职级对应薪资一览表
微信全面支持“小号”;员工购买公司福利房,被裁员后遭巨额索赔;16岁少年孤身前往深圳腾讯总部解封QQ账号|Q资讯
据外媒消息称,美国将禁止供应商向华为提供任何产品;小米迎来“开年第一件大事”:组织架构调整,设立两个关键委员会;理想销量夺冠后,员工不满年终奖打折;OpenAI 开始将 ChatGPT 商业化,同时发布新工具对其“制裁”;百度出手,国产版 ChatGPT 要来了;微软回应苏州大裁员:不要把宝贵的时间浪费在这种毫无根据的谣言上;英特尔进行大规模降薪:CEO 最高降 25%,员工也受影响;Twitter 前 CEO 力推的 Web3 社交应用刷屏,但已在国内中国大陆 App Store 商店下架;为解封 QQ 空间,16 岁少年春节孤身前往深圳腾讯总部;“他们裁员,我们招聘” ,美国硅谷大裁员德国公司捡漏;春节后,IT 行业用工需求旺盛……
深度学习与Python
2023/02/10
8490
微信全面支持“小号”;员工购买公司福利房,被裁员后遭巨额索赔;16岁少年孤身前往深圳腾讯总部解封QQ账号|Q资讯
14家互联网公司裁员了(1-2月裁员清单)
2022年开年不久,已有14家公司裁员......  下面为未经完全证实消息。 1、微博裁员(2.17) 新浪微博裁员开始。经多方面与内部人士获取信息,相关情况如下: 坐标北京,批量约谈已经于本周开始,有多位员工已经谈完并签署协议; 目前人均有N+1,但本次被裁将无年终奖;另有工作10年的哺乳期员工也在优化范围内,而且赔偿同为N+1; 本次裁员绩效为D的员工全清; 前不久微博新HR负责人上任,本次人员成本的优化可看作“新官上任三把火”; 约谈还在进行中。 先前的一些公司裁员消息都会上微博热搜,这次还会上
张俊红
2022/03/14
3.3K0
作为一个中产阶级,我对国家有哪些不满意
我的文章,很多上面的人都能看到,有的在内部刊物发表,有的被相关领导批示过,也有政府部门联系过我,还有智库针对我的文章发表过评论。
纯洁的微笑
2018/08/16
1K0
作为一个中产阶级,我对国家有哪些不满意
黑掉多家大公司,7名青少年被逮捕;消息称钉钉将上线“下班勿扰”功能​;Java 18 正式发布 | EA周报
腾讯控股发布2021年度第四季度及全年财报。财报显示,2021年第四季度,腾讯营收1442亿元,同比增长 8%,略低于市场预期的1453亿元,No-IFRS净利润248.8亿元,同比大 25%,连续第二个季度负增长,而且幅度扩大了23个百分点。全年No-IFRS净利润1237.88亿元,同比增长仅1%,创近十年来的最低值。在腾讯内部,马化腾曾和员工调侃起自己腰椎不好的老毛病,经过了一年时间的锻炼,拍了部腰的片子,结果和腾讯2020年的业绩一样「突出」。这一次,在腾讯内部社区里,马化腾再次拿自己的「腰」来做调侃:游了一年泳,又拍了片子,结果发现自己的腰椎间盘跟腾讯2021年的情况差不多——不那么突出了,甚至还少了一块儿。(快科技)
yuanyi928
2022/04/19
6840
在 BAT 做三年,普通程序员能拿多少工资?
说到薪资,BAT 作为国内互联网三巨头,员工薪资相信很多人都很好奇。有人提出,按起薪 15k 算,在 BAT 工作了三年的普通员工,按照每年 20% 的增幅可以达到 15*1.2*1.2*1.2=25k。年薪 25k*14(百度),25k*16(腾讯),25k*15(阿里)。那么这个算法准确吗?
哲洛不闹
2018/09/18
2.7K0
在 BAT 做三年,普通程序员能拿多少工资?
运营商遭虚拟运营商挖角:传统企业难抗衡互联网
一个久未谋面的前运营商同事约我喝茶叙旧。聊的话题除了生活、创业之外,大多还是通信。最后这位朋友话锋一转,“你觉得虚拟运营商怎么样?”我立马反映过来,核心问题来了。 没错,他收到了虚拟运营商的猎头电话,正在纠结要不要离开为之奋斗近十年的公司和城市,到另一座城市寻找一个更好的前程。当人们遇到重大问题拿捏不定时,往往需要寻找外力,给自己潜意识已经做出的选择更多的支撑。我给了他一些说了等于没说的建议,因为你永远无法帮别人做决定。 能够影响一个人轨迹的重大选择并不多。升学、择偶,还有求职。在人
罗超频道
2018/04/28
1.4K1
将浪潮、曙光等 10 家告上法庭:索赔金额数百万
前两日,云头条发布了《郭某以恶意取消录用为由:将一公司告上法庭,索赔 100 万》、《反转、17900 元不用赔了》的内容。 经深度查询,郭某与10家企业存在劳动争议纠纷。 以上内容根据《裁决文书网》资料整理,云头条将以上案件主角郭某判断为一个人的原因为,姓名相同、生日相同、籍贯相同、职位类似,案件诉讼内容相近。 其与每家的劳动纠纷在 2~ 6 个之间,大多会二审,案由以违法解除劳动合同、竞业限制为主。 云头条选择浪潮、曙光两家比较典型的案例发布这里,供大家参考。云头条编辑过程中根据重要程度对裁决文书
云头条
2022/09/20
7770
将浪潮、曙光等 10 家告上法庭:索赔金额数百万
一个中科大差生的8年程序员工作总结
平时遇到自己觉得比较感兴趣的文章,如果我当时没有时间阅读,就会将其列为阅读代办。后面有时间了,抽出时间再细看。
Guide哥
2021/02/08
6650
推荐阅读
相关推荐
985 博士真的会舍弃华为年薪接近 100 万 offer,去选择年薪 20 万的公务员吗?
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档