马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
迁徙学习
标题1.什么是迁徙学习
迁徙学习(Transfer Learning)是一种呆板学习方法,就是把为使命 A 开发 的模子作为初始点,重新利用在为使命 B 开发模子的过程中。迁徙学习是通过 从已学习的相干使命中转移知识来改进学习的新使命,固然大多数呆板学习算 法都是为了办理单个使命而计划的,但是促进迁徙学习的算法的开发是呆板学 习社区一连关注的话题。 迁徙学习对人类来说很常见,比方,我们可能会发现 学习辨认苹果可能有助于辨认梨,大概学习弹奏电子琴可能有助于学习钢琴。
找到目的题目的相似性,迁徙学习使命就是从相似性出发,将旧范畴 (domain)学习过的模子应用在新范畴上
标题2.迁徙学习的步骤
1、选择预练习的模子和适当的层
通常,我们会选择在大规模图像数据集(如ImageNet)上预练习的模子,如VGG、ResNet等。然后,根据新数据集的特点,选择必要微调的模子层。对于低级特征的使命(如边缘检测),最好利用浅层模子的层,而对于高级特征的使命(如分类),则应选择更深条理的模子。
2、冻结预练习模子的参数
保持预练习模子的权重稳定,只练习新增长的层大概微调一些层,避免由于在数据集中过拟合导致预练习模子过分拟合。
3、在新数据集上练习新增长的层
在冻结预练习模子的参数情况下,练习新增长的层。如许,可以使新模子顺应新的使命,从而得到更高的性能。
4、微调预练习模子的层
在新层上举行练习后,可以解冻一些已经练习过的层,而且将它们作为微调的目的。如许做可以进步模子在新数据集上的性能。
5、评估和测试
在练习完成之后,利用测试集对模子举行评估。如果模子的性能仍然不够好,可以实验调解超参数大概更改微调层。
标题3.迁徙学习实例
该实例利用的模子是ResNet-18残差神经网络模子
###1. 导入必要的库
- 在import torch
- import torchvision.models as models
- from torch import nn
- from torch.utils.data import Dataset,DataLoader
- from torchvision import transforms
- from PIL import Image
- import numpy as np
复制代码 这里导入了后续代码会用到的库,具体如下:
torch:PyTorch 深度学习框架的焦点库。
torchvision.models:包罗了预练习的模子,这里会用到 ResNet-18。
torch.nn:用于构建神经网络的模块。
torch.utils.data.Dataset 和 torch.utils.data.DataLoader:用于自界说数据集和加载数据。
torchvision.transforms:用于图像的预处理惩罚。
PIL.Image:用于读取图像。
numpy:用于数值盘算。
###2. 加载预练习模子并修改全连接层
- resnet_model= models.resnet18(weights=models.ResNet18_Weights.DEFAULT)
- for param in resnet_model.parameters():
- print(param)
- param.requires_grad=False
- in_features=resnet_model.fc.in_features
- resnet_model.fc=nn.Linear(in_features,20)
- params_to_update=[]
- for param in resnet_model.parameters():
- if param.requires_grad==True:
- params_to_update.append(param)
复制代码 加载预练习的 ResNet-18 模子。
把模子中全部参数的 requires_grad 设置为 False,也就是冻结这些参数,使其在练习时不更新。
获取原模子全连接层的输入特征数,然后将全连接层更换为一个新的全连接层,输出维度为 20。
网络全部 requires_grad 为 True 的参数,这些参数会在练习时更新。
###3. 界说图像预处理惩罚变换
- data_transforms = {
- 'train':
- transforms.Compose([
- transforms.Resize([300,300]),
- transforms.RandomRotation(45),
- transforms.CenterCrop(224),
- transforms.RandomHorizontalFlip(p=0.5),
- transforms.RandomVerticalFlip(p=0.5),
- transforms.RandomGrayscale(p=0.1),
- transforms.ToTensor(),
- transforms.Normalize([0.485,0.456,0.406],[0.229,0.224,0.225])
- ]),
- 'valid':
- transforms.Compose([
- transforms.Resize([224,224]),
- transforms.ToTensor(),
- transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
- ]),
- }
复制代码 界说了两个图像预处理惩罚的组合变换,分别用于练习集和验证集。
练习集的变换包罗了数据增强操纵,像随机旋转、程度翻转、垂直翻转等。
验证集的变换只包罗了调解巨细、转换为张量和标准化操纵。
4. 自界说数据集类
- class food_dataset(Dataset):
- def __init__(self,file_path,transform=None):
- self.file_path = file_path
- self.imgs = []
- self.labels = []
- self.transform = transform
- with open(self.file_path) as f:
- samples = [x.strip().split(' ') for x in f.readlines()]
- for img_path,label in samples:
- self.imgs.append(img_path)
- self.labels.append(label)
- def __len__(self):
- return len(self.imgs)
- def __getitem__(self, idx):
- image = Image.open(self.imgs[idx])
- if self.transform:
- image = self.transform(image)
- label = self.labels[idx]
- label = torch.from_numpy(np.array(label,dtype=np.int64))
- return image,label
复制代码 自界说了一个 food_dataset 类,继承自 torch.utils.data.Dataset。 init 方法:分析包罗图像路径和标签的文本文件,把图像路径和标签分别存到 self.imgs 和 self.labels 中。
len 方法:返回数据集的巨细。
getitem 方法:根据索引读取图像,对图像举行预处理惩罚,将标签转换为张量,然后返回图像和标签。
5. 创建数据集和数据加载器
- training_data = food_dataset(file_path='./trainbig.txt',transform=data_transforms['train'])
- test_data = food_dataset(file_path='./testbig.txt',transform=data_transforms['valid'])
- train_dataloader = DataLoader(training_data,batch_size=64,shuffle=True)
- test_dataloader = DataLoader(test_data,batch_size=64,shuffle=True)
复制代码 创建练习集和测试集的数据集对象。
创建练习集和测试集的数据加载器,设置批量巨细为 64,而且打乱数据
###6. 设置练习装备、丧失函数、优化器和学习率调理器
- device = "cuda" if torch.cuda.is_available() else "mps" if torch.backends.mps.is_available() else "cpu"
- print(f"Using {device} device")
- model=resnet_model.to(device)
- loss_fn = nn.CrossEntropyLoss()
- optimizer = torch.optim.Adam(params_to_update,lr=0.001)
- scheduler=torch.optim.lr_scheduler.StepLR(optimizer,step_size=5,gamma=0.5)
复制代码 选择符合的练习装备(GPU 或 CPU)。
把模子移动到所选装备上。
界说交织熵丧失函数。
界说 Adam 优化器,只对之前网络的必要更新的参数举行优化。
界说学习率调理器,每 5 个 epoch 将学习率乘以 0.5。
###7. 界说练习和测试函数
- def train(dataloader,model,loss_fn,optimizer):
- model.train()
- batch_size_num = 1
- for X,y in dataloader:
- X,y = X.to(device),y.to(device)
- pred = model.forward(X)
- loss = loss_fn(pred,y)
- optimizer.zero_grad()
- loss.backward()
- optimizer.step()
- def test(dataloader, model,loss_fn):
- global best_acc
- size = len(dataloader.dataset)
- num_batches =len(dataloader)
- model.eval()
- test_loss,correct =0,0
- with torch.no_grad():
- for X, y in dataloader:
- X,y = X.to(device),y.to(device)
- pred = model.forward(X)
- test_loss+=loss_fn(pred,y).item()
- correct += (pred.argmax(1) == y).type(torch.float).sum().item()
- test_loss /= num_batches
- correct /= size
- print(f"Test result:\n Accuracy:{(100 * correct)}%, Avg loss: {test_loss}")
- acc_s.append(correct)
- loss_s.append(test_loss)
- if correct>best_acc:
- best_acc=correct
复制代码 train 函数:将模子设置为练习模式,遍历练习数据加载器,盘算丧失,反向传播并更新模子参数。
test 函数:将模子设置为评估模式,遍历测试数据加载器,盘算测试集的精确率和匀称丧失,记录最佳精确率。
8. 练习模子并保存
- epochs = 20
- acc_s = []
- loss_s =[]
- for t in range(epochs):
- print(f"Epoch {t + 1}\n-----------")
- train(train_dataloader, model,loss_fn, optimizer)
- scheduler.step()
- test(test_dataloader,model,loss_fn)
- print('最优训练结果为:',best_acc)
- torch.save(model.state_dict(), 'food_classification_model.pt')
复制代码 练习模子 20 个 epoch。
每个 epoch 竣事后,更新学习率并举行测试。
打印最优练习效果。
保存模子的参数到 food_classification_model.pt 文件中。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |