FaceNetSimple.py 6.18 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#!/usr/bin/env python
# vim: set fileencoding=utf-8 :
# @author: Tiago de Freitas Pereira <tiago.pereira@idiap.ch>
# @date: Wed 11 May 2016 09:39:36 CEST 

import tensorflow as tf
from .SequenceNetwork import SequenceNetwork
from ..layers import Conv2D, FullyConnected, MaxPooling
from bob.learn.tensorflow.initialization import Xavier
from bob.learn.tensorflow.initialization import Constant


class FaceNetSimple(SequenceNetwork):
    """
    Class that creates the The FaceNet architecture used in

    Schroff, Florian, Dmitry Kalenichenko, and James Philbin.
    "Facenet: A unified embedding for face recognition and clustering."
    Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition. 2015.

    This CNN DOES NOT HAVE THE 2d convolution of 1x1 described in:

    Ahuja, Ravindra K., Thomas L. Magnanti, and James B. Orlin.
    "Network flows: theory, algorithms, and applications." (1993).

    """

    def __init__(self,
                 ### First macro layer
                 conv1_kernel_size=7,
                 conv1_output=64,
                 conv1_stride=[1, 2, 2, 1], #[1, 2, 2, 1],

                 pool1_shape=[1, 3, 3, 1],
                 pool1_stride=[1, 2, 2, 1],

                 ### Second macro layer
                 conv2_kernel_size=3,
                 conv2_output=192,

                 pool2_shape=[1, 3, 3, 1],
                 pool2_stride=[1, 2, 2, 1],

                 ### Third macro layer
                 conv3_kernel_size=3,
                 conv3_output=192,

                 pool3_shape=[1, 3, 3, 1],
                 pool3_stride=[1, 2, 2, 1],

                 ### Forth macro layer
                 conv4_kernel_size=3,
                 conv4_output=384,

                 ### Fifth macro layer
                 conv5_kernel_size=3,
                 conv5_output=256,

                 ### Sixth macro layer
                 conv6_kernel_size=3,
                 conv6_output=256,

                 pool6_shape=[1, 3, 3, 1],
                 pool6_stride=[1, 2, 2, 1],


                 fc1_output=256,
                 fc2_output=128,

                 fc7128_output=128,

                 default_feature_layer="fc7128",
                 seed=10,
                 use_gpu=False):
        """
        Create all the necessary variables for this CNN

        **Parameters**
            conv1_kernel_size=5,
            conv1_output=32,

            conv2_kernel_size=5,
            conv2_output=64,

            fc1_output=400,
            n_classes=10

            seed = 10
        """
        super(FaceNetSimple, self).__init__(default_feature_layer=default_feature_layer,
                                    use_gpu=use_gpu)

        self.add(Conv2D(name="conv1", kernel_size=conv1_kernel_size,
                        filters=conv1_output,
                        activation=tf.nn.relu,
                        stride=conv1_stride,
                        weights_initialization=Xavier(seed=seed, use_gpu=self.use_gpu),
                        bias_initialization=Constant(use_gpu=self.use_gpu)
                        ))
        self.add(MaxPooling(name="pooling1", shape=pool1_shape, strides=pool1_stride))

        ##########
        self.add(Conv2D(name="conv2", kernel_size=conv2_kernel_size,
                        filters=conv2_output,
                        activation=tf.nn.relu,
                        weights_initialization=Xavier(seed=seed, use_gpu=self.use_gpu),
                        bias_initialization=Constant(use_gpu=self.use_gpu)
                        ))
        self.add(MaxPooling(name="pooling2", shape=pool2_shape, strides=pool2_stride))

        ##########
        self.add(Conv2D(name="conv3", kernel_size=conv3_kernel_size,
                        filters=conv3_output,
                        activation=tf.nn.relu,
                        weights_initialization=Xavier(seed=seed, use_gpu=self.use_gpu),
                        bias_initialization=Constant(use_gpu=self.use_gpu)
                        ))
        self.add(MaxPooling(name="pooling3", shape=pool3_shape, strides=pool3_stride))

        ##########
        self.add(Conv2D(name="conv4", kernel_size=conv4_kernel_size,
                        filters=conv4_output,
                        activation=tf.nn.relu,
                        weights_initialization=Xavier(seed=seed, use_gpu=self.use_gpu),
                        bias_initialization=Constant(use_gpu=self.use_gpu)
                        ))

        ##########
        self.add(Conv2D(name="conv5", kernel_size=conv5_kernel_size,
                        filters=conv5_output,
                        activation=tf.nn.relu,
                        weights_initialization=Xavier(seed=seed, use_gpu=self.use_gpu),
                        bias_initialization=Constant(use_gpu=self.use_gpu)
                        ))

        ##########
        self.add(Conv2D(name="conv6", kernel_size=conv6_kernel_size,
                        filters=conv6_output,
                        activation=tf.nn.relu,
                        weights_initialization=Xavier(seed=seed, use_gpu=self.use_gpu),
                        bias_initialization=Constant(use_gpu=self.use_gpu)
                        ))
        self.add(MaxPooling(name="pooling6", shape=pool6_shape, strides=pool6_stride))

        self.add(FullyConnected(name="fc1", output_dim=fc1_output,
                                activation=tf.nn.relu,
                                weights_initialization=Xavier(seed=seed, use_gpu=self.use_gpu),
                                bias_initialization=Constant(use_gpu=self.use_gpu)
                                ))

        self.add(FullyConnected(name="fc2", output_dim=fc2_output,
                                activation=tf.nn.relu,
                                weights_initialization=Xavier(seed=seed, use_gpu=self.use_gpu),
                                bias_initialization=Constant(use_gpu=self.use_gpu)
                                ))

        self.add(FullyConnected(name="fc7128", output_dim=fc7128_output,
                                activation=None,
                                weights_initialization=Xavier(seed=seed, use_gpu=self.use_gpu),
                                bias_initialization=Constant(use_gpu=self.use_gpu)
                                ))