/**
 * Copyright 2013 Neuroph Project http://neuroph.sourceforge.net
 *
 * 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.
 */
package org.neuroph.nnet.comp.layer;

import org.neuroph.nnet.comp.Kernel;
import org.neuroph.core.Neuron;
import org.neuroph.core.Weight;
import org.neuroph.core.input.Max;
import org.neuroph.core.transfer.Ramp;
import org.neuroph.core.transfer.Tanh;
import org.neuroph.nnet.comp.Dimension2D;
import org.neuroph.util.ConnectionFactory;
import org.neuroph.util.NeuronProperties;

/**
 * Pooling layer is a special type of feature maps layer (FeatureMapsLayer)
 * which is used in convolutional networks. It contains neurons with max input
 * function and method for creating pooling layer specific conectivity patterns.
 * The role of pooling layer is dimensionality and complexity reduction,
 * while it keeps essential information.
 *
 * @author Boris Fulurija
 * @author Zoran Sevarac
 * @see FeatureMapsLayer
 */
public class PoolingLayer extends FeatureMapsLayer {

    private static final long serialVersionUID = -6771501759374920878L;
    
    private Kernel kernel;

    /**
     * Default neuron properties for pooling layer
     */
    public static final NeuronProperties DEFAULT_NEURON_PROP = new NeuronProperties();

    static {
        DEFAULT_NEURON_PROP.setProperty("useBias", true);
        DEFAULT_NEURON_PROP.setProperty("transferFunction", Tanh.class);
    //    DEFAULT_NEURON_PROP.setProperty("transferFunction", Ramp.class);
        DEFAULT_NEURON_PROP.setProperty("inputFunction", Max.class);
    }

    /**
     * Creates pooling layer with specified kernel, appropriate map
     * dimensions in regard to previous layer (fromLayer param) and specified
     * number of feature maps with default neuron settings for pooling layer.
     * Number of maps in pooling layer must be the same as number of maps in previous
     * layer.
     *
     * @param fromLayer previous layer, which will be connected to this layer
     * @param kernel    kernel for all feature maps
     */
    public PoolingLayer(FeatureMapsLayer fromLayer, Dimension2D kernelDim) {
        this.kernel = new Kernel(kernelDim);
        int numberOfMaps = fromLayer.getNumberOfMaps();
        Dimension2D fromDimension = fromLayer.getMapDimensions();

        int mapWidth = fromDimension.getWidth() / kernel.getWidth();
        int mapHeight = fromDimension.getHeight() / kernel.getHeight();
        this.mapDimensions = new Dimension2D(mapWidth, mapHeight);

        createFeatureMaps(numberOfMaps, mapDimensions, kernelDim, DEFAULT_NEURON_PROP);
    }

    /**
     * Creates pooling layer with specified kernel, appropriate map
     * dimensions in regard to previous layer (fromLayer param) and specified
     * number of feature maps with given neuron properties.
     *
     * @param fromLayer    previous layer, which will be connected to this layer
     * @param kernel       kernel for all feature maps
     * @param numberOfMaps number of feature maps to create in this layer
     * @param neuronProp   settings for neurons in feature maps
     */
    public PoolingLayer(FeatureMapsLayer fromLayer, Dimension2D kernelDim, int numberOfMaps, NeuronProperties neuronProp) {
        this.kernel = kernel;
        Dimension2D fromDimension = fromLayer.getMapDimensions();

        int mapWidth = fromDimension.getWidth() / kernel.getWidth();
        int mapHeight = fromDimension.getHeight() / kernel.getHeight();
        this.mapDimensions = new Dimension2D(mapWidth, mapHeight);

        createFeatureMaps(numberOfMaps, mapDimensions, kernelDim, neuronProp);
    }

    /**
     * Creates connections with shared weights between two feature maps
     * Assumes that toMap is from Pooling layer.
     * 

* In this implementation, there is no overlapping between kernel positions. * * @param fromMap source feature map * @param toMap destination feature map */ @Override public void connectMaps(FeatureMapLayer fromMap, FeatureMapLayer toMap) { int kernelWidth = kernel.getWidth(); int kernelHeight = kernel.getHeight(); Weight weight = new Weight(1); for (int x = 0; x < fromMap.getWidth() - kernelWidth + 1; x += kernelWidth) { // < da li step treba da je kernel for (int y = 0; y < fromMap.getHeight() - kernelHeight + 1; y += kernelHeight) { Neuron toNeuron = toMap.getNeuronAt(x / kernelWidth, y / kernelHeight); for (int dy = 0; dy < kernelHeight; dy++) { for (int dx = 0; dx < kernelWidth; dx++) { int fromX = x + dx; int fromY = y + dy; Neuron fromNeuron = fromMap.getNeuronAt(fromX, fromY); ConnectionFactory.createConnection(fromNeuron, toNeuron, weight); } } } } } }

Ads help maintain this website.