365天深度学习训练营-第P6周:好莱坞明星识别

 我的环境:

  • 语言环境:Python3.11.2
  • 编译器:PyCharm Community Edition 2022.3
  • 深度学习环境:torch==2.0,torchvision==0.15.1 

 本次目标

  • 调用官方vgg16模型

 一、前期准备

        将数据集导入。

import torch
import torch.nn as nn
from torchvision import transforms,datasets
from torchvision.models import vgg16
import PIL,pathlib
from torchinfo import summary
import matplotlib.pyplot as plt

data_path='F:\\48-data'
data_path=pathlib.Path(data_path)
data_paths = list(data_path.glob('*'))
classNames = [str(path).split('\\')[2] for path in data_paths]
print(classNames)

'''
['Angelina Jolie', 'Brad Pitt', 'Denzel Washington', 'Hugh Jackman', 'Jennifer Lawrence', 'Johnny Depp', 'Kate Winslet', 'Leonardo DiCaprio', 'Megan Fox', 'Natalie Portman', 'Nicole Kidman', 'Robert Downey Jr', 'Sandra Bullock', 'Scarlett Johansson', 'Tom Cruise', 'Tom Hanks', 'Will Smith']
'''

        处理数据并划分数据集。

train_transforms = transforms.Compose([
    transforms.Resize([224,224]),
    transforms.ToTensor(),
    transforms.Normalize(
        mean=[0.485,0.456,0.406],
        std=[0.229,0.224,0.225]
    )
])

total_data =datasets.ImageFolder(data_path, transform=train_transforms)
print(total_data)
print(total_data.class_to_idx)

train_size = int(0.8*len(total_data))
test_size = len(total_data)-train_size
train_dataset,test_dataset=torch.utils.data.random_split(total_data,[train_size,test_size])
print(train_dataset,test_dataset)
print(train_size,test_size)

batch_size = 32
train_dl = torch.utils.data.DataLoader(train_dataset,batch_size=batch_size,shuffle=True)
test_dl = torch.utils.data.DataLoader(test_dataset,batch_size=batch_size)

二、调用官方vgg16模型

model = vgg16(pretrained=True).to("cpu")
for params in model.parameters():
    params.requires_grad=False
model.classifier._modules['6']=nn.Linear(4096,len(classNames))
summary(model)

        调用官方vgg16模型进行学习。

三、训练模型

        设置超参数。

loss_fn = nn.CrossEntropyLoss()
learn_rate = 1e-3
opt = torch.optim.SGD(model.parameters(),lr=learn_rate)

        编写训练函数和测试函数。

def train(dataloader,model,loss_fn,optimizer):
    size = len(dataloader.dataset)
    num_batchs = len(dataloader)
    train_loss, train_acc = 0, 0
    for X,y in dataloader:
        pred=model(X)
        loss=loss_fn(pred,y)

        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        train_acc+=(pred.argmax(1)==y).type(torch.float).sum().item()
        train_loss+=loss.item()
    train_acc /= size
    train_loss /= num_batchs

    return train_acc,train_loss

def test(dataloader,model,loss_fn):
    size=len(dataloader.dataset)
    num_batchs=len(dataloader)
    test_loss,test_acc=0,0

    with torch.no_grad():
        for imgs,target in dataloader:

            target_pred = model(imgs)
            loss=loss_fn(target_pred,target)
            test_loss+=loss.item()
            test_acc+=(target_pred.argmax(1)==target).type(torch.float).sum().item()

    test_acc /= size
    test_loss /= num_batchs

    return test_acc,test_loss

        正式训练。

epochs=20
train_loss=[]
train_acc=[]
test_loss=[]
test_acc=[]

for epoch in range(epochs):
    model.train()
    epoch_train_acc,epoch_train_loss= train(train_dl,model,loss_fn,opt)
    model.eval()
    epoch_test_acc,epoch_test_loss=test(test_dl,model, loss_fn)
    train_acc.append(epoch_train_acc)
    train_loss.append(epoch_train_loss)
    test_acc.append(epoch_test_acc)
    test_loss.append(epoch_test_loss)

    template = ('Epoch:{:2d},Train_acc:{:.1f}%,Train_loss:{:.3f},Test_acc:{:.1f}%,Test_loss:{:.3f}')
    print(template.format(epoch+1,epoch_train_acc,epoch_train_loss,epoch_test_acc,epoch_test_loss))
print('Done')

四、结果可视化

epochs_range = range(epochs)

plt.figure(figsize=(12,3))
plt.subplot(1,2,1)
plt.plot(epochs_range,train_acc,label='Training Accuracy')
plt.plot(epochs_range,test_acc,label='Test Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')

plt.subplot(1,2,2)
plt.plot(epochs_range,train_loss,label='Training Loss')
plt.plot(epochs_range,test_loss,label='Validation Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()

五、指定图片进行预测 

classes = list(total_data.class_to_idx)
def predict_one_img(image_path, model, transform, classes):
    test_img = PIL.Image.open(image_path).convert('RGB')
    test_img=transform(test_img)
    img = test_img.to('cpu').unsqueeze(0)
    model.eval()
    output = model(img)
    x,pred = torch.max(output,1)
    pred_class=classes[pred]
    print(f'预测结果是{pred_class}')
predict_one_img(image_path='F:\\48-data\\Angelina Jolie\\001_fe3347c0.jpg',model=model,transform=train_transforms,classes=classes)

        保存模型参数

PATH = './model.pth'
torch.save(model.state_dict(),PATH)

model.load_state_dict(torch.load(PATH))

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值