机器学习的入门笔记(第十三周)

本周观看了李沐老师的《动手学深度学习》和李宏毅老师的课程,李沐老师很注重代码的编写,但是对概念的讲解并不是特别多,所以还要去结合一些其他的资料去进行了解;李宏毅老师讲解的理论知识真的很好,两者可以相互借鉴,互相补充学习,下面是本周的所看的课程总结。

狗的品种识别(ImageNet Dogs)

与上周的CIFAR10的识别相似,进行分类,只不过这次利用的模型为resnet34,是微调后的模型,只设置除输出层的权重参数梯度,并最终没有只对图片进行一个品种的预测,是利用softmax进行每个类别的预测概率的输出。

1、加载相关模块

import os
import torch
import torchvision
from torch import nn
from torch.utils.data import DataLoader
from d2l import torch as d2l
import collections
import shutil
import math

2、加载ImageNet Dog的tiny数据集,这个数据集小一些,方便下载和训练,其中训练集有1000张图片,测试集有10张图片,另外还有labels.csv文件,里面包括图片的id和breed品种数据

d2l.DATA_HUB['dog_tiny'] = (d2l.DATA_URL+'kaggle_dog_tiny.zip','0cb91d09b814ecdc07b50f31f8dcad3e81d6a86d')
## 如果使用Kaggle比赛的完整数据集,请将下面的变量更改为False
demo = True
if demo:
    data_dir = d2l.download_extract('dog_tiny')
else:
    data_dir = '../data/dog-breed-identification'

3、定义函数,读取id和breed标签的labels.csv文件,将每个id和breed生成一个字典

def read_csv_data(fname):
    with open(fname,'r') as f:
        lines = f.readlines()[1:]
    tokens = [line.rstrip().split(',') for line in lines]
    return dict(tokens)
labels = read_csv_data(os.path.join(data_dir,'labels.csv'))

labels

'''
{'0097c6242c6f3071762d9f85c3ef1b2f': 'bedlington_terrier',
 '00a338a92e4e7bf543340dc849230e75': 'dingo',
 '00b7d114bc5166a629a3cc03d9329120': 'irish_water_spaniel',
 '00f34ac0a16ef43e6fd1de49a26081ce': 'walker_hound',
 '010e87fdf252645a827e37470e65e842': 'groenendael',
 '014c2b0cd8e3b517e649cecf8543b8fe': 'african_hunting_dog',
 '0206c12e8984e3c8a166cc272de25d6f': 'chihuahua',
 '021b5a49189665c0442c19b5b33e8cf1': 'entlebucher',
 '023e4e28415506e0deddcbd8f8bdab29': 'pug',
 '02508e76981e1ba059d785704b4c480c': 'pug',
 }
'''

4、计算训练的样本个数以及类别数目

print('samples num',len(labels))
print('classes num',len(set(labels.values())))

'''
samples num 1000
classes num 120
'''

5、定义copy_file函数,创建文件夹,并将源图片地址复制指定文件夹下

def copy_file(fname,target_dir):
    # 创建文件夹,若存在,就不在重复创建
    os.makedirs(name=target_dir,exist_ok=True)
    # 将源图片复制到指定文件夹下
    shutil.copy(fname,target_dir)

6、定义split_copy_train_valid函数,从训练集拆分一部分做验证集,然后复制在指定文件夹下,每个训练集和测试集文件夹下都是每个类的文件夹

