from lasagne.layers import InputLayer, DenseLayer, NonlinearityLayer
from lasagne.layers.dnn import Conv2DDNNLayer as ConvLayer
from lasagne.layers import Pool2DLayer as PoolLayer
from lasagne.nonlinearities import softmax
from lasagne.utils import floatX
def build_vgg16():
net = {}
net['input'] = InputLayer((None, 3, 224, 224))
net['conv1_1'] = ConvLayer(net['input' ], 64 , 3, pad=1)
net['conv1_2'] = ConvLayer(net['conv1_1'], 64 , 3, pad=1)
net['pool1'] = PoolLayer(net['conv1_2'], 2)
net['conv2_1'] = ConvLayer(net['pool1' ], 128, 3, pad=1)
net['conv2_2'] = ConvLayer(net['conv2_1'], 128, 3, pad=1)
net['pool2'] = PoolLayer(net['conv2_2'], 2)
net['conv3_1'] = ConvLayer(net['pool2' ], 256, 3, pad=1)
net['conv3_2'] = ConvLayer(net['conv3_1'], 256, 3, pad=1)
net['conv3_3'] = ConvLayer(net['conv3_2'], 256, 3, pad=1)
net['pool3'] = PoolLayer(net['conv3_3'], 2)
net['conv4_1'] = ConvLayer(net['pool3' ], 512, 3, pad=1)
net['conv4_2'] = ConvLayer(net['conv4_1'], 512, 3, pad=1)
net['conv4_3'] = ConvLayer(net['conv4_2'], 512, 3, pad=1)
net['pool4'] = PoolLayer(net['conv4_3'], 2)
net['conv5_1'] = ConvLayer(net['pool4' ], 512, 3, pad=1)
net['conv5_2'] = ConvLayer(net['conv5_1'], 512, 3, pad=1)
net['conv5_3'] = ConvLayer(net['conv5_2'], 512, 3, pad=1)
net['pool5'] = PoolLayer(net['conv5_3'], 2)
net['fc6'] = DenseLayer(net['pool5'], num_units=4096)
net['fc7'] = DenseLayer(net['fc6' ], num_units=4096)
net['fc8'] = DenseLayer(net['fc7' ], num_units=1000, nonlinearity=None)
net['prob'] = NonlinearityLayer(net['fc8'], softmax)
return netThe unpooling layers use the indices of the max elements in the corresponding max pooling layer to scale up each feature map.
However, I don't know how to implement the unpooling layers. What is the simplest way to do that in Lasagne?
from lasagne.layers import InputLayer, DenseLayer, NonlinearityLayer, InverseLayer, Upscale2DLayer
from lasagne.layers.dnn import Conv2DDNNLayer as ConvLayer
from lasagne.layers.dnn import Conv2DDNNLayer as DeconvLayer
from lasagne.layers import Pool2DLayer as PoolLayer
def build_SegNet():
net = {}
# Build encoder (downsampling) part
net['input'] = InputLayer((None, 3, destH, destW))
net['conv1_1'] = ConvLayer(net['input'], 64 , hyperParams.encFilterSize, pad=1)
net['conv1_2'] = ConvLayer(net['conv1_1'], 64 , hyperParams.encFilterSize, pad=1)
net['pool1'] = PoolLayer(net['conv1_2'], 2, ignore_border=ignoreBorder)
net['conv2_1'] = ConvLayer(net['pool1'], 128, hyperParams.encFilterSize, pad=1)
net['conv2_2'] = ConvLayer(net['conv2_1'], 128, hyperParams.encFilterSize, pad=1)
net['pool2'] = PoolLayer(net['conv2_2'], 2, ignore_border=ignoreBorder)
net['conv3_1'] = ConvLayer(net['pool2'], 256, hyperParams.encFilterSize, pad=1)
net['conv3_2'] = ConvLayer(net['conv3_1'], 256, hyperParams.encFilterSize, pad=1)
net['conv3_3'] = ConvLayer(net['conv3_2'], 256, hyperParams.encFilterSize, pad=1)
net['pool3'] = PoolLayer(net['conv3_3'], 2, ignore_border=ignoreBorder)
net['conv4_1'] = ConvLayer(net['pool3'], 512, hyperParams.encFilterSize, pad=1)
net['conv4_2'] = ConvLayer(net['conv4_1'], 512, hyperParams.encFilterSize, pad=1)
net['conv4_3'] = ConvLayer(net['conv4_2'], 512, hyperParams.encFilterSize, pad=1)
net['pool4'] = PoolLayer(net['conv4_3'], 2, ignore_border=ignoreBorder)
net['conv5_1'] = ConvLayer(net['pool4'], 512, hyperParams.encFilterSize, pad=1)
net['conv5_2'] = ConvLayer(net['conv5_1'], 512, hyperParams.encFilterSize, pad=1)
net['conv5_3'] = ConvLayer(net['conv5_2'], 512, hyperParams.encFilterSize, pad=1)
net['pool5'] = PoolLayer(net['conv5_3'], 2, ignore_border=ignoreBorder)
net['fc6'] = DenseLayer(net['pool5'], num_units=4096)
net['fc7'] = DenseLayer(net['fc6'], num_units=4096)
net['fc8'] = DenseLayer(net['fc7'], num_units=1000, nonlinearity=None)
net['prob'] = NonlinearityLayer(net['fc8'], softmax)
# Build decoder (upsampling) part
net['unpool5'] = InverseLayer(net['pool5'], net['pool5'])
net['deconv5_3'] = DeconvLayer(net['conv5_3'], 512, hyperParams.decFilterSize, pad=1)
net['deconv5_2'] = DeconvLayer(net['deconv5_3'], 512, hyperParams.decFilterSize, pad=1)
net['deconv5_1'] = DeconvLayer(net['deconv5_2'], 512, hyperParams.decFilterSize, pad=1)
net['unpool4'] = InverseLayer(net['deconv5_1'], net['pool4'])
net['deconv4_3'] = DeconvLayer(net['unpool4'], 512, hyperParams.decFilterSize, pad=1)
net['deconv4_2'] = DeconvLayer(net['deconv4_3'], 512, hyperParams.decFilterSize, pad=1)
net['deconv4_1'] = DeconvLayer(net['deconv4_2'], 256, hyperParams.decFilterSize, pad=1)
net['unpool3'] = InverseLayer(net['deconv4_1'], net['pool3'])
net['deconv3_3'] = DeconvLayer(net['unpool3'], 256, hyperParams.decFilterSize, pad=1)
net['deconv3_2'] = DeconvLayer(net['deconv3_3'], 256, hyperParams.decFilterSize, pad=1)
net['deconv3_1'] = DeconvLayer(net['deconv3_2'], 128, hyperParams.decFilterSize, pad=1)
net['unpool2'] = InverseLayer(net['deconv3_1'], net['pool2'])
net['deconv2_2'] = DeconvLayer(net['unpool2'], 128, hyperParams.decFilterSize, pad=1)
net['deconv2_1'] = DeconvLayer(net['deconv2_2'], 64, hyperParams.decFilterSize, pad=1)
net['unpool1'] = InverseLayer(net['deconv2_1'], net['pool1'])
net['deconv1_2'] = DeconvLayer(net['unpool1'], 64, hyperParams.decFilterSize, pad=1)
net['deconv1_1'] = DeconvLayer(net['deconv1_2'], 1, hyperParams.decFilterSize, pad=1,
nonlinearity=None)
return netAnyway, does this look like correct usage of the InverseLayer class to you?
Maybe InverseLayer handles such situations?
I hope this should be correct!