Switch to unified view

a b/src/LiviaNet/Modules/General/Utils.py
1
""" 
2
Copyright (c) 2016, Jose Dolz .All rights reserved.
3
4
Redistribution and use in source and binary forms, with or without modification,
5
are permitted provided that the following conditions are met:
6
7
    1. Redistributions of source code must retain the above copyright notice,
8
       this list of conditions and the following disclaimer.
9
    2. Redistributions in binary form must reproduce the above copyright notice,
10
       this list of conditions and the following disclaimer in the documentation
11
       and/or other materials provided with the distribution.
12
13
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14
    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
15
    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16
    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
17
    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18
    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19
    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20
    OTHER DEALINGS IN THE SOFTWARE.
21
22
Jose Dolz. Dec, 2016.
23
email: jose.dolz.upv@gmail.com
24
LIVIA Department, ETS, Montreal.
25
"""
26
27
import pdb
28
import os
29
import numpy as np
30
import theano
31
import theano.tensor as T
32
import gzip
33
import cPickle
34
import sys
35
from os.path import isfile, join
36
37
38
# https://github.com/Theano/Theano/issues/689
39
sys.setrecursionlimit(50000)
40
41
# To set a learning rate at each layer
42
def extendLearningRateToParams(numberParamsPerLayer,learning_rate):
43
    if not isinstance(learning_rate, list):
44
        learnRates = np.ones(sum(numberParamsPerLayer), dtype = "float32") * learning_rate
45
    else:
46
        print("")
47
        learnRates = []
48
        for p_i in range(len(numberParamsPerLayer)) :
49
            for lr_i in range(numberParamsPerLayer[p_i]) :
50
                learnRates.append(learning_rate[p_i])
51
    return learnRates
52
# TODO: Check that length of learning rate (in config ini) actually corresponds to length of layers (CNNs + FCs + SoftMax)
53
54
55
def computeReceptiveField(kernelsCNN, stride) :
56
    # To-do. Verify receptive field with stride size other than 1
57
    if len(kernelsCNN) == 0:
58
        return 0
59
    
60
    # Check number of ConvLayers
61
    numberCNNLayers = []
62
63
    for l_i in range(1,len(kernelsCNN)):
64
        if len(kernelsCNN[l_i]) == 3:
65
            numberCNNLayers = l_i + 1
66
              
67
    kernelDim = len(kernelsCNN[0])
68
    receptiveField = [stride]*kernelDim
69
70
    for d_i in xrange(kernelDim) :
71
        for l_i in xrange(numberCNNLayers) :
72
            receptiveField[d_i] += kernelsCNN[l_i][d_i] - 1
73
74
    return receptiveField
75
76
77
78
###########################################################
79
######## Create bias and include them on feat maps ########
80
###########################################################
81
82
# TODO. Remove number of FeatMaps
83
def addBiasParametersOnFeatureMaps( bias, featMaps, numberOfFeatMaps ) :
84
    output = featMaps + bias.dimshuffle('x', 0, 'x', 'x', 'x')
85
    return (output)
86
87
###########################################################
88
########         Initialize CNN weights            ########
89
###########################################################
90
def initializeWeights(filter_shape, initializationMethodType, weights) :
91
    # filter_shape:[#FMs in this layer, #FMs in input, KernelDim_0, KernelDim_1, KernelDim_2]
92
    def Classic():
93
        print " --- Weights initialization type: Classic "
94
        rng = np.random.RandomState(24575)
95
        stdForInitialization = 0.01
96
        W = theano.shared(
97
            np.asarray(
98
                rng.normal(loc=0.0, scale=stdForInitialization, size=(filter_shape[0],filter_shape[1],filter_shape[2],filter_shape[3],filter_shape[4])),
99
                dtype='float32'#theano.config.floatX
100
                ),
101
            borrow=True
102
        )
103
        return W
104
        
105
    def Delving():
106
       # https://arxiv.org/pdf/1502.01852.pdf
107
       print " --- Weights initialization type: Delving "
108
       rng = np.random.RandomState(24575)
109
       stdForInitialization = np.sqrt( 2.0 / (filter_shape[1] * filter_shape[2] * filter_shape[3] * filter_shape[4]) ) #Delving Into rectifiers suggestion.