def split_copy_trian_valid(data_dir,labels,split_to_valid_ratio): 
    """
    从训练集拆分一部分做验证集,然后复制在指定文件夹下
    """
    split_num = collections.Counter(labels.values()).most_common()[-1][1] # 对类别数目计数,从大到小排列,获取最少的类目 85
    num_valid_per_label = max(1,math.floor(split_num*split_to_valid_ratio)) # 获取从训练集中每一类需要选出多少个样本作为验证集 floor向下取整 8
    valid_label_count = {}
    for train_file in os.listdir(os.path.join(data_dir,'train')):
        # 获取当前图片的label
        label = labels[train_file.split('.')[0]] # eg dog
        # 当前图片的路径
        train_file_path = os.path.join(data_dir,'train',train_file) # eg /train/1.png
        absolute_path = os.path.join(data_dir,'train_valid_test') # /train_valid_test
        # 复制训练集的图片到trian_valid文件夹下
        copy_file(train_file_path,os.path.join(absolute_path,'train_valid',label)) # /train_valid_test/train_valid/dog
        if label not in valid_label_count or valid_label_count[label]<num_valid_per_label:
            # 复制训练集的图片到valid文件夹下
            copy_file(train_file_path,os.path.join(absolute_path,'valid',label)) # /train_valid_test/valid/dog
            valid_label_count[label] = valid_label_count.get(label,0)+1 # 统计分类数据中每个类别的出现次数
        else:
            # 复制训练集的图片到train文件夹下
            copy_file(train_file_path,os.path.join(absolute_path,'train',label)) # /train_valid_test/train/dog
    return num_valid_per_label

train_valid为原始数据集为120个类,1000张图片,train文件夹为训练集,valid文件夹为验证集,以split_to_valid_ratio比率分配数据。

7、定义copy_test函数,复制测试集图片到指定文件夹,而测试集不知道label,所以test文件夹下的类别为unknown

def copy_test(data_dir):
    """
    复制测试集图片到指定文件夹
    """
    for test_file in os.listdir(os.path.join(data_dir,'test')): # 复制测试集图片到test文件夹下
        copy_file(os.path.join(data_dir,'test',test_file),os.path.join(data_dir,'train_valid_test','test','unknown')) # /train_valid_test/test/unknown

8、定义copy_ImageNetDogs_data函数,调用之前的函数

def copy_ImageNetDogs_data(data_dir,split_to_valid_ratio):
    labels = read_csv_data(os.path.join(data_dir,'labels.csv'))
    split_copy_train_valid(data_dir,labels,split_to_valid_ratio)
    copy_test(data_dir)

9、定义batch_size,split_to_valid_ratio,并调用copy_ImageNetDogs_data函数

batch_size = 32 if demo else 128

split_to_valid_ratio = 0.1
copy_ImageNetDogs_data(data_dir,split_to_valid_ratio)

10、图像增广

train_augs = torchvision.transforms.Compose([
    torchvision.transforms.RandomResizedCrop(224,scale=(0.08,1.0),ratio=(3.0/4.0,4.0/3.0)),
    torchvision.transforms.RandomHorizontalFlip(),
    torchvision.transforms.ColorJitter(brightness=0.4,contrast=0.4,saturation=0.4,hue=0.4),
    torchvision.transforms.ToTensor(),
    torchvision.transforms.Normalize([0.485,0.456,0.406],[0.229,0.224,0.225])
])

test_augs = torchvision.transforms.Compose([
    torchvision.transforms.Resize(256),
    torchvision.transforms.CenterCrop(224),
    torchvision.transforms.ToTensor(),
    torchvision.transforms.Normalize([0.485,0.456,0.406],[0.229,0.224,0.225])
])

11、加载数据集

train_datasets,train_valid_datasets = [torchvision.datasets.ImageFolder(
    root=os.path.join(data_dir,'train_valid_test',folder),transform=train_augs
) for folder in ['train','train_valid']]

test_datasets,valid_datasets = [torchvision.datasets.ImageFolder(
    root=os.path.join(data_dir,'train_valid_test',folder),transform=test_augs
) for folder in ['test','valid']]

12、总训练集个数1000个样本,从训练集分割出来的训练集880个样本,验证集120个样本,测试集10个样本

len(train_datasets),len(train_valid_datasets),len(test_datasets),len(valid_datasets)

'''
(880, 1000, 10, 120)
'''

13、创建数据迭代器

train_iter,train_valid_iter = [DataLoader(dataset=ds,batch_size=batch_size,shuffle=True,drop_last=True) for ds in [train_datasets,train_valid_datasets]]

test_iter = DataLoader(dataset=test_datasets,batch_size=batch_size,shuffle=False,drop_last=False)

