深度学习100例 | 第2例:人脸表情识别 - PyTorch实现
Posted K同学啊
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深度学习100例 | 第2例:人脸表情识别 - PyTorch实现相关的知识,希望对你有一定的参考价值。
大家好,我是K同学啊,今天讲《深度学习100例》PyTorch版的第二个例子,前面一些例子主要还是以带大家了解PyTorch为主,建议手动敲一下代码,只有自己动手了,才能真正体会到里面的内容,光看不练是没有用的。今天的重点是在PyTorch调用VGG-16算法模型。先来了解一下PyTorch与TensorFlow的区别
PyTorch VS TensorFlow:
TensorFlow
:简单,模块封装比较好,容易上手,对新手比较友好。在工业界最重要的是模型落地,目前国内的大部分企业支持TensorFlow模型在线部署,不支持Pytorch。PyTorch
:前沿算法多为PyTorch版本,如果是你高校学生or研究人员,建议学这个。相对于TensorFlow,Pytorch在易用性上更有优势,更加方便调试。
当然如果你时间充足,我建议两个模型都是需要了解一下的,这两者都还是很重要的。
文章目录
🍖 我的环境:
- 语言环境:Python3.8
- 编译器:Jupyter Lab
- 深度学习环境:
- torch==1.10.0+cu113
- torchvision==0.11.1+cu113
- 创作平台:🔗 极链AI云
- 创作教程:🔎 操作手册
一、导入数据
from torchvision.datasets import CIFAR10
from torchvision.transforms import transforms
from torch.utils.data import DataLoader
from torchvision import datasets
from torch.optim import Adam
import torchvision.models as models
import torch.nn.functional as F
import torch.nn as nn
import torch,torchvision
train_datadir = './2-Emotion_Images/train/'
test_datadir = './2-Emotion_Images/test/'
train_transforms = transforms.Compose([
transforms.Resize([48, 48]), # 将输入图片resize成统一尺寸
transforms.ToTensor(), # 将PIL Image或numpy.ndarray转换为tensor,并归一化到[0,1]之间
transforms.Normalize( # 标准化处理-->转换为标准正太分布(高斯分布),使模型更容易收敛
mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225]) # 其中 mean=[0.485,0.456,0.406]与std=[0.229,0.224,0.225] 从数据集中随机抽样计算得到的。
])
test_transforms = transforms.Compose([
transforms.Resize([48, 48]), # 将输入图片resize成统一尺寸
transforms.ToTensor(), # 将PIL Image或numpy.ndarray转换为tensor,并归一化到[0,1]之间
transforms.Normalize( # 标准化处理-->转换为标准正太分布(高斯分布),使模型更容易收敛
mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225]) # 其中 mean=[0.485,0.456,0.406]与std=[0.229,0.224,0.225] 从数据集中随机抽样计算得到的。
])
train_data = datasets.ImageFolder(train_datadir,transform=train_transforms)
test_data = datasets.ImageFolder(test_datadir,transform=test_transforms)
train_loader = torch.utils.data.DataLoader(train_data,
batch_size=16,
shuffle=True,
num_workers=1)
test_loader = torch.utils.data.DataLoader(test_data,
batch_size=16,
shuffle=True,
num_workers=1)
print("The number of images in a training set is: ", len(train_loader)*16)
print("The number of images in a test set is: ", len(test_loader)*16)
print("The number of batches per epoch is: ", len(train_loader))
classes = ('Angry', 'Fear', 'Happy', 'Surprise')
The number of images in a training set is: 18480
The number of images in a test set is: 2320
The number of batches per epoch is: 1155
二、VGG-16算法模型
device = "cuda" if torch.cuda.is_available() else "cpu"
print("Using device".format(device))
# 直接调用官方封装好的VGG16模型
model = models.vgg16(pretrained=True)
model
Using cuda device
VGG(
(features): Sequential(
(0): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(1): ReLU(inplace=True)
(2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(3): ReLU(inplace=True)
(4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(5): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(6): ReLU(inplace=True)
(7): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(8): ReLU(inplace=True)
(9): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(10): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(11): ReLU(inplace=True)
(12): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(13): ReLU(inplace=True)
(14): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(15): ReLU(inplace=True)
(16): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(17): Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(18): ReLU(inplace=True)
(19): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(20): ReLU(inplace=True)
(21): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(22): ReLU(inplace=True)
(23): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(24): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(25): ReLU(inplace=True)
(26): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(27): ReLU(inplace=True)
(28): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(29): ReLU(inplace=True)
(30): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)
(avgpool): AdaptiveAvgPool2d(output_size=(7, 7))
(classifier): Sequential(
(0): Linear(in_features=25088, out_features=4096, bias=True)
(1): ReLU(inplace=True)
(2): Dropout(p=0.5, inplace=False)
(3): Linear(in_features=4096, out_features=4096, bias=True)
(4): ReLU(inplace=True)
(5): Dropout(p=0.5, inplace=False)
(6): Linear(in_features=4096, out_features=1000, bias=True)
)
)
1. 优化器与损失函数
optimizer = Adam(model.parameters(), lr=0.0001, weight_decay=0.0001)
loss_model = nn.CrossEntropyLoss()
from torch.autograd import Variable
def test(model, test_loader, loss_model):
size = len(test_loader.dataset)
num_batches = len(test_loader)
model.eval()
test_loss, correct = 0, 0
with torch.no_grad():
for X, y in test_loader:
X, y = X.to(device), y.to(device)
pred = model(X)
test_loss += loss_model(pred, y).item()
correct += (pred.argmax(1) == y).type(torch.float).sum().item()
test_loss /= num_batches
correct /= size
print(f"Test Error: \\n Accuracy: (100*correct):>0.1f%, Avg loss: test_loss:>8f \\n")
return correct,test_loss
def train(model,train_loader,loss_model,optimizer):
model=model.to(device)
model.train()
for i, (images, labels) in enumerate(train_loader, 0):
images = Variable(images.to(device))
labels = Variable(labels.to(device))
optimizer.zero_grad()
outputs = model(images)
loss = loss_model(outputs, labels)
loss.backward()
optimizer.step()
if i % 1000 == 0:
print('[%5d] loss: %.3f' % (i, loss))
2. 模型的训练
test_acc_list = []
epochs = 10
for t in range(epochs):
print(f"Epoch t+1\\n-------------------------------")
train(model,train_loader,loss_model,optimizer)
test_acc,test_loss = test(model, test_loader, loss_model)
test_acc_list.append(test_acc)
print("Done!")
Epoch 1
-------------------------------
[ 0] loss: 37.630
[ 1000] loss: 1.025
Test Error:
Accuracy: 69.7%, Avg loss: 0.716039
Epoch 2
-------------------------------
[ 0] loss: 0.836
[ 1000] loss: 0.438
Test Error:
Accuracy: 71.0%, Avg loss: 0.699544
Epoch 3
-------------------------------
[ 0] loss: 0.527
[ 1000] loss: 0.616
Test Error:
Accuracy: 75.3%, Avg loss: 0.634513
Epoch 4
-------------------------------
[ 0] loss: 0.276
[ 1000] loss: 0.294
Test Error:
Accuracy: 75.7%, Avg loss: 0.817064
Epoch 5
-------------------------------
[ 0] loss: 1.014
[ 1000] loss: 0.496
Test Error:
Accuracy: 77.0%, Avg loss: 0.619491
Epoch 6
-------------------------------
[ 0] loss: 0.298
[ 1000] loss: 0.111
Test Error:
Accuracy: 76.4%, Avg loss: 0.780474
Epoch 7
-------------------------------
[ 0] loss: 0.037
[ 1000] loss: 0.151
Test Error:
Accuracy: 75.4%, Avg loss: 0.890973
Epoch 8
-------------------------------
[ 0] loss: 0.263
[ 1000] loss: 0.285
Test Error:
Accuracy: 79.1%, Avg loss: 0.863850
Epoch 9
-------------------------------
[ 0] loss: 0.010
[ 1000] loss: 0.014
Test Error:
Accuracy: 78.0%, Avg loss: 1.078627
Epoch 10
-------------------------------
[ 0] loss: 0.004
[ 1000] loss: 0.545
Test Error:
Accuracy: 78.5%, Avg loss: 1.079087
Done!
三、可视化
import numpy as np
import matplotlib.pyplot as plt
x = [i for i in range(1,11)]
plt.plot(x, test_acc_list, label="line ACC", alpha=0.8)
plt.xlabel("epoch")
plt.ylabel("acc")
plt.legend()
plt.show()
以上是关于深度学习100例 | 第2例:人脸表情识别 - PyTorch实现的主要内容,如果未能解决你的问题,请参考以下文章
深度学习100例 | 第4例:水果识别 - PyTorch实现
深度学习100例 | 第4例:水果识别 - PyTorch实现
深度学习100例—— 使用PyTorch实现验证码识别 | 第4例
深度学习100例 | 第1例:猫狗识别 - PyTorch实现