乐清门户网站,示范建设验收网站,中国航发网上商城废旧物资,wordpress js代码插件下载地址目录
一、迁移学习
1.什么是迁移学习
2.迁移学习的步骤
1、选择预训练的模型和适当的层
2、冻结预训练模型的参数
3、在新数据集上训练新增加的层
4、微调预训练模型的层
5、评估和测试
二、迁移学习实例
1.导入模型
2.冻结模型参数
3.修改参数
4.创建类#xff…目录
一、迁移学习
1.什么是迁移学习
2.迁移学习的步骤
1、选择预训练的模型和适当的层
2、冻结预训练模型的参数
3、在新数据集上训练新增加的层
4、微调预训练模型的层
5、评估和测试
二、迁移学习实例
1.导入模型
2.冻结模型参数
3.修改参数
4.创建类数据增强导入数据
5.定义训练集和测试集函数
6.将模型传入GPU并有序调整学习率
7.进行训练和测试 一、迁移学习
1.什么是迁移学习 迁移学习是指利用已经训练好的模型在新的任务上进行微调。迁移学习可以加快模型训练速度提高模型性能并且在数据稀缺的情况下也能很好地工作。 2.迁移学习的步骤
1、选择预训练的模型和适当的层 通常我们会选择在大规模图像数据集如ImageNet上预训练的模型如VGG、ResNet等。然后根据新数据集的特点选择需要微调的模型层。对于低级特征的任务如边缘检测最好使用浅层模型的层而对于高级特征的任务如分类则应选择更深层次的模型。 2、冻结预训练模型的参数 保持预训练模型的权重不变只训练新增加的层或者微调一些层避免因为在数据集中过拟合导致预训练模型过度拟合。 3、在新数据集上训练新增加的层 在冻结预训练模型的参数情况下训练新增加的层。这样可以使新模型适应新的任务从而获得更高的性能。 4、微调预训练模型的层 在新层上进行训练后可以解冻一些已经训练过的层并且将它们作为微调的目标。这样做可以提高模型在新数据集上的性能。 5、评估和测试 在训练完成之后使用测试集对模型进行评估。如果模型的性能仍然不够好可以尝试调整超参数或者更改微调层。 二、迁移学习实例
该实例使用的模型是ResNet-18残差神经网络模型 1.导入模型
导入所要用的库加载ResNet18模型
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将resnet18模型迁移到食物分类项目中
resent_model models.resnet18(weightsmodels.ResNet18_Weights.DEFAULT) # 既调用了resnet18网络,又使用了训练好的模型 在这里下载了模型2.冻结模型参数
将导入的模型参数冻结
for param in resent_model.parameters():param.requires_grad False # 设置每个参数的requires_grad属性为False,表示在训练过程中这些参数不需要计算梯度,也就是说它们不会在反向传播中更新。# print(param)
# 模型所有参数(即权重和偏差)的requires_grad属性设置为False,从而冻结所有模型参数
# 使得在反向传播过程中不会计算它们的梯度,以此减少模型的计算量,提高理速度。 3.修改参数
因为我们所用的数据分类是20个原模型分类是1000个所以需要修改全连接层获取原模型输入层的特征个数将原模型的全连接层替换成原输入输出为20的全连接层保存需要训练的参数后面优化器进行优化时就可以只训练该层参数
in_features resent_model.fc.in_features # 获取模型原输入的特征个数
resent_model.fc nn.Linear(in_features, 20) # 创建一个全连接层,输入特征为in_features,输出为20param_to_update [] # 保存需要训练的参数,仅仅包含全连接层的参数
for param in resent_model.parameters():if param.requires_grad True:param_to_update.append(param)4.创建类数据增强导入数据
将图片从本地导入并进行数据增强最后进行打包
class food_dataset(Dataset):def __init__(self, file_path, transformNone): # 类的初始化,解析数据文件txtself.file_path file_pathself.imgs []self.labels []self.transform transformwith open(self.file_path) as f: # 是把train.txt文件中图片的路径保存在 self.imgs,train.txt文件中标签保存在self.label里samples [x.strip().split( ) for x in f.readlines()] # 去掉首尾空格 再按空格分成两个元素for img_path, label in samples:self.imgs.append(img_path) # 图像的路径self.labels.append(label) # 标签,还不是tensor# 初始化:把图片目录加载到selfdef __len__(self): # 类实例化对象后,可以使用len函数测量对象的个数return len(self.imgs)def __getitem__(self, idx): # 关键,可通过索引的形式获取每一个图片数据及标签image Image.open(self.imgs[idx]) # 读取到图片数据,还不是tensorif self.transform:# 将pil图像数据转换为tensorimage self.transform(image) # 图像处理为256x256,转换为tenorlabel self.labels[idx] # label还不是tensorlabel torch.from_numpy(np.array(label, dtypenp.int64)) # label也转换为tensorreturn image, labeldata_transforms {train:transforms.Compose([transforms.Resize([300, 300]),transforms.RandomRotation(45),transforms.CenterCrop(224),transforms.RandomHorizontalFlip(p0.5),transforms.RandomVerticalFlip(p0.5),# transforms.ColorJitter(brightness0.2, contrast0.1, saturation0.1, hue0.1),transforms.RandomGrayscale(p0.1),transforms.ToTensor(),transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) # 为 ImageNet 数据集计算的标准化参数]),test:transforms.Compose([transforms.Resize([224, 224]),transforms.ToTensor(),transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) # 为 ImageNet 数据集计算的标准化参数])
}train_data food_dataset(file_pathrtrainda.txt,transformdata_transforms[train]) # 64张图片为一个包 训练集60000张图片 打包成了938个包
test_data food_dataset(file_pathrtestda.txt, transformdata_transforms[test])train_dataloader DataLoader(train_data, batch_size64, shuffleTrue)
test_dataloader DataLoader(test_data, batch_size64, shuffleTrue)5.定义训练集和测试集函数
def train(dataloader, model, loss_fn, optimizer):model.train() # 告诉模型,我要开始训练,模型中w进行随机化操作,已经更新w.在训练过程中,w会被修改的batch_size_num 1for x, y in dataloader:x, y x.to(device), y.to(device) # 把训练数据集和标签传入CPU或GPUpred model.forward(x) # 向前传播loss loss_fn(pred, y) # 通过交叉熵损失函数计算损失值lossoptimizer.zero_grad() # 梯度值清零loss.backward() # 反向传播计算得到每个参数的梯度值woptimizer.step() # 根据梯度更新网络w参数loss_value loss.item() # 从tensor数据中提取数据出来,tensor获取损失值if batch_size_num % 40 0:print(floss:{loss_value:7f} [number:{batch_size_num}])batch_size_num 1best_acc 0def test(dataloader, model, loss_fn):global best_accsize len(dataloader.dataset)num_batches len(dataloader)model.eval() # 测试,w就不能再更新。test_loss, correct 0, 0with torch.no_grad(): # 一个上下文管理器,关闭梯度计算。当你确认不会调用Tensor.backward()的时候。这可以减少计算所占用的消耗for x, y in dataloader:x, y x.to(device), y.to(device)pred model.forward(x)test_loss loss_fn(pred, y).item() # test loss是会自动累加每一个批次的损失值correct (pred.argmax(1) y).type(torch.float).sum().item()test_loss / num_batches # 能来衡量模型测试的好坏。correct / size # 平均的正确率print(fTest result: \n Accuracy: {(100 * correct)}%, Avg loss: {test_loss}\n)acc_s.append(correct)loss_s.append(test_loss)if correct best_acc: # 保存正确率最大的那一次的模型best_acc correct 6.将模型传入GPU并有序调整学习率
from torch import nndevice cuda if torch.cuda.is_available() else mps if torch.backends.mps.is_avaibale() else cpu
model resent_model.to(device) # 为什么不需要加括号,之前是model CNN().to(device) 因为 resnet_model 是对象不是类有序调整学习率
loss_fn nn.CrossEntropyLoss() # 处理多分类
optimizer torch.optim.Adam(param_to_update, lr0.001) # 仅训练最后一层的参数
scheduler torch.optim.lr_scheduler.StepLR(optimizer, step_size5, gamma0.5) # 调整学习率7.进行训练和测试
选择训练100轮每训练一轮输出测试结果
epchos 100
acc_s []
loss_s []
for t in range(epchos):print(fEpoch {t 1}\n--------------------------)train(train_dataloader, model, loss_fn, optimizer)scheduler.step()test(test_dataloader, model, loss_fn)
print(最优测试结果为:, best_acc)输出