valid_iter = DataLoader(dataset=valid_datasets,batch_size=batch_size,shuffle=False,drop_last=True)

14、定义get_net函数,定义resnet34模型,并设置除输出层以外的其它层的权重参数梯度为False

def get_net(devices):
    finetunning_net = nn.Sequential()
    finetunning_net.features = torchvision.models.resnet34(pretrained=True)
    # 定义一个新的输出网络,共有120个输出类别
    finetunning_net.output_layer = nn.Sequential(nn.Linear(in_features=1000,out_features=256),nn.ReLU(),nn.Linear(in_features=256,out_features=120))
    finetunning_net = finetunning_net.to(devices[0])
    # 设置除输出层以外的其它层的权重参数梯度为False
    for param in finetunning_net.features.parameters():
        param.requires_grad = False
    return finetunning_net

15、定义损失函数

loss = nn.CrossEntropyLoss(reduction='none') # 每个样本的损失值而不是整体的平均损失

16、定义evaluate_loss函数,计算整体数据集上的平均损失

def evaluate_loss(data_iter,net,device):
    """
    整体数据集上的平均损失
    """
    loss_sum,num = 0.0,0
    for X,y in data_iter:
        X = X.to(device)
        y = y.to(device)
        y_hat = net(X)
        loss_sum += loss(y_hat,y).sum() # 每批所有样本的总损失
        num += y.numel() # 当前批次的样本个数
    return (loss_sum/num).to('cpu')

17、定义train函数,进行训练

