深度学习pytorch编程入门,test5_resnet

预测分为单张预测和多张预测

从训练开始

import os
import sys
import json

import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import transforms, datasets
from tqdm import tqdm

from model import resnet34

def main():
    device=torch.device("cuda:0"if torch.cuda.is_available()else "cpu")
    print("using {} ".format(device))
    data_transforms={
      "train": transforms.Compose([
        transforms.RandomResizedCrop(224),
        transforms.RandomHorizontalFlip(),
        transforms.ToTensor(),
        transforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5))]),
      "val": transforms.Compose([
        transforms.Resize(256),
        transforms.CenterCrop(224),
        transforms.ToTensor(),
        transforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5))

    ])}

    data_root=os.path.abspath(os.path.join(os.getcwd(),"../.."))
    image_path=os.path.join(data_root,"data_set","flower_data")
    assert os.path.exists(image_path),"{} is not exists".format(image_path)
    train_dataset=datasets.ImageFolder(root=os.path.join(image_path,"train"),
                                       transform=data_transforms["train"])
    val_dataset=datasets.ImageFolder(root=os.path.join(image_path,"val"),
                                     transform=data_transforms["val"]
                            )
    train_num=len(train_dataset)
    val_num=len(val_dataset)


    flower_list=train_dataset.class_to_idx
    cla_dict=dict((val,key)for val,key in flower_list.items())

    json_str=json.dumps(cla_dict,indent=4)
    with open("class_indices.json","w") as f:
        f.write(json_str)

    batch_size=16
    nw = min([os.cpu_count(), batch_size if batch_size > 1 else 0, 8])
    train_loader=torch.utils.data.Dataloader(
        train_dataset,batch_size=batch_size,shuffle=True,num_workers=nw
    )
    val_loader=torch.utils.data.Dataloader(val_dataset,
                                           batch_size=batch_size,
                                           shuffle=False,
                                           num_workers=nw)
    net=resnet34()
    model_weight_path="./resnet34-pre.pth"
    assert os.path.exists(model_weight_path),"{} is not exist".format(model_weight_path)
    net.load_state_dict(torch.load(model_weight_path,map_location="cpu"))
    in_channel=net.fc.in_features
    net.fc=nn.Linear(in_channel,5)
    net.to(device)
    loss_fuction=nn.CrossEntropyLoss()
    param=[p for p in net.parameters() if p.requires_grad]
    optimizer=optim.Adam(param,lr=0.0001)
    epochs=30
    best_acc=0.0
    save_path = './resNet34.pth'
    train_steps=len(train_loader)
    for epoch in range(epochs):
        net.train()
        running_loss=0.0
        train_bar=tqdm(train_loader,file=sys.stdout)
        for step, data in enumerate(train_bar):
            images,labels=data
            optimizer.zero_grad()
            logits=net(images.to(device))
            loss=loss_fuction(logits,labels.to(device))
            loss.backward()
            optimizer.step()
            running_loss=running_loss+loss.item()
        net.eval()
        acc=0.0
        with torch.no_grad():
            val_bar=tqdm(val_loader,file=sys.stdout)
            for val_data in val_bar:
                val_images,val_labels=val_data
                output=net(val_images.to(device))
                predict_y=torch.max(output,dim=1)[1]
                acc=acc+torch.eq(predict_y,labels.to(device)).sum().item()
        val_acc=acc/val_num
        
        if val_acc>best_acc:
            best_acc=val_acc
            torch.save(net.state_dict(),save_path)

考虑预训练

model_path="./resnet34-pre.pth"

assert os.path.exists(model_weight_path),"{} is not exist".format(model_weight_path)

net.load_state_dict(torch.load(model_paht,map_loaction="cpu")

in_channel=net.fc.in_features

net.fc=nn.Linear(in_channel,5)

多张图片预测

import os
import json

import torch
from PIL import Image
from torchvision import transforms

from model import resnet34

def main():
    device=torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
    data_transform=transforms.Compose([
        transforms.Resize(256),
        transforms.CenterCrop(224),
        transforms.ToTensor(),
        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
    ])
    imgs_root = "/data/imgs"
    assert os.path.exists(imgs_root), f"file: '{imgs_root}' dose not exist."
    img_path_list=[os.path.join(imgs_root,i) for i in os.listdir(imgs_root)]
    json_path="./class_indices.json"
    json_file=open(json_path,"r")
    class_indict=json.load(json_file)
    model=resnet34(num_classes=5).to(device)
    weight_path= "./resNet34.pth"
    model.load_state_dict(torch.load(weight_path,map_location=device))
    model.eval()
    batch_size=8
    with torch.no_grad():
        for ids in range(0,len(img_path_list)//batch_size):
            img_list=[]
            for img_path in img_path_list[ids *batch_size:(ids+1)*batch_size]:
                img=Image.open(img_path)
                img=data_transform(img)
                img.list.append(img)
            
            batch_size=torch.stack(img_list,dim=0)
            output=model(batch_size.to(device)).cpu()
            predict=torch.softmax(output,dim=1)
            probs,classes=torch.max(predict,dim=1)
            

单张图片预测

import os
import json

import torch
from PIL import Image
from torchvision import transforms
import matplotlib.pyplot as plt

from model import resnet34

def main():
    device=torch.device("cuda :0"if torch.cuda.is_available() else "cpu")
    
    data_transform=transforms.Compose(
        [
            transforms.Resize(256),
            transforms.CenterCrop(224),
            transforms.ToTensor(),
            transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
        ]
    )
    
    img_path="../tulip.jpg"
    assert os.path.exists(img_path),"file: '{}' dose not exist.".format(img_path)
    img=Image.open(img_path)
    img=data_transform(img)
    img=torch.unsqueeze(img,dim=0)
    json_path = './class_indices.json'
    assert os.path.exists(json_path), "file: '{}' dose not exist.".format(json_path)
    with open(json_path,"r")as f:
        class_indict=json.load(f)
    
    model=resnet34(num_classes=5).to(device)
    weights_path = "./resNet34.pth"
    assert os.path.exists(weights_path), "file: '{}' dose not exist.".format(weights_path)
    model.load_state_dict(torch.load(weights_path,map_location="cpu"))
    model.eval()
    with torch.no_grad():
        output=model(img.to(device))
        output=torch.squeeze(output).cpu()
        predict=torch.softmax(output,dim=0)
        predict_cla=torch.argmax(predict).numpy()
    print_res="class: {}   prob: {:.3}".format(class_indict[str(predict_cla)],
                                               predict[predict_cla].numpy())
    

’模型

import torch.nn as nn
import torch
class BasicBlock(nn.Module):
    expansion=1
    def __init__(self,in_channel,out_channel,stride=1,downsample=None,**kwargs):
        super(BasicBlock,self).__init__()
        self.conv1 = nn.Conv2d(in_channels=in_channel, out_channels=out_channel,
                               kernel_size=3, stride=stride, padding=1, bias=False)
        self.bn1 = nn.BatchNorm2d(out_channel)
        self.relu = nn.ReLU()
        self.conv2 = nn.Conv2d(in_channels=out_channel, out_channels=out_channel,
                               kernel_size=3, stride=1, padding=1, bias=False)
        self.bn2 = nn.BatchNorm2d(out_channel)
        self.downsample = downsample

    def forward(self, x):
        identity = x
        if self.downsample is not None:
            identity = self.downsample(x)

        out = self.conv1(x)
        out = self.bn1(out)
        out = self.relu(out)

        out = self.conv2(out)
        out = self.bn2(out)

        out += identity
        out = self.relu(out)

        return out


class Bottleneck(nn.Module):
    """
    注意:原论文中,在虚线残差结构的主分支上,第一个1x1卷积层的步距是2,第二个3x3卷积层步距是1。
    但在pytorch官方实现过程中是第一个1x1卷积层的步距是1,第二个3x3卷积层步距是2,
    这么做的好处是能够在top1上提升大概0.5%的准确率。
    可参考Resnet v1.5 https://ngc.nvidia.com/catalog/model-scripts/nvidia:resnet_50_v1_5_for_pytorch
    """
    expansion = 4

    def __init__(self, in_channel, out_channel, stride=1, downsample=None,
                 groups=1, width_per_group=64):
        super(Bottleneck, self).__init__()

        width = int(out_channel * (width_per_group / 64.)) * groups

        self.conv1 = nn.Conv2d(in_channels=in_channel, out_channels=width,
                               kernel_size=1, stride=1, bias=False)  # squeeze channels
        self.bn1 = nn.BatchNorm2d(width)
        # -----------------------------------------
        self.conv2 = nn.Conv2d(in_channels=width, out_channels=width, groups=groups,
                               kernel_size=3, stride=stride, bias=False, padding=1)
        self.bn2 = nn.BatchNorm2d(width)
        # -----------------------------------------
        self.conv3 = nn.Conv2d(in_channels=width, out_channels=out_channel * self.expansion,
                               kernel_size=1, stride=1, bias=False)  # unsqueeze channels
        self.bn3 = nn.BatchNorm2d(out_channel * self.expansion)
        self.relu = nn.ReLU(inplace=True)
        self.downsample = downsample

    def forward(self, x):
        identity = x
        if self.downsample is not None:
            identity = self.downsample(x)

        out = self.conv1(x)
        out = self.bn1(out)
        out = self.relu(out)

        out = self.conv2(out)
        out = self.bn2(out)
        out = self.relu(out)

        out = self.conv3(out)
        out = self.bn3(out)

        out += identity
        out = self.relu(out)

        return out


class ResNet(nn.Module):

    def __init__(self,
                 block,
                 blocks_num,
                 num_classes=1000,
                 include_top=True,
                 groups=1,
                 width_per_group=64):
        super(ResNet, self).__init__()
        self.include_top = include_top
        self.in_channel = 64

        self.groups = groups
        self.width_per_group = width_per_group

        self.conv1 = nn.Conv2d(3, self.in_channel, kernel_size=7, stride=2,
                               padding=3, bias=False)
        self.bn1 = nn.BatchNorm2d(self.in_channel)
        self.relu = nn.ReLU(inplace=True)
        self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
        self.layer1 = self._make_layer(block, 64, blocks_num[0])
        self.layer2 = self._make_layer(block, 128, blocks_num[1], stride=2)
        self.layer3 = self._make_layer(block, 256, blocks_num[2], stride=2)
        self.layer4 = self._make_layer(block, 512, blocks_num[3], stride=2)
        if self.include_top:
            self.avgpool = nn.AdaptiveAvgPool2d((1, 1))  # output size = (1, 1)
            self.fc = nn.Linear(512 * block.expansion, num_classes)

        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')

    def _make_layer(self, block, channel, block_num, stride=1):
        downsample = None
        if stride != 1 or self.in_channel != channel * block.expansion:
            downsample = nn.Sequential(
                nn.Conv2d(self.in_channel, channel * block.expansion, kernel_size=1, stride=stride, bias=False),
                nn.BatchNorm2d(channel * block.expansion))

        layers = []
        layers.append(block(self.in_channel,
                            channel,
                            downsample=downsample,
                            stride=stride,
                            groups=self.groups,
                            width_per_group=self.width_per_group))
        self.in_channel = channel * block.expansion

        for _ in range(1, block_num):
            layers.append(block(self.in_channel,
                                channel,
                                groups=self.groups,
                                width_per_group=self.width_per_group))

        return nn.Sequential(*layers)

    def forward(self, x):
        x = self.conv1(x)
        x = self.bn1(x)
        x = self.relu(x)
        x = self.maxpool(x)

        x = self.layer1(x)
        x = self.layer2(x)
        x = self.layer3(x)
        x = self.layer4(x)

        if self.include_top:
            x = self.avgpool(x)
            x = torch.flatten(x, 1)
            x = self.fc(x)

        return x


def resnet34(num_classes=1000, include_top=True):
    # https://download.pytorch.org/models/resnet34-333f7ec4.pth
    return ResNet(BasicBlock, [3, 4, 6, 3], num_classes=num_classes, include_top=include_top)


def resnet50(num_classes=1000, include_top=True):
    # https://download.pytorch.org/models/resnet50-19c8e357.pth
    return ResNet(Bottleneck, [3, 4, 6, 3], num_classes=num_classes, include_top=include_top)


def resnet101(num_classes=1000, include_top=True):
    # https://download.pytorch.org/models/resnet101-5d3b4d8f.pth
    return ResNet(Bottleneck, [3, 4, 23, 3], num_classes=num_classes, include_top=include_top)


def resnext50_32x4d(num_classes=1000, include_top=True):
    # https://download.pytorch.org/models/resnext50_32x4d-7cdf4587.pth
    groups = 32
    width_per_group = 4
    return ResNet(Bottleneck, [3, 4, 6, 3],
                  num_classes=num_classes,
                  include_top=include_top,
                  groups=groups,
                  width_per_group=width_per_group)


def resnext101_32x8d(num_classes=1000, include_top=True):
    # https://download.pytorch.org/models/resnext101_32x8d-8ba56ff5.pth
    groups = 32
    width_per_group = 8
    return ResNet(Bottleneck, [3, 4, 23, 3],
                  num_classes=num_classes,
                  include_top=include_top,
                  groups=groups,
                  width_per_group=width_per_group)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Sure! Here's an example of PyTorch code for training DeepLabV2 with ResNet101 as the backbone: ```python import torch import torch.nn as nn import torchvision.models as models # Define DeepLabV2 model class DeepLabV2(nn.Module): def __init__(self, num_classes): super(DeepLabV2, self).__init__() self.resnet = models.resnet101(pretrained=True) # Remove the fully connected layer and average pooling layer del self.resnet.fc del self.resnet.avgpool self.conv1 = nn.Conv2d(2048, 256, kernel_size=1) self.conv2 = nn.Conv2d(256, num_classes, kernel_size=1) def forward(self, x): x = self.resnet.conv1(x) x = self.resnet.bn1(x) x = self.resnet.relu(x) x = self.resnet.maxpool(x) x = self.resnet.layer1(x) x = self.resnet.layer2(x) x = self.resnet.layer3(x) x = self.resnet.layer4(x) x = self.conv1(x) x = self.conv2(x) return x # Create an instance of the model num_classes = 21 # Number of classes in the dataset model = DeepLabV2(num_classes) # Define loss function and optimizer criterion = nn.CrossEntropyLoss() optimizer = torch.optim.SGD(model.parameters(), lr=0.001, momentum=0.9) # Training loop for epoch in range(num_epochs): for images, labels in dataloader: optimizer.zero_grad() # Forward pass outputs = model(images) loss = criterion(outputs, labels) # Backward pass and optimization loss.backward() optimizer.step() ``` This code defines the DeepLabV2 model with ResNet101 as the backbone. It removes the fully connected layer and average pooling layer from the ResNet101 model and replaces them with convolutional layers. The model is trained using the CrossEntropyLoss and optimized using stochastic gradient descent (SGD). Please note that this code is a simplified example and may need modification based on your specific dataset and requirements.

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值