pytorch argmax_深度学习Pytorch实现分类模型

81e935a1e0e0cdecfcf727b868329981.gif 93601d6ac1b5df0ab8d0837cd91d6606.png

99fc3d9ddb585e84a1bf2d6f091a88f8.png

6e03992597c5bdc3c7d13226997cae01.png 今天将介绍深度学习中的分类模型,以下主要介绍Softmax的基本概念、神经网络模型、交叉熵损失函数、准确率以及Pytorch实现图像分类。 6e03992597c5bdc3c7d13226997cae01.png 0 1Softmax基本概念

在分类问题中,通常标签都为类别,可以用离散值来代替。例如,在图像分类问题中,假设一张图片是0b2a4cb5-bf2e-eb11-8da9-e4434bdf6706.svg的灰度图片,那么图片中的4个像素值102a4cb5-bf2e-eb11-8da9-e4434bdf6706.svg便是特征。假设对应的标签是猫狗等动物,其都是离散值132a4cb5-bf2e-eb11-8da9-e4434bdf6706.svg,在深度学习模型中都是采用172a4cb5-bf2e-eb11-8da9-e4434bdf6706.svg这样的离散值来代替。

0 2神经网络模型

Softmax回归同线性回归一样,也是一个单层神经网络。由于每个输出 bf1e44bb-bf2e-eb11-8da9-e4434bdf6706.svg,c11e44bb-bf2e-eb11-8da9-e4434bdf6706.svgc61e44bb-bf2e-eb11-8da9-e4434bdf6706.svg 的计算都要依赖于所有的输入c81e44bb-bf2e-eb11-8da9-e4434bdf6706.svgcb1e44bb-bf2e-eb11-8da9-e4434bdf6706.svgce1e44bb-bf2e-eb11-8da9-e4434bdf6706.svgd01e44bb-bf2e-eb11-8da9-e4434bdf6706.svg,softmax回归的输出层也是一个全连接层。那么其模型可以表达为:d31e44bb-bf2e-eb11-8da9-e4434bdf6706.svg

2de186c9a39a4b85f8f5aecd13c9de9c.png

既然分类问题需要得到离散的预测输出,一个简单的办法是将输出值da1e44bb-bf2e-eb11-8da9-e4434bdf6706.svg 当作预测类别是的dc1e44bb-bf2e-eb11-8da9-e4434bdf6706.svg 置信度,并将值最大的输出所对应的类作为预测输出,即输出dd1e44bb-bf2e-eb11-8da9-e4434bdf6706.svg. 例如, bf1e44bb-bf2e-eb11-8da9-e4434bdf6706.svg,c11e44bb-bf2e-eb11-8da9-e4434bdf6706.svgc61e44bb-bf2e-eb11-8da9-e4434bdf6706.svg 分别为0.1,5,0.1,那么该预测类别便是2。

但是这样存在问题:

  1. 一方面,由于输出层的输出值的范围不确定,我们难以直观上判断这些值的意义。如果某个样本输出值bf1e44bb-bf2e-eb11-8da9-e4434bdf6706.svg,c11e44bb-bf2e-eb11-8da9-e4434bdf6706.svgc61e44bb-bf2e-eb11-8da9-e4434bdf6706.svg 分别为0.1,10,0.1,那么说明该样本非常可能为第二类,但是如果另外一个样本的输出值bf1e44bb-bf2e-eb11-8da9-e4434bdf6706.svg,c11e44bb-bf2e-eb11-8da9-e4434bdf6706.svgc61e44bb-bf2e-eb11-8da9-e4434bdf6706.svg分别为1000,10,1000,那这个10却表示的是为第二类的概率很低;

  2. 另一方面,由于真实标签是离散值,这些离散值与不确定范围的输出值之间的误差难以衡量。

因此需要将每个样本的输出值归一化,即softmax运算:f11e44bb-bf2e-eb11-8da9-e4434bdf6706.svg
其中f41e44bb-bf2e-eb11-8da9-e4434bdf6706.svg
可以看出f61e44bb-bf2e-eb11-8da9-e4434bdf6706.svg,f81e44bb-bf2e-eb11-8da9-e4434bdf6706.svg。取fd1e44bb-bf2e-eb11-8da9-e4434bdf6706.svg为某类的概率。