def train(net,train_iter,valid_iter,num_epochs,lr,weight_decay,lr_period,lr_decay,devices):
    # 只迭代输出网络的参数
    optimizer = torch.optim.SGD((param for param in net.parameters() if param.requires_grad),lr=lr,momentum=0.9,weight_decay=weight_decay)
    lr_scheduler = torch.optim.lr_scheduler.StepLR(optimizer=optimizer,step_size=lr_period,gamma=lr_decay)
    timer,num_batches = d2l.Timer(),len(train_iter)
    legend = ['train loss']
    if valid_iter is not None:
        legend.append('valid loss')
    animator = d2l.Animator(xlabel='epoch',xlim=[1,num_epochs],legend=legend)
    net = nn.DataParallel(module=net,device_ids=devices).to(devices[0])
    for epoch in range(num_epochs):
        metric = d2l.Accumulator(2)
        net.train()
        for i,(X,y) in enumerate(train_iter):
            timer.start()
            optimizer.zero_grad()
            X,y = X.to(devices[0]),y.to(devices[0])
            y_hat = net(X)
            l_sum = loss(y_hat,y).sum()
            l_sum.backward()
            optimizer.step()
            metric.add(l_sum,y.shape[0])
            timer.stop()
            if i%(num_batches//5)==0 or i == num_batches-1:
                animator.add(epoch+(i+1)/num_batches,(metric[0]/metric[1],None))
        net.eval()
        messages = f'train loss {metric[0]/metric[1]}'
        if valid_iter is not None:
            valid_loss = evaluate_loss(valid_iter,net,devices[0])
            animator.add(epoch+1,(None,valid_loss.detach().cpu()))
            messages += f'valid loss {valid_loss:.3f}'
        lr_scheduler.step()
    print(messages+f'\n{num_epochs*metric[1]/timer.sum():.1f} example/sec,on{str(devices[0])}')

17、调整学习率等参数,进行训练

lr,weight_decay,epochs = 1e-4,1e-4,10
lr_decay,lr_period,devices = 0.9,2,d2l.try_all_gpus()
net = get_net(devices)
train(net,train_iter,valid_iter,epochs,lr,weight_decay,lr_period,lr_decay,devices)

18、在测试集上进行分类

注:此时输出并不是概率最大的类,而是将每个类别的预测概率输出

net = get_net(devices)
train(net,train_valid_iter,None,epochs,lr,weight_decay,lr_period,lr_decay,devices)
preds = []
for X,_ in test_iter:
    X = X.to(devices[0])
    output = torch.nn.functional.softmax(net(X),dim=-1)
    preds.extend(output.cpu().detach().numpy())

indexs = sorted(os.listdir(os.path.join(data_dir,'train_valid_test','test','unknown')))
with open('submission.csv','w') as f:
    f.write('id,'+','.join(train_valid_datasets.classes)+'\n')
    for id,pred in zip(indexs,preds):
        f.write(id.split('.')[0]+','+','.join([str(num) for num in pred])+'\n')

19、输出每个id的预测类别概率

import pandas as pd
pd.read_csv('submission.csv')

物体检测和数据集

物体检测

图像分类是在图片中只有一个主要物体对象,识别主要物体对象的类别;而目标检测是在一张图片中识别多种物体,找到在图片中的具体位置,在图片中利用方框表示。

目标检测可以应用的地方很多,比如无人驾驶,可以去识别图像中的车辆,行人等障碍物的位置。

目标检测可以使用边缘框来描述图片中的位置,边缘框是一个矩形,边缘框可以使用四个数字来表示,常用两种表示方法

第一种方式 利用图片左上角的坐标和右下角的坐标

第二种方式 利用图片中心的坐标和图片的宽和高

对于 x 轴来说,向右为 x 轴的正方向,即 x 的值从左到右依次增大

对于 y 轴来说,向下为 y 轴的正方向,y 的值从上到下依次增大

边缘框的代码实现

1、展示图片

%matplotlib inline
import torch
from d2l import torch as d2l

d2l.set_figsize()
img = d2l.plt.imread('../img/catdog.jpg')
d2l.plt.imshow(img)

2、从(左上、右下)转化到(中间、宽度、高度)的边界框

def box_corner_to_center(boxes):
    """
    从(左上、右下)转化到(中间、宽度、高度)
    """
    x1,y1,x2,y2 = boxes[:,0],boxes[:,1],boxes[:,2],boxes[:,3]
    cx = (x1+x2) / 2
    xy = (y1+y2) / 2
    w = x2 - x1
    h = y2 - y1
    boxes = torch.stack((cx,xy,w,h),axis=-1)
    return boxes

3、转化到左上,右下的边界框

def box_center_to_corner(boxes):
    cx,cy,w,h = boxes[:,0],boxes[:,1],boxes[:,2],boxes[:,3]
    x1 = cx - 0.5*w
    y1 = cy - 0.5*h
    x2 = cx + 0.5*w
    y2 = cy + 0.5*h
    boxes = torch.stack((x1,y1,x2,y2),axis=-1)
    return boxes

4、图片中狗和猫的左上和右下的坐标

dog_bbox,cat_bbox = [60.0,45.0,378.0,516.0],[400.0,112.0,655.0,493.0]

5、验证

boxes = torch.tensor((dog_bbox,cat_bbox))
box_center_to_corner(box_corner_to_center(boxes)) == boxes

'''
tensor([[True, True, True, True],
        [True, True, True, True]])
'''

6、定义函数bbox_to_rect,设置边界框位置

def bbox_to_rect(bbox,color):
    return d2l.plt.Rectangle(
        xy=(bbox[0],bbox[1]),width=bbox[2]-bbox[0],height=bbox[3]-bbox[1],fill=False,edgecolor=color,linewidth=2
    )

7、在图片中标出边界框

fig = d2l.plt.imshow(img)
fig.axes.add_patch(bbox_to_rect(dog_bbox,'blue'))
fig.axes.add_patch(bbox_to_rect(cat_bbox,'red'))

数据集的代码实现

1、引入相关的模块

import torch
import os
import pandas as pd
import torchvision
from d2l import torch as d2l
from torch.utils import data

2、下载数据集

d2l.DATA_HUB['banana-detection'] = (
    d2l.DATA_URL + 'banana-detection.zip',
    '5de26c8fce5ccdea9f91267273464dc968d20d72')
    
data_dir = d2l.download_extract('banana-detection')
print(data_dir)

'''
../data/banana-detection
'''

数据集分为bananas_train和bananas_val

labels.csv格式如下

4、读取香蕉检测数据集

def read_data_bananas(data_dir,is_train=True):
    csv_fname = os.path.join(data_dir,'bananas_train' if is_train else 'bananas_val','label.csv')
    csv_data = pd.read_csv(csv_fname)
    csv_data = csv_data.set_index('img_name')
    images,targets = [],[]
    for image_name,target in csv_data.iterrows():
        images.append(torchvision.io.read_image(path=os.path.join(data_dir,'bananas_train' if is_train else 'bananas_val','images',f'{image_name}')))
        targets.append(list(target))
    # 将targets列表转换为pytorch张量,在第一维度上增加一个维度,将标签值除以256进行归一化处理
    return images,torch.tensor(targets).unsqueeze(1)/256 

images,targets = read_data_bananas(data_dir)

len(images)
'''
1000
'''
targets.shape
'''
torch.Size([1000, 1, 5]) 1000个样本,每个样本中有1个检测目标,每个检测目标有5个相关的位置信息
'''

5、加载香蕉检测数据集的自定义数据集

class BananasDataset(data.Dataset):
    def __init__(self,is_train):
        self.features,self.labels = read_data_bananas(data_dir,is_train)
    def __getitem__(self,item):
        return (self.features[item].float(),self.labels[item])
    def __len__(self):
        return len(self.features)

6、加载香蕉检测数据集

def load_data_bananas(batch_size):
    train_iter = data.DataLoader(dataset=BananasDataset(is_train=True),batch_size=batch_size,shuffle=True)
    val_iter = data.DataLoader(dataset=BananasDataset(is_train=False),batch_size=batch_size,shuffle=False)
    return train_iter,val_iter

7、读取一个小批量,打印其中的图像和标签的形状

batch_size,edge_size = 32,256
train_iter,val_iter = load_data_bananas(batch_size=batch_size)
batch = next(iter(train_iter))
batch[0].shape,batch[1].shape

'''
(torch.Size([32, 3, 256, 256]), torch.Size([32, 1, 5]))
batch[0]为一个批量的图片,批量大小为32,通道数为3,每个图片大小256*256
batch[1]为一个批量的标签,批量大小为32,每个标签的检测目标为1个,标签被长度为5的数组表示,5个相关的位置信息
'''

注:

  • 读取小批量的时候,图像的小批量的形状为(批量大小、通道数、高度、宽度),与图像分类任务中的相同
  • 标签的小批量的形状为(批量大小,m,5)
    • 其中m为 数据集的任何图像中边界框可能出现的最大数量 ,检测目标
    • 5为 每个边界框的标签将被长度为5的数组表示,数组第一个元素是边界框中对象的类别,其余的4个元素是边界框左上角和右下角的坐标值,左上角和右下角的位置信息

8、进行打印

# 把每个像素点的RGB三色从0-255缩放到0-1,方便网络读入训练
# 进行维度重排,将张量的维度从 (batch_size, channels, height, width) 调整为 (batch_size, height, width, channels),show_images 函数需要最后一个维度是通道数。
imgs = (batch[0][0:10].permute(0,2,3,1))/255
axes = d2l.show_images(imgs,2,5,scale=2)

for axe,label in zip(axes,batch[1][0:10]):
    d2l.show_bboxes(axe,bboxes=[label[0][1:5]*edge_size],colors=['r'])

锚框

大部分的目标检测算法是基于锚框的,在输入图像中采样大量的区域,判断区域中是否包含目标,并调整区域边界从而更加准确的预测真实的边缘框。

  • 基于锚框的目标检测算法,是以每个像素为中心,生成多个缩放比和宽高比的不同边界框,锚框是算法预测的边框,是对物体真实位置的预测,而边缘框是真实标签所处区域的边框,是真实物体的位置。
  • 并且基于锚框的目标检测算法提出多个称为锚框的区域(边缘框),并预测每个锚框中是否包含有关注的物体,如果有的话,预测这个锚框到真实边缘框的便宜。

IoU是用来计算两个框之间的相似度的,是两个框的交集与两个框的并集的比值

Intersection为两个框的交集,Union为两个框的并集

IoU计算后的取值范围在0和1之间,其中0表示两个框没有重叠,1表示两个框重合,所以越接近1,两个框的相似度越高。

  • 在训练过程中,每个锚框是一个训练样本,我们需要每个锚框的类别和与真实边缘框的偏移量;在预测过程中,为每个图像生成多个锚框,并预测所有锚框的类别和偏移量,根据预测的偏移量来调整锚框的位置,最后获得符合条件的预测边缘框。
  • 对于每个锚框,要么标注为背景,要么关联上一个真实的边缘框,对于标注为背景的锚框是锚框内不包含我们所关注的物体,只包含背景。
  • 基于锚框的目标检测算法会生成大量的锚框,并且绝大部分锚框都是标注为背景,所以会导致产生大量的负类样本,负类样本就是标注为背景的锚框。
  • 并且在目标检测算法的训练集中会包含每个物体类别的标签,以及真实边缘框的位置,所以要标记所生成的锚框,可以参考分配到最接近此锚框的真实边缘框的位置和类别标签。

赋予锚框编号的做法:

如下图的矩阵,表示有4个真实的边缘框,和9个生成的锚框,矩阵的每个元素都是一个锚框与一个边缘框的IoU,然后将整个矩阵中的最大IoU值挑选出来,假设是x23(它是锚框2与边缘框3的IoU,也是矩阵中最大的IoU),那么就会将边缘框3中的标号给锚框2,并删除x23所在的行和列的其他值,因为锚框2与边缘框3已经匹配成功了。

紧接着,在删除矩阵最大IoU值所在的行和列后,在剩下的矩阵元素中寻找最大IoU值,假设是x71,那么会跟上述相同,将锚框7与边缘框1关联起来,删除x71所在的行和列的其他值。

根据上述操作,重复进行,直到所有的边缘框与对应的锚框管理起来。

我们可以使用非极大值抑制(NMS)进行输出

  • 在预测过程中,会为图像生成多个锚框,每个锚框可以预测一个边缘框,每个边缘框至少有一个锚框,而不是只有一个,因此会有多个相似的锚框围绕着同一个目标,我们需要对这些相似的框进行剔除,最终保留下来比较干净的预测输出结果。
  • NMS的方法是首先选择所有预测框中非背景类的最大预测值,然后去掉所有其它和它IoU值大于theta的预测值,去掉和最大预测值相似度比较高的锚框,重复这个过程,直到所有的预测框要么被选中,要么被去掉,得到一个比较干净的输出。

如下图所示

总结

Meta Learning(元学习)

Meta Learning 称为元学习,Machine Learning 是让机器能够学习,Meta Learning 是让机器学会如何去学习

如下图所示

  • Machine Learning 是寻找一个函数,计算损失函数,进行优化,进而得到更好的函数模型,可以进行图片的分类等等任务。
  • 由人类设计一套学习算法,训练得到算法里面的参数,参数拟合出一个最优的模型,再继续用测试资料来测试这个模型。

  • Meta Learning与之不同的是,由人来设计学习方法的过程,比如学习率的调整,神经网络的调整,这些由机器来进行设计一套学习方法。
  • Meta Learning是要找到一个Function通过训练样本让机器自动学习原来人为确定的一些超参数,通过训练样本训练出来一个学习算法,再生成一个分类器,并进行测试,简单来说,通过Meta Learning训练出来我们之前Machine Learning的函数,再利用函数进行预测和分类。

Meta Learning的步骤

一、Meta Learning需要学习的部分定义为φ,则Function 为Fφ,Function并不是像Machine Learning那样针对特定任务的,而是针对一群类似的任务,包括猫和狗的分类、橘子和苹果的分类等等,而Function就是要在这一群类似的任务中找到一个好的超参数,下次遇到这些相似任务,可以直接利用初始化参数。

二、Meta Learning需要定义损失函数来确定学习算法Function,但是与Machine Learning不同的是,Machine Learning 的损失函数是在训练集进行计算的,而Meta Learning并不是只有训练集和测试集,它分为训练任务和测试任务,训练任务中分为多个任务,有苹果和橘子的分类,有自行车和汽车的分类等等,训练任务中分为多个任务,每个任务中有训练集和测试集。

Meta Learning中的训练任务中有多个任务,它的损失函数首先在训练任务的训练集上进行训练,得到学习算法Function,在进行生成任务1的算法分类器,在训练任务1的测试集上进行测试,通过比较其真实值,计算Cross-entropy,从而得到训练任务1的损失函数,当然,损失函数值越小,代表这个分类器越好,学习算法也越好。

扩展来说,刚才我们计算了训练任务1的损失函数,训练任务中会有多个任务,通过我们的学习算法Function,我们可以去计算后面任务的分类器,并如训练任务1的步骤一样,在训练任务中的测试集进行测试,计算损失函数,所以最后总的损失函数是每个训练任务的损失函数的和。

三、通过Meta Learning学得学习算法的第二步,我们已经得到了训练任务的损失函数,现在我们可以仿照之前Machine Learning的步骤,进行求得使损失函数最小的φ值-> φ*,如果我们可以去计算损失函数对参数φ的偏导数,那么我们可以利用我们最熟悉的Gradient Descent(梯度下降)方法进行求得我们的最优解;若损失函数Fφ对φ求不了偏导,参数φ可能是神经网络等参数,我们可以利用Reinforcement Learning或者Evolutionary Algotithm来求得我们的最优解(这两个算法目前还不太了解,后续会补),现在已经有了我们的求得最优解的φ*得到的学习算法Fφ*。

通过上面的步骤,我们已经学习到了最优的学习算法,注意我们是通过训练任务中的训练集和测试集学习到的算法,相当于Machine Learning的训练集,现在我们将我们学习到的学习算法应用到测试任务的训练集,得到相应的分类器,在利用测试任务中的测试集进行测试和预测。

我们要知道Meta Learning分为训练任务和测试任务,它们都各自有训练集和测试集,我们真正关心的是我们的测试任务。

Meta Learning与Machine Learning的不同点

目标:机器学习的目标是找到一个函数f,可以对图片进行分类;而元学习的目标是找到函数f的函数F,让机器学会如何去学习,通过函数F大量的训练样本的训练,得到最优的函数f,最终可以更好的对图片分类。

训练的数据:机器学习的训练数据是训练集,也就是一个任务,里面包含猫或者狗,对它们进行训练;元学习的训练数据是训练任务,里面包含多个任务,每个任务中有训练集和测试集,当然,为了避免重复,也把元学习的训练任务中的训练集叫做Support Set,测试集叫做Query Set。

对于机器学习,仅仅是通过训练得到的函数模型,通过测试集进行预测;而元学习则是通过训练任务得到的函数模型,它是学习算法的函数,再通过测试任务的训练集进行训练得到分类器,再对测试任务的训练集进行测试。

机器学习的训练过程叫做Within-task Training,测试过程叫做Within-task Testing;元学习的训练过程叫做Across-task Training,测试过程叫做Across-task Testing,每个训练过程中又包含Within-task Training和Within-task Testing。

注:一般把多任务的训练Across-task Training叫做Outer Loop,Within-task Training叫做Inner Loop。

Meta Learning与Machine Learning的共同点

  • 机器学习与元学习都是有很大概率会遇到过拟合问题,在训练的任务中的精度很好,但是在测试的任务中精度很低。
  • 机器学习与元学习遇到过拟合问题,依然可以去增加测试的任务来提高模型的精度,减少过拟合现象。
  • 虽然元学习是来学习学习算法,学习机器学习函数的算法,但是我们依然要进行调整元学习的超参数,但是这属于一劳永逸,下次遇到这些相似任务,可以直接利用初始化参数。
  • 并且元学习依然可以像机器学习那样利用验证集合来调整参数。

个人总结

本周主要学习了深度学习中用于物体检测的方法和理论,以及论文中元学习的一些内容,下周将继续学习其他的一些模型算法和理论知识,并且阅读相应的文献,理论与实践相结合。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值