如何在PyTorch情感检测模型上进行预测

我为5种情感识别制作了一个CNN模型。我想用单张图片来测试它,以获取每种情感的个别类别预测结果。

评估模型是可行的,但我似乎找不到如何用单张图片进行预测的方法。我该怎么做呢?

模型

def conv_block(in_channels, out_channels, pool=False):layers = [nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1),           nn.BatchNorm2d(out_channels),           nn.ELU(inplace=True)]if pool: layers.append(nn.MaxPool2d(2))return nn.Sequential(*layers)class ResNet(ImageClassificationBase):    def __init__(self, in_channels, num_classes):        super().__init__()                self.conv1 = conv_block(in_channels, 128)        self.conv2 = conv_block(128, 128, pool=True)        self.res1 = nn.Sequential(conv_block(128, 128), conv_block(128, 128))        self.drop1 = nn.Dropout(0.5)                self.conv3 = conv_block(128, 256)        self.conv4 = conv_block(256, 256, pool=True)        self.res2 = nn.Sequential(conv_block(256, 256), conv_block(256, 256))        self.drop2 = nn.Dropout(0.5)                self.conv5 = conv_block(256, 512)        self.conv6 = conv_block(512, 512, pool=True)        self.res3 = nn.Sequential(conv_block(512, 512), conv_block(512, 512))        self.drop3 = nn.Dropout(0.5)        self.classifier = nn.Sequential(nn.MaxPool2d(6),                                         nn.Flatten(),                                        nn.Linear(512, num_classes))            def forward(self, xb):        out = self.conv1(xb)        out = self.conv2(out)        out = self.res1(out) + out        out = self.drop1(out)        out = self.conv3(out)        out = self.conv4(out)        out = self.res2(out) + out        out = self.drop2(out)        out = self.conv5(out)        out = self.conv6(out)        out = self.res3(out) + out        out = self.drop3(out)        out = self.classifier(out)        return out

调用fit_one_cycle函数来训练模型

@torch.no_grad()def evaluate(model, val_loader):model.eval()outputs = [model.validation_step(batch) for batch in val_loader]return model.validation_epoch_end(outputs)def get_lr(optimizer):    for param_group in optimizer.param_groups:       return param_group['lr']def fit_one_cycle(epochs, max_lr, model, train_loader, val_loader,               weight_decay=0, grad_clip=None, opt_func=torch.optim.SGD):    torch.cuda.empty_cache()    history = []# Set up custom optimizer with weight decayoptimizer = opt_func(model.parameters(), max_lr, weight_decay=weight_decay)# Set up one-cycle learning rate schedulersched = torch.optim.lr_scheduler.OneCycleLR(optimizer, max_lr, epochs=epochs,                                             steps_per_epoch=len(train_loader))    for epoch in range(epochs):        # Training Phase         model.train()        train_losses = []        lrs = []        for batch in train_loader:            loss = model.training_step(batch)            train_losses.append(loss)            loss.backward()                    # Gradient clipping            if grad_clip:                 nn.utils.clip_grad_value_(model.parameters(), grad_clip)                    optimizer.step()            optimizer.zero_grad()                    # Record & update learning rate            lrs.append(get_lr(optimizer))            sched.step()            # Validation phase        result = evaluate(model, val_loader)        result['train_loss'] = torch.stack(train_losses).mean().item()        result['lrs'] = lrs        model.epoch_end(epoch, result)        history.append(result)    return history

这会返回准确率和损失,我希望将其更改为返回每个类别的预测百分比。

    def accuracy(outputs, labels):    _, preds = torch.max(outputs, dim=1)    return torch.tensor(torch.sum(preds == labels).item() / len(preds))class ImageClassificationBase(nn.Module):    def training_step(self, batch):        images, labels = batch         out = self(images)        loss = F.cross_entropy(out, labels)        return loss        def validation_step(self, batch):        images, labels = batch        out = self(images)        loss = F.cross_entropy(out, labels)        acc = accuracy(out, labels)        return {'val_loss': loss, 'val_acc': acc}            def validation_epoch_end(self, outputs):        batch_losses = [x['val_loss'] for x in outputs]        epoch_loss = torch.stack(batch_losses).mean()        batch_accs = [x['val_acc'] for x in outputs]        epoch_acc = torch.stack(batch_accs).mean()        return {'val_loss': epoch_loss.item(), 'val_acc': epoch_acc.item()}        def epoch_end(self, epoch, result):        print("Epoch [{}], last_lr: {:.5f}, train_loss: {:.4f}, val_loss: {:.4f}, val_acc: {:.4f}".format(            epoch, result['lrs'][-1], result['train_loss'], result['val_loss'], result['val_acc']))

回答:

评估模型是可行的,但我似乎找不到如何用单张图片进行预测的方法。我该怎么做呢?

简单来说,如果你有一张图片,请确保:

  • 在开头使用额外的1维度
  • 确保使用CHW格式而不是HWC(或者在PyTorch中指定,查看如何操作请点击这里

例如:

my_model = CNN(...)random_image = torch.randn(1, 3, 100, 100) # 3个通道,100x100的图像

顺便提一下,你的准确率计算可以简化如下:

def accuracy(outputs, labels):    preds = torch.argmax(outputs, dim=1)    return torch.sum(preds == labels) / len(preds)

获取类别概率

类似于argmax,你可以使用softmax,它将网络输出的logits(未归一化的概率)转换为概率:

def probability(outputs):    return torch.nn.functional.softmax(outputs, dim=1)

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注