图片情感识别/分类/分析 概述

(一)简介

图片可以用于传达某些情感,例如看到流浪狗的照片会让你感到悲伤,而看到美景的时候会让你心旷神怡。对图片所传达的情感进行识别分析是一个具有吸引力的问题。目前已经有很多的方法在研究这个课题,本博客主要对自己所看过的相关论文做一个总结分享。

1. 情绪模型

心理学中主要有两种情感表达模型:

  • CES (Categorical Emotion States): 类别情绪状态。这种模型主要讲情绪设置为一组预先定义好的种类,例如:伤心,开心,激动等。这种模型所对应的方法将图片情感分析视为一个分类问题。
  • DES(Dimensional Emotion Space): 维度情绪模型。其中常用的有 valence-arousal-dominance (VAD) and activity-temperature-weight (VTT) 模型,其中 VAD 模型常用一些。我们可以将其视为颜色中的三种基本颜色,通过不同数值的组合得到一个颜色。VAD 中 valence、arousa l和 dominance 三个维度给一个值就代表一种情感。这种模型所对应的方法将图片情感分析视为一个回归问题。

目前大部分的论文都是使用 CES 模型的,因为这个模型直观简单,但是理论上来说 CES 的情感表达能力不如 DES,比如特别伤心和有点伤心都属于伤心一类,但是在 DES 中各个维度的值就会不同。但是两者之间是有一定联系的。比如下图中的 © 子图,如果按照 CES 就是 fear 一类,如果按照 DES 三个维度对应的值就是 4.1956、4.49989 和 4.8378。

在这里插入图片描述

2. 常用数据集

  1. IASP (International Affective Picture System)
  2. IASPa
  3. Abstract
  4. GAPED (Geneva Affective Picture Database)
  5. MART
  6. devArt
  7. Tweet
  8. FlickrCC (Flickr creative common)
  9. Flickr
  10. Emotion6
  11. FI (Flicker and Instagram)
  12. Emotion6
  13. IESN
  14. FlickrLDL
  15. TwitterLDL

3. 问题难点(挑战)

3.1 数据标记困难

标记图片的情感是一件很困难的事情,一是构造大型数据集(深度学习通常需要大量数据)通常需要大量的人力,另外有一个很关键的问题就是情绪这个问题是很主观的:同一张图片不同人可能从中获得的情感是不同的,同一个人在不同时期对同一张图片产生的情感也可能是不同的。因此标注一个大型数据集很麻烦,导致现有的大型数据集很少。解决上述问题的方法之一就是一张图片多个人标注,当某一情感占据绝对优势的时候才放入数据集。具体的流程可以参考《Bui