一般的,softmax回归的矢量计算表达式为:011f44bb-bf2e-eb11-8da9-e4434bdf6706.svg
假设样本数为031f44bb-bf2e-eb11-8da9-e4434bdf6706.svg,特征数为051f44bb-bf2e-eb11-8da9-e4434bdf6706.svg,输出个数(类别数)为071f44bb-bf2e-eb11-8da9-e4434bdf6706.svg,那么091f44bb-bf2e-eb11-8da9-e4434bdf6706.svg的维度为121f44bb-bf2e-eb11-8da9-e4434bdf6706.svg141f44bb-bf2e-eb11-8da9-e4434bdf6706.svg的维度为171f44bb-bf2e-eb11-8da9-e4434bdf6706.svg1d1f44bb-bf2e-eb11-8da9-e4434bdf6706.svg的维度为1e1f44bb-bf2e-eb11-8da9-e4434bdf6706.svg

0 3交叉熵损失函数

交叉熵(cross entropy)是一个常用的衡量两个概率分布差异的测量函数:201f44bb-bf2e-eb11-8da9-e4434bdf6706.svg

例如,样本dc1e44bb-bf2e-eb11-8da9-e4434bdf6706.svg的预测输出值分别为[0.2,0.6,0.2],即上式中的预测值271f44bb-bf2e-eb11-8da9-e4434bdf6706.svg,其真实类别为[0,1,0],即上式中的2b1f44bb-bf2e-eb11-8da9-e4434bdf6706.svg。也就是说,交叉熵只关心对正确类别的预测概率,因为只要其值足够大,就可以确保分类结果正确。

假设训练数据集的样本数为031f44bb-bf2e-eb11-8da9-e4434bdf6706.svg,交叉熵损失函数定义为:311f44bb-bf2e-eb11-8da9-e4434bdf6706.svg
最小化交叉熵损失函数等价于最大化训练数据集所有标签类别的联合预测概率。

04 准确率

在训练好softmax回归模型后,给定任一样本特征,就可以预测每个输出类别的概率。通常,我们把预测概率最大的类别作为输出类别。如果它与真实类别(标签)一致,说明这次预测是正确的。可以使用准确率(accuracy)来评价模型的表现。它等于正确预测数量与总预测数量之比。

05 获取数据

此处使用的是使用一个图像内容更加复杂的数据集Fashion-MNIST[2]。去下载。
这里我们会使用torchvision包,它是服务于PyTorch深度学习框架的,主要用来构建计算机视觉模型。torchvision主要由以下几部分构成:

  1. torchvision.datasets: 一些加载数据的函数及常用的数据集接口;

  2. torchvision.models: 包含常用的模型结构(含预训练模型),例如AlexNet、VGG、ResNet等;

  3. torchvision.transforms: 常用的图片变换,例如裁剪、旋转等;

  4. torchvision.utils: 其他的一些有用的方法。

数据展示:

9338a5ada60019b13acf0ec46e3aa1a6.png

