cv_module.py 3.4 KB
Newer Older
W
wuzewu 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
# coding:utf-8
# Copyright (c) 2020  PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

16 17
from typing import List

W
wuzewu 已提交
18 19
import numpy as np
import paddle
20
import paddle.nn.functional as F
W
wuzewu 已提交
21 22 23 24 25 26 27

from paddlehub.module.module import serving, RunModule
from paddlehub.utils.utils import base64_to_cv2


class ImageServing(object):
    @serving
28
    def serving_method(self, images: List[str], **kwargs) -> List[dict]:
W
wuzewu 已提交
29 30 31 32 33 34 35
        """Run as a service."""
        images_decode = [base64_to_cv2(image) for image in images]
        results = self.predict(images=images_decode, **kwargs)
        return results


class ImageClassifierModule(RunModule, ImageServing):
36 37 38 39 40 41 42 43 44 45 46
    def training_step(self, batch: int, batch_idx: int) -> dict:
        '''
        One step for training, which should be called as forward computation.

        Args:
            batch(list[paddle.Variable]): The one batch data, which contains images and labels.
            batch_idx(int): The index of batch.

        Returns:
            results(dict) : The model outputs, such as loss and metrics.
        '''
W
wuzewu 已提交
47 48
        return self.validation_step(batch, batch_idx)

49 50 51 52 53 54 55 56 57 58 59
    def validation_step(self, batch: int, batch_idx: int) -> dict:
        '''
        One step for validation, which should be called as forward computation.

        Args:
            batch(list[paddle.Variable]): The one batch data, which contains images and labels.
            batch_idx(int): The index of batch.

        Returns:
            results(dict) : The model outputs, such as metrics.
        '''
W
wuzewu 已提交
60
        images = batch[0]
61
        labels = paddle.unsqueeze(batch[1], axis=-1)
W
wuzewu 已提交
62 63

        preds = self(images)
64 65 66
        loss, _ = F.softmax_with_cross_entropy(preds, labels, return_softmax=True, axis=1)
        loss = paddle.mean(loss)
        acc = paddle.metric.accuracy(preds, labels)
W
wuzewu 已提交
67 68
        return {'loss': loss, 'metrics': {'acc': acc}}

69 70 71 72 73 74 75 76 77 78 79
    def predict(self, images: List[np.ndarray], top_k: int = 1) -> List[dict]:
        '''
        Predict images

        Args:
            images(list[numpy.ndarray]) : Images to be predicted, consist of np.ndarray in bgr format.
            top_k(int) : Output top k result of each image.

        Returns:
            results(list[dict]) : The prediction result of each input image
        '''
W
wuzewu 已提交
80 81 82
        images = self.transforms(images)
        if len(images.shape) == 3:
            images = images[np.newaxis, :]
83 84
        preds = self(paddle.to_variable(images))
        preds = F.softmax(preds, axis=1).numpy()
W
wuzewu 已提交
85 86 87 88 89 90 91 92 93 94
        pred_idxs = np.argsort(preds)[::-1][:, :top_k]
        res = []
        for i, pred in enumerate(pred_idxs):
            res_dict = {}
            for k in pred:
                class_name = self.labels[int(k)]
                res_dict[class_name] = preds[i][k]
            res.append(res_dict)
        return res

95
    def is_better_score(self, old_score: dict, new_score: dict):
W
wuzewu 已提交
96
        return old_score['acc'] < new_score['acc']