Source code for chainercv.links.model.vgg.vgg16

from __future__ import division

import numpy as np

import chainer
from chainer.functions import dropout
from chainer.functions import max_pooling_2d
from chainer.functions import relu
from chainer.functions import softmax
from chainer.initializers import constant
from chainer.initializers import normal

from chainer.links import Linear

from chainercv.links.connection.conv_2d_activ import Conv2DActiv
from chainercv.links.model.pickable_sequential_chain import \
    PickableSequentialChain
from chainercv import utils


# RGB order
_imagenet_mean = np.array(
    [123.68, 116.779, 103.939], dtype=np.float32)[:, np.newaxis, np.newaxis]


[docs]class VGG16(PickableSequentialChain): """VGG-16 Network. This is a pickable sequential link. The network can choose output layers from set of all intermediate layers. The attribute :obj:`pick` is the names of the layers that are going to be picked by :meth:`__call__`. The attribute :obj:`layer_names` is the names of all layers that can be picked. Examples: >>> model = VGG16() # By default, __call__ returns a probability score (after Softmax). >>> prob = model(imgs) >>> model.pick = 'conv5_3' # This is layer conv5_3 (after ReLU). >>> conv5_3 = model(imgs) >>> model.pick = ['conv5_3', 'fc6'] >>> # These are layers conv5_3 (after ReLU) and fc6 (before ReLU). >>> conv5_3, fc6 = model(imgs) .. seealso:: :class:`chainercv.links.model.PickableSequentialChain` When :obj:`pretrained_model` is the path of a pre-trained chainer model serialized as a :obj:`.npz` file in the constructor, this chain model automatically initializes all the parameters with it. When a string in the prespecified set is provided, a pretrained model is loaded from weights distributed on the Internet. The list of pretrained models supported are as follows: * :obj:`imagenet`: Loads weights trained with ImageNet and distributed \ at `Model Zoo \ <https://github.com/BVLC/caffe/wiki/Model-Zoo>`_. Args: n_class (int): The number of classes. If :obj:`None`, the default values are used. If a supported pretrained model is used, the number of classes used to train the pretrained model is used. Otherwise, the number of classes in ILSVRC 2012 dataset is used. pretrained_model (string): The destination of the pre-trained chainer model serialized as a :obj:`.npz` file. If this is one of the strings described above, it automatically loads weights stored under a directory :obj:`$CHAINER_DATASET_ROOT/pfnet/chainercv/models/`, where :obj:`$CHAINER_DATASET_ROOT` is set as :obj:`$HOME/.chainer/dataset` unless you specify another value by modifying the environment variable. mean (numpy.ndarray): A mean value. If :obj:`None`, the default values are used. If a supported pretrained model is used, the mean value used to train the pretrained model is used. Otherwise, the mean value calculated from ILSVRC 2012 dataset is used. initialW (callable): Initializer for the weights. initial_bias (callable): Initializer for the biases. """ _models = { 'imagenet': { 'param': {'n_class': 1000, 'mean': _imagenet_mean}, 'overwritable': ('mean',), 'url': 'https://chainercv-models.preferred.jp/' 'vgg16_imagenet_converted_2017_07_18.npz' } } def __init__(self, n_class=None, pretrained_model=None, mean=None, initialW=None, initial_bias=None): param, path = utils.prepare_pretrained_model( {'n_class': n_class, 'mean': mean}, pretrained_model, self._models, {'n_class': 1000, 'mean': _imagenet_mean}) self.mean = param['mean'] if initialW is None: # Employ default initializers used in the original paper. initialW = normal.Normal(0.01) if pretrained_model: # As a sampling process is time-consuming, # we employ a zero initializer for faster computation. initialW = constant.Zero() kwargs = {'initialW': initialW, 'initial_bias': initial_bias} super(VGG16, self).__init__() with self.init_scope(): self.conv1_1 = Conv2DActiv(None, 64, 3, 1, 1, **kwargs) self.conv1_2 = Conv2DActiv(None, 64, 3, 1, 1, **kwargs) self.pool1 = _max_pooling_2d self.conv2_1 = Conv2DActiv(None, 128, 3, 1, 1, **kwargs) self.conv2_2 = Conv2DActiv(None, 128, 3, 1, 1, **kwargs) self.pool2 = _max_pooling_2d self.conv3_1 = Conv2DActiv(None, 256, 3, 1, 1, **kwargs) self.conv3_2 = Conv2DActiv(None, 256, 3, 1, 1, **kwargs) self.conv3_3 = Conv2DActiv(None, 256, 3, 1, 1, **kwargs) self.pool3 = _max_pooling_2d self.conv4_1 = Conv2DActiv(None, 512, 3, 1, 1, **kwargs) self.conv4_2 = Conv2DActiv(None, 512, 3, 1, 1, **kwargs) self.conv4_3 = Conv2DActiv(None, 512, 3, 1, 1, **kwargs) self.pool4 = _max_pooling_2d self.conv5_1 = Conv2DActiv(None, 512, 3, 1, 1, **kwargs) self.conv5_2 = Conv2DActiv(None, 512, 3, 1, 1, **kwargs) self.conv5_3 = Conv2DActiv(None, 512, 3, 1, 1, **kwargs) self.pool5 = _max_pooling_2d self.fc6 = Linear(None, 4096, **kwargs) self.fc6_relu = relu self.fc6_dropout = dropout self.fc7 = Linear(None, 4096, **kwargs) self.fc7_relu = relu self.fc7_dropout = dropout self.fc8 = Linear(None, param['n_class'], **kwargs) self.prob = softmax if path: chainer.serializers.load_npz(path, self)
def _max_pooling_2d(x): return max_pooling_2d(x, ksize=2)