0 6实现
import matplotlib.pyplot as pltimport torchimport torchvisionimport numpy as npimport torchvision.transforms as transformsimport timeimport sysdef getData():    # train:指定是否为训练集 download:是否下载,如果本地已经有了则不会下载    # (可被调用 , 可选)– 一种函数或变换,输入PIL图片,返回变换之后的数据。如:transforms.RandomCrop。    mnist_train = torchvision.datasets.FashionMNIST(root='data/', train=True, download=True, transform=transforms.ToTensor())    # 如果无法下载,可https://github.com/zalandoresearch/fashion-mnist    # 放进data/FashionMNIST\raw\train-images-idx3-ubyte.gz    mnist_test = torchvision.datasets.FashionMNIST(root='data/', train=False, download=True, transform=transforms.ToTensor())    return mnist_train, mnist_test# softmax运算def softmax(X):    X_exp = X.exp()    partition = X_exp.sum(dim=1, keepdim=True)    return X_exp / partition  # 这里应用了广播机制# softmax模型def model(X, W, b):    return softmax(torch.mm(X.view((-1, W.shape[0])), W) + b)# 损失函数def cross_entropy(y_hat, y):    # 按y中的数字取相应的列    return - torch.log(y_hat.gather(1, y.view(-1, 1)))# 准确率def evaluate_accuracy(data_iter, net, params):    acc_sum, n = 0.0, 0    for X, y in data_iter:        acc_sum += (net(X, params[0], params[1]).argmax(dim=1) == y).float().sum().item()        n += y.shape[0]    return acc_sum / ndef train(net, train_iter, test_iter, loss, num_epochs, batch_size,              params=None, lr=None, optimizer=None):    for epoch in range(num_epochs):        train_l_sum, train_acc_sum, n = 0.0, 0.0, 0        for X, y in train_iter:            y_hat = net(X, params[0], params[1])            l = loss(y_hat, y).sum()                        # 梯度清零            if optimizer is not None:                optimizer.zero_grad()            elif params is not None and params[0].grad is not None:                for param in params:                    param.grad.data.zero_()                        l.backward()            if optimizer is None:                sgd(params, lr, batch_size) # 梯度更新            else:                optimizer.step()             train_l_sum += l.item()            train_acc_sum += (y_hat.argmax(dim=1) == y).sum().item()            n += y.shape[0]        test_acc = evaluate_accuracy(test_iter, net, params)        print('epoch %d, loss %.4f, train acc %.3f, test acc %.3f'              % (epoch + 1, train_l_sum / n, train_acc_sum / n, test_acc))def predict(net, test_iter, params):    X, y = iter(test_iter).next()    true_labels = get_fashion_mnist_labels(y.numpy())    pred_labels = get_fashion_mnist_labels(net(X, params[0], params[1]).argmax(dim=1).numpy())    titles = [true + '\n' + pred for true, pred in zip(true_labels, pred_labels)]    show_fashion_mnist(X[0:9], titles[0:9])def main():    # 超参数    num_epochs, lr = 5, 0.1    batch_size = 256 # 批量大小    num_inputs = 28*28 # 图像的高和宽    num_outputs = 10 # 一共十种类别    train_iter, test_iter = loadData(batch_size)    W, b = init_parameters(num_inputs, num_outputs)    train(model, train_iter, test_iter, cross_entropy, num_epochs, batch_size, [W, b], lr)    # 预测    predict(model, test_iter, [W, b])if __name__ == '__main__':    # getData() # 获取数据    # show() # 展示数据    main() # 自己实现
0 7结果及预测
epoch 1, loss 0.7874, train acc 0.749, test acc 0.791epoch 2, loss 0.5712, train acc 0.812, test acc 0.813epoch 3, loss 0.5250, train acc 0.826, test acc 0.820epoch 4, loss 0.5018, train acc 0.833, test acc 0.824epoch 5, loss 0.4860, train acc 0.837, test acc 0.827

可以看出测试集上能够达到80%以上的准确率。模型训练完后,便可以进行预测。给定一系列图像(第三行图像输出),比较一下它们的真实标签(第一行文本输出)和模型预测结果(第二行文本输出)。

22cb1b9f3478ebb4ff5f1631998a8b47.png

如需源码,请后台回复 "softmax回归"。有什么问题,可添加微信 "wxid-3ccc".

02f58d255d7cc09f423b6ffd9a2cfdc8.png

双向Dijkstra算法

EndNote引文编排

利用GN算法进行社区发现

Python爬取高德地图--瓦片图

水位时态数据在地图上的动态展示

深度学习--Pytorch实现线性规划

ArcPy批量定义投影和批量投影转换

机器人局部规划算法--DWA算法原理

ArcGIS时间滑块实现车辆轨迹动态展示

多时间序列数据MK突变检验突变点提取

世界各国GDP排名变化--Matlab动图实现

世界各国GDP排名变化--Python动图实现

da033517fe7ff870978af382af4bf3ff.png

95d55c2ca756ded46ac035728381b575.gif