<think>好的,用户想用EfficientNet模型进行动物情绪分类,数据集结构是四个子文件夹,每个里面有100张图片。首先,我需要确定如何加载和处理这样的数据集。根据引用[1]里的信息,数据集以文件夹区分类别,训练时直接放入代码,代码会自动拆分训练集和验证集。所以应该用ImageFolder这种数据加载方式,或者类似的工具。 接下来,用户需要具体的代码示例。我应该考虑使用PyTorch框架,因为EfficientNet在PyTorch中有现成的实现,比如timm库。需要安装必要的库,比如torch、torchvision、timm,还有Pillow处理图像。 数据预处理部分,EfficientNet通常需要特定的图像尺寸和归一化参数。比如EfficientNet-B0通常使用224x224的输入,归一化参数是mean=[0.485, 0.456, 0.406],std=[0.229, 0.224, 0.225]。所以需要定义transforms,包括调整大小、转为张量、归一化。 数据集的划分,用户的数据集结构是每个类一个文件夹,共四个类,每个100张。根据引用[1],代码会根据提供的划分比例随机拆分训练集和验证集。可以用torch.utils.data.random_split来实现,或者用ImageFolder加载后拆分。可能需要用SubsetRandomSampler或者直接拆分数据集。 然后定义数据加载器,设置batch_size,比如32。接着加载预训练的EfficientNet模型,修改分类头,因为原来的模型输出是1000类,这里需要改成4类。需要冻结前面的层,只训练最后的全连接层,或者进行微调,根据情况调整。 训练循环部分,需要定义损失函数(交叉熵损失)、优化器(如Adam),学习率调整,训练周期数。还要考虑设备是否用GPU。在训练过程中,记录损失和准确率,每epoch验证模型性能,保存最佳模型。 可能还需要数据增强,比如随机翻转、旋转等,防止过拟合。在transforms里加入RandomHorizontalFlip、RandomRotation等。 测试阶段,加载最佳模型,用验证集或测试集评估准确率。最后,给出一个预测示例,展示如何使用模型进行单张图片的预测。 需要检查代码是否正确处理了数据路径,是否正确划分了训练集和验证集。根据引用[3],YOLOv8使用EfficientNet变体进行分类,但用户需要的是EfficientNet本身,所以代码示例应以EfficientNet为基础。 可能还需要注意类别标签的映射,确保子文件夹名称对应正确的情绪类别。比如用dataset.classes获取类别名称。 最后,确保代码中的注释清晰,用户能理解每一步的作用,特别是数据加载、模型修改和训练过程。还要提醒用户可能需要调整超参数,如学习率、batch_size,以及进行更长时间的训练以获得更好的效果。</think>以下是一个使用PyTorch实现基于EfficientNet的动物情绪分类的完整代码示例,适用于您描述的数据集结构: ```python import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms, models from torch.utils.data import DataLoader, random_split import timm # 需要安装timm库:pip install timm # 数据预处理 train_transforms = transforms.Compose([ transforms.RandomResizedCrop(224), transforms.RandomHorizontalFlip(), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ]) # 加载数据集(假设根目录结构为:/data/emotion_class/) dataset = datasets.ImageFolder( root='path/to/your/data_folder', transform=train_transforms ) # 划分训练集和验证集(8:2比例) train_size = int(0.8 * len(dataset)) val_size = len(dataset) - train_size train_dataset, val_dataset = random_split(dataset, [train_size, val_size]) # 创建数据加载器 batch_size = 32 train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True) val_loader = DataLoader(val_dataset, batch_size=batch_size) # 初始化EfficientNet模型 model = timm.create_model('efficientnet_b0', pretrained=True) num_ftrs = model.classifier.in_features model.classifier = nn.Linear(num_ftrs, 4) # 4个情绪类别 # 训练配置 device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") model = model.to(device) criterion = nn.CrossEntropyLoss() optimizer = optim.Adam(model.parameters(), lr=0.001) # 训练循环 best_acc = 0.0 for epoch in range(20): # 训练20个epoch model.train() running_loss = 0.0 for inputs, labels in train_loader: inputs = inputs.to(device) labels = labels.to(device) optimizer.zero_grad() outputs = model(inputs) loss = criterion(outputs, labels) loss.backward() optimizer.step() running_loss += loss.item() # 验证阶段 model.eval() val_loss = 0.0 correct = 0 with torch.no_grad(): for inputs, labels in val_loader: inputs = inputs.to(device) labels = labels.to(device) outputs = model(inputs) _, preds = torch.max(outputs, 1) val_loss += criterion(outputs, labels).item() correct += torch.sum(preds == labels.data) epoch_acc = correct.double() / len(val_dataset) print(f'Epoch {epoch+1}: Loss: {running_loss/len(train_loader):.4f}, Val Acc: {epoch_acc:.4f}') # 保存最佳模型 if epoch_acc > best_acc: best_acc = epoch_acc torch.save(model.state_dict(), 'best_model.pth') print(f'Training complete, best val acc: {best_acc:.4f}') ``` 关键实现要点: 1. 数据加载:利用`ImageFolder`自动解析文件夹结构[^1],每个子文件夹对应一个类别 2. 数据增强:包含随机裁剪和翻转增强模型泛化能力 3. 迁移学习:使用预训练的EfficientNet-B0作为基础模型,替换最后的全连接层 4. 训练策略:采用Adam优化器和交叉熵损失函数,保留最佳模型参数
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值