110
       W = theano.shared(
111
           np.asarray(
112
               rng.normal(loc=0.0, scale=stdForInitialization, size=(filter_shape[0],filter_shape[1],filter_shape[2],filter_shape[3],filter_shape[4])),
113
               dtype='float32'#theano.config.floatX
114
               ),
115
           borrow=True
116
       )
117
       return W
118
119
    # TODO: Add checks so that weights and kernel have the same shape
120
    def Load():
121
       print " --- Weights initialization type: Transfer learning... "
122
       W = theano.shared(
123
           np.asarray(
124
               weights,
125
               dtype=theano.config.floatX
126
               ),
127
           borrow=True
128
       )
129
       return W
130
131
    optionsInitWeightsType = {0 : Classic,
132
                              1 : Delving,
133
                              2 : Load}
134
135
    W = optionsInitWeightsType[initializationMethodType]()
136
        
137
    return W
138
139
140
def getCentralVoxels(sampleSize, receptiveField) :
141
    centralVoxels = []
142
    for d_i in xrange(0, len(sampleSize)) :
143
        centralVoxels.append(sampleSize[d_i] - receptiveField[d_i] + 1)
144
    return centralVoxels
145
146
147
 
148
def extractCenterFeatMaps(featMaps, featMaps_shape, centralVoxels) :
149
150
    centerValues = []
151
    minValues = []
152
    maxValues = []
153
    
154
    for i in xrange(3) :
155
        C_v = (featMaps_shape[i + 2] - 1) / 2
156
        min_v = C_v - (centralVoxels[i]-1)/2
157
        max_v = min_v + centralVoxels[i]
158
        centerValues.append(C_v)
159
        minValues.append(min_v)
160
        maxValues.append(max_v)
161
        
162
    return featMaps[:,
163
                    :,
164
                    minValues[0] : maxValues[0],
165
                    minValues[1] : maxValues[1],
166
                    minValues[2] : maxValues[2]]
167
                    
168
169
###########################################
170
############# Save/Load models ############
171
###########################################
172
173
def load_model_from_gzip_file(modelFileName) :
174
    f = gzip.open(modelFileName, 'rb')
175
    model_obj = cPickle.load(f)
176
    f.close()
177
    return model_obj
178
179
def dump_model_to_gzip_file(model, modelFileName) :
180
    # First release GPU memory
181
    model.releaseGPUData()
182
    
183
    f = gzip.open(modelFileName, 'wb')
184
    cPickle.dump(model, f, protocol=cPickle.HIGHEST_PROTOCOL)
185
    f.close()
186
187
    return modelFileName
188
189
def makeFolder(folderName, display_Str) :
190
    if not os.path.exists(folderName) :
191
        os.makedirs(folderName)
192
193
    strToPrint = "..Folder " + display_Str + " created..."
194
    print strToPrint
195
196
197
    from os import listdir
198
199
200
""" Get a set of images from a folder given an array of indexes """
201
def getImagesSet(imagesFolder, imageIndexes) :
202
   imageNamesToGetWithFullPath = []
203
   imageNamesToGet = []
204
   
205
   if os.path.exists(imagesFolder):
206
       imageNames = [f for f in os.listdir(imagesFolder) if isfile(join(imagesFolder, f))]
207
       imageNames.sort()
208
   
209
       # Remove corrupted files (if any)
210
       if '.DS_Store' in imageNames: imageNames.remove('.DS_Store')
211
212
       imageNamesToGetWithFullPath = []
213
       imageNamesToGet = []
214
  
215
       if ( len(imageNames) > 0):  
216
           imageNamesToGetWithFullPath = [join(imagesFolder,imageNames[imageIndexes[i]]) for i in range(0,len(imageIndexes))]
217
           imageNamesToGet = [imageNames[imageIndexes[i]] for i in range(0,len(imageIndexes))]
218
219
   return (imageNamesToGetWithFullPath,imageNamesToGet)
220
221
222
223
"""" Get a set of weights from a folder given an array of indexes """
224
def getWeightsSet(weightsFolder, weightsIndexes) :
225
   weightNames = [f for f in os.listdir(weightsFolder) if isfile(join(weightsFolder, f))]
226
   weightNames.sort()
227
   
228
   # Remove corrupted files (if any)
229
   if '.DS_Store' in weightNames: weightNames.remove('.DS_Store')
230
 
231
   weightNamesToGetWithFullPath = [join(weightsFolder,weightNames[weightsIndexes[i]]) for i in range(0,len(weightsIndexes))]
232
233
   return (weightNamesToGetWithFullPath)