最新迁移学习_pytorch简单实战_迁移学习 torch(1),2024年最新带你玩转自定义view系列

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

image_dir = 'D:/Notebook/cell\_images'
def imshow(image):
    plt.figure(figsize=(6, 6))
    plt.imshow(image)
    plt.axis('off')
    plt.show()

#可视化一张感染的图
x = Image.open(image_dir + '/Parasitized/C39P4thinF\_original\_IMG\_20150622\_111206\_cell\_84.png')
np.array(x).shape
imshow(x)

定义转换并加载进数据

转换是将一个图形、表达式或函数转换为另一个图形、表达式或函数的过程。

我们需要为训练、测试以及验证数据定义一些转换。值得注意的,可能有的类别图像太少,不够进行转换,为了增加网络识别的图像数量,我们执行所谓的数据增强。

在训练期间,我们随机裁剪、缩放和旋转图像,以便在每个时期,网络会看到同一图像的不同变化,提高实验的准确性。

# Define transforms for the training, validation, and testing sets
train_transforms = transforms.Compose([transforms.RandomResizedCrop(size=256, scale=(0.8, 1.0)),
                                      transforms.RandomRotation(degrees=15),
                                      transforms.ColorJitter(),
                                      transforms.RandomHorizontalFlip(),
                                      transforms.CenterCrop(size=224),  # Image net standards
                                      transforms.ToTensor(),
                                      transforms.Normalize([0.485, 0.456, 0.406],
                                                           [0.229, 0.224, 0.225])
                                      ])

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

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

接下来加载数据集。最简单的方法是用torchvision的dataset.ImageFolder。

加载imageFolder后,我们将数据拆分为20%验证集和10%测试集; 然后将它传递给DataLoader。

它接收一个类似从ImageFolder获得的数据集,并返回批量图像及其相应的标签(可以将改组设置为true以在时期内引入变化)。

# Loading in the dataset

train_data = datasets.ImageFolder(image_dir, transform=train_transforms)

# number of subprocesses to use for data loading
num_workers = 0
# percentage of training set to use as validation
valid_size = 0.2

test_size = 0.1

# obtain training indices that will be used for validation
num_train = len(train_data)
indices = list(range(num_train))
np.random.shuffle(indices)
valid_split = int(np.floor((valid_size) \* num_train))
test_split = int(np.floor((valid_size + test_size) \* num_train))
valid_idx, test_idx, train_idx = indices[:valid_split], indices[valid_split:test_split], indices[test_split:]

print(len(valid_idx), len(test_idx), len(train_idx))

# define samplers for obtaining training and validation batches
train_sampler = SubsetRandomSampler(train_idx)
valid_sampler = SubsetRandomSampler(valid_idx)
test_sampler = SubsetRandomSampler(test_idx)

# prepare data loaders (combine dataset and sampler)
train_loader = torch.utils.data.DataLoader(train_data, batch_size=32, sampler=train_sampler, num_workers=num_workers)
valid_loader = torch.utils.data.DataLoader(train_data, batch_size=32, sampler=valid_sampler, num_workers=num_workers)
test_loader = torch.utils.data.DataLoader(train_data, batch_size=32, sampler=test_sampler, num_workers=num_workers)


5511 2756 19291

模型训练流程

  1. 加载预先训练的模型
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
# pretrained=True will download a pretrained network for us
model = models.densenet121(pretrained=True)

#model

PyTorch以及几乎所有其他深度学习框架,都使用CUDA来有效地计算GPU上的前向和后向传递。

在PyTorch中,我们使用model.cuda()将模型参数和其他张量移动到GPU内存,或者从GPU移回,

import tensorwatch as tw
import os
os.environ["PATH"] += os.pathsep + 'C:/Program Files (x86)/Graphviz2.38/bin'
tw.draw_model(model, [1, 3, 224, 224])

Pytorch网络结构可视化

所需库文件:

  • graphviz
  • tensorwatch
    draw_model函数需要传入三个参数,第一个为model,第二个参数为input_shape,第三个参数为orientation,可以选择’LR’或者’TB’,分别代表左右布局与上下布局。
    统计网络参数

可以通过model_stats方法统计各层的参数情况。

tw.draw_model(model, [1, 3, 224, 224], orientation='LR')

tw.model_stats(model, [1, 3, 224, 224])

  1. 冻结卷积层并使用自定义分类器替换全连接层
#Freezing model parameters and defining the fully connected network to be attached to the model, loss function and the optimizer.
#We there after put the model on the GPUs
for param in model.parameters():
  param.require_grad = False
fc = nn.Sequential(
    nn.Linear(1024, 460),
    nn.ReLU(),
    nn.Dropout(0.4),
    
    nn.Linear(460,2),
    nn.LogSoftmax(dim=1)
    
)
model.classifier = fc
criterion = nn.NLLLoss()
#Over here we want to only update the parameters of the classifier so
optimizer = torch.optim.Adam(model.classifier.parameters(), lr=0.003)
model.cuda()

冻结模型参数允许我们为早期卷积层保留预训练模型的权重,其目的是用于特征提取。

然后我们定义我们的全连接网络,示例代码中是1024。

我们还定义了要使用的激活函数,和有助于通过随机关闭层中的神经元,以强制在剩余节点之间共享信息,来避免过度拟合。

在我们定义了自定义全连接网络之后,我们将其连接到预先训练好的模型的完全连接网络。

接下来我们定义损失函数,优化器,并通过将模型移动到GPU来准备训练模型。

  1. 为特定任务训练自定义分类器

在训练期间,我们遍历每个时期的DataLoader。 对于每个batch,使用标准函数计算损失。

使用loss.backward()方法计算相对于模型参数的损失梯度。

optimizer.zero_grad()负责清除任何累积的梯度,因为我们会一遍又一遍地计算梯度。

optimizer.step()使用具有动量的随机梯度下降(Adam)更新模型参数。

为了防止过度拟合,我们使用一种称为早期停止的强大技术。背后的想法很简单,当验证数据集上的性能开始降低时停止训练。

epochs = 10
valid_loss_min = 0.0
torch.device('cuda')
torch.backends.cudnn.benchmark = True
import time

for epoch in range(epochs):

    start = time.time()

    # scheduler.step()
    model.to(device)
    model.train()

    train_loss = 0.0
    valid_loss = 0.0

    for index, (inputs, labels) in enumerate(train_loader):
        # Move input and label tensors to the default device
        inputs, labels = inputs.cuda(), labels.cuda()
        logps = model(inputs)
        loss = criterion(logps, labels)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        train_loss += loss.item()

    model.eval()

    with torch.no_grad():
        accuracy = 0
        for inputs, labels in valid_loader:
            inputs, labels = inputs.to(device), labels.to(device)
            logps = model.forward(inputs)
            batch_loss = criterion(logps, labels)
            valid_loss += batch_loss.item()
            # Calculate accuracy


![img](https://img-blog.csdnimg.cn/img_convert/774b6fbccc7fee6b3af5bdb6c5c6c93d.png)
![img](https://img-blog.csdnimg.cn/img_convert/8ec4981fe87a15f136a38db46b7552e3.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618668825)**

g-uo2h9IL9-1715881431384)]
[外链图片转存中...(img-cxogT334-1715881431384)]

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618668825)**

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值