▼ 更多精彩推荐,敬请关注我们 ▼ ee63a146411fcd974a0416013cbac681.png e2cd9a5fee93ab1490bf4cf00b964f4d.png 5bb6fd7b873a0645ea5d3fd2451d5f22.png我就知道你“在看” d012a2ce0f8ac8f6846999f6ac1c6c6f.gif
<think>嗯,用户想用PyTorch实现面部表情识别,需要教程或示例代码。首先,我需要考虑用户可能的背景。他们可能有一定的深度学习基础,但对面部表情识别的具体实现太熟悉。所以,我应该从项目的基本流程入手,分步骤讲解,并提供代码示例。 根据用户提供的引用内容,特别是引用[2]、[3]、[4]中提到的数据准备、模型构建、环境配置等,我应该涵盖这些方面。例如,数据预处理可能需要用到OpenCV进行人脸检测,模型方面可以使用ResNet等预训练模型进行迁移学习,训练过程中要注意数据增强和优化器选择。 用户可能需要具体的代码示例,所以需要提供数据加载、模型定义、训练循环等关键部分的代码。同时,要确保代码符合PyTorch的最佳实践,比如使用Dataset和DataLoader类。 还需要考虑数据集的获取,比如FER2013或CK+,这些在引用中被提到过。数据预处理步骤可能需要归一化,使用均值和方差,如引用[3]中提到的计算数据集的均值和方差。 模型训练部分,要提到损失函数和优化器的选择,比如交叉熵损失和Adam优化器。另外,引用[4]中提到使用haarcascade_frontalface_default进行人脸检测,这一点在代码实现中也需要体现,确保输入图像是经过人脸裁剪的。 可能还需要提醒用户注意过拟合问题,使用验证集和早停法,如引用[3]中提到的Batch Normalization的作用。此外,激活函数的选择,比如Mish,但ReLU更常见,可能更适合初学者。 最后,生成相关问题时,要考虑用户可能的后续需求,比如性能优化、模型部署、数据增强方法等,这些问题在引用中也有涉及,比如引用[2]中的Flask部署,引用[4]中的环境配置。 总之,回答需要结构清晰,步骤明确,代码实用,同时覆盖数据准备、模型构建、训练和评估,以及实际应用场景,确保用户能够按照步骤实现项目,并解决可能遇到的问题。</think>### 分步实现面部表情识别的PyTorch教程 #### 一、数据准备 1. **常用数据集**: - FER2013:包含35,887张48×48灰度图像,7种表情(愤怒、厌恶、恐惧、快乐、悲伤、惊讶、中性)[^4] - CK+:包含593个视频序列,提取关键帧后获得表情图像 ```python # 示例数据加载代码 import torchvision.transforms as transforms from torchvision.datasets import ImageFolder transform = transforms.Compose([ transforms.Grayscale(), transforms.Resize((48,48)), transforms.ToTensor(), transforms.Normalize(mean=[0.5], std=[0.5]) ]) dataset = ImageFolder('path/to/fer2013', transform=transform) ``` #### 二、模型构建(基于ResNet改进) ```python import torch.nn as nn import torchvision.models as models class FacialExpressionCNN(nn.Module): def __init__(self, num_classes=7): super().__init__() self.base_model = models.resnet18(pretrained=True) # 修改第一层适配灰度图 self.base_model.conv1 = nn.Conv2d(1, 64, kernel_size=7, stride=2, padding=3, bias=False) # 修改最后一层 self.base_model.fc = nn.Sequential( nn.Dropout(0.5), nn.Linear(512, num_classes) ) def forward(self, x): return self.base_model(x) ``` #### 三、训练流程 ```python from torch.utils.data import DataLoader import torch.optim as optim # 超参数设置 BATCH_SIZE = 64 EPOCHS = 30 LR = 0.001 # 初始化组件 model = FacialExpressionCNN() criterion = nn.CrossEntropyLoss() optimizer = optim.Adam(model.parameters(), lr=LR) train_loader = DataLoader(dataset, batch_size=BATCH_SIZE, shuffle=True) # 训练循环 for epoch in range(EPOCHS): for inputs, labels in train_loader: outputs = model(inputs) loss = criterion(outputs, labels) optimizer.zero_grad() loss.backward() optimizer.step() ``` #### 四、关键实现细节 1. **人脸检测预处理**: ```python import cv2 def detect_face(image_path): face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml') img = cv2.imread(image_path) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) faces = face_cascade.detectMultiScale(gray, 1.3, 5) return faces[0] if len(faces)>0 else None # 返回第一个检测到的人脸坐标[^4] ``` 2. **数据增强策略**: ```python train_transform = transforms.Compose([ transforms.RandomRotation(15), transforms.RandomHorizontalFlip(), transforms.ColorJitter(brightness=0.2, contrast=0.2), transforms.ToTensor(), transforms.Normalize(mean=[0.485], std=[0.229]) ]) ``` #### 五、模型评估 建议使用混淆矩阵和分类报告: ```python from sklearn.metrics import classification_report def evaluate(model, test_loader): model.eval() all_preds = [] all_labels = [] with torch.no_grad(): for inputs, labels in test_loader: outputs = model(inputs) _, preds = torch.max(outputs, 1) all_preds.extend(preds.cpu().numpy()) all_labels.extend(labels.cpu().numpy()) print(classification_report(all_labels, all_preds)) ``` #### 六、部署建议 使用Flask创建Web应用: ```python from flask import Flask, request, jsonify app = Flask(__name__) @app.route('/predict', methods=['POST']) def predict(): file = request.files['image'] img = process_image(file) # 包含人脸检测和预处理 prediction = model(img) return jsonify({'emotion': class_names[prediction.argmax()]}) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值