Example #1
0
DoubleBuffer2D neo::createDoubleBuffer2D(sys::ComputeSystem &cs, cl_int2 size) {
	DoubleBuffer2D db;
	
	db[_front] = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), size.x, size.y);
	db[_back] = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), size.x, size.y);

	return db;
}
Example #2
0
void HTFE::createRandom(sys::ComputeSystem &cs, sys::ComputeProgram &program, int inputWidth, int inputHeight, const std::vector<LayerDesc> &layerDescs, float minInitWeight, float maxInitWeight) {
    std::mt19937 generator(time(nullptr));

    std::uniform_int_distribution<int> seedDist(0, 99999);

    _inputWidth = inputWidth;
    _inputHeight = inputHeight;

    _layerDescs = layerDescs;

    _layers.resize(_layerDescs.size());

    cl::Kernel initializeLayerHiddenKernel = cl::Kernel(program.getProgram(), "initializeLayerHidden");
    cl::Kernel initializeLayerVisibleKernel = cl::Kernel(program.getProgram(), "initializeLayerVisible");

    _input.clear();
    _input.resize(_inputWidth * _inputHeight, 0.0f);

    _prediction.clear();
    _prediction.resize(_inputWidth * _inputHeight, 0.0f);

    _inputImage = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), _inputWidth, _inputHeight);
    _inputImagePrev = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), _inputWidth, _inputHeight);

    {
        cl_uint4 clear = { 0, 0, 0, 0 };

        cl::size_t<3> origin;
        origin[0] = 0;
        origin[1] = 0;
        origin[2] = 0;

        cl::size_t<3> region;
        region[0] = _inputWidth;
        region[1] = _inputHeight;
        region[2] = 1;

        cs.getQueue().enqueueFillImage(_inputImage, clear, origin, region);
        cs.getQueue().enqueueFillImage(_inputImagePrev, clear, origin, region);
    }

    int prevWidth = _inputWidth;
    int prevHeight = _inputHeight;

    for (int l = 0; l < _layers.size(); l++) {
        int numFeedForwardWeights = std::pow(_layerDescs[l]._receptiveFieldRadius * 2 + 1, 2);
        int numReconstructionWeights = std::pow(_layerDescs[l]._reconstructionRadius * 2 + 1, 2);
        int numLateralWeights = std::pow(_layerDescs[l]._lateralConnectionRadius * 2 + 1, 2);
        int numFeedBackWeights = std::pow(_layerDescs[l]._feedBackConnectionRadius * 2 + 1, 2);

        _layers[l]._hiddenFeedForwardActivations = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_RG, CL_FLOAT), _layerDescs[l]._width, _layerDescs[l]._height);

        _layers[l]._hiddenFeedBackActivations = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_RG, CL_FLOAT), _layerDescs[l]._width, _layerDescs[l]._height);
        _layers[l]._hiddenFeedBackActivationsPrev = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_RG, CL_FLOAT), _layerDescs[l]._width, _layerDescs[l]._height);

        _layers[l]._hiddenStatesFeedForward = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), _layerDescs[l]._width, _layerDescs[l]._height);
        _layers[l]._hiddenStatesFeedForwardPrev = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), _layerDescs[l]._width, _layerDescs[l]._height);

        _layers[l]._hiddenStatesFeedBack = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), _layerDescs[l]._width, _layerDescs[l]._height);
        _layers[l]._hiddenStatesFeedBackPrev = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), _layerDescs[l]._width, _layerDescs[l]._height);
        _layers[l]._hiddenStatesFeedBackPrevPrev = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), _layerDescs[l]._width, _layerDescs[l]._height);

        _layers[l]._feedForwardWeights = cl::Image3D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), _layerDescs[l]._width, _layerDescs[l]._height, numFeedForwardWeights);
        _layers[l]._feedForwardWeightsPrev = cl::Image3D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), _layerDescs[l]._width, _layerDescs[l]._height, numFeedForwardWeights);

        _layers[l]._reconstructionWeights = cl::Image3D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), prevWidth, prevHeight, numReconstructionWeights);
        _layers[l]._reconstructionWeightsPrev = cl::Image3D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), prevWidth, prevHeight, numReconstructionWeights);

        _layers[l]._visibleBiases = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), prevWidth, prevHeight);
        _layers[l]._visibleBiasesPrev = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), prevWidth, prevHeight);

        _layers[l]._hiddenBiases = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), _layerDescs[l]._width, _layerDescs[l]._height);
        _layers[l]._hiddenBiasesPrev = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), _layerDescs[l]._width, _layerDescs[l]._height);

        _layers[l]._lateralWeights = cl::Image3D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), _layerDescs[l]._width, _layerDescs[l]._height, numLateralWeights);
        _layers[l]._lateralWeightsPrev = cl::Image3D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), _layerDescs[l]._width, _layerDescs[l]._height, numLateralWeights);

        _layers[l]._feedBackWeights = cl::Image3D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), _layerDescs[l]._width, _layerDescs[l]._height, numFeedBackWeights);
        _layers[l]._feedBackWeightsPrev = cl::Image3D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), _layerDescs[l]._width, _layerDescs[l]._height, numFeedBackWeights);

        _layers[l]._visibleReconstruction = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), prevWidth, prevHeight);
        _layers[l]._visibleReconstructionPrev = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), prevWidth, prevHeight);

        // Initialize
        Uint2 initSeedHidden;
        initSeedHidden._x = seedDist(generator);
        initSeedHidden._y = seedDist(generator);

        int index = 0;

        initializeLayerHiddenKernel.setArg(index++, _layers[l]._hiddenFeedForwardActivations);
        initializeLayerHiddenKernel.setArg(index++, _layers[l]._hiddenFeedBackActivations);
        initializeLayerHiddenKernel.setArg(index++, _layers[l]._hiddenStatesFeedForward);
        initializeLayerHiddenKernel.setArg(index++, _layers[l]._feedForwardWeights);
        initializeLayerHiddenKernel.setArg(index++, _layers[l]._hiddenBiases);
        initializeLayerHiddenKernel.setArg(index++, _layers[l]._lateralWeights);
        initializeLayerHiddenKernel.setArg(index++, _layers[l]._feedBackWeights);
        initializeLayerHiddenKernel.setArg(index++, numFeedForwardWeights);
        initializeLayerHiddenKernel.setArg(index++, numLateralWeights);
        initializeLayerHiddenKernel.setArg(index++, numFeedBackWeights);
        initializeLayerHiddenKernel.setArg(index++, initSeedHidden);
        initializeLayerHiddenKernel.setArg(index++, _layerDescs[l]._sparsity);
        initializeLayerHiddenKernel.setArg(index++, _layerDescs[l]._lateralScalar);
        initializeLayerHiddenKernel.setArg(index++, _layerDescs[l]._feedBackScalar);
        initializeLayerHiddenKernel.setArg(index++, minInitWeight);
        initializeLayerHiddenKernel.setArg(index++, maxInitWeight);

        cs.getQueue().enqueueNDRangeKernel(initializeLayerHiddenKernel, cl::NullRange, cl::NDRange(_layerDescs[l]._width, _layerDescs[l]._height));

        Uint2 initSeedVisible;
        initSeedVisible._x = seedDist(generator);
        initSeedVisible._y = seedDist(generator);

        index = 0;

        initializeLayerVisibleKernel.setArg(index++, _layers[l]._visibleBiases);
        initializeLayerVisibleKernel.setArg(index++, _layers[l]._visibleReconstruction);
        initializeLayerVisibleKernel.setArg(index++, _layers[l]._reconstructionWeights);
        initializeLayerVisibleKernel.setArg(index++, numReconstructionWeights);
        initializeLayerVisibleKernel.setArg(index++, initSeedVisible);
        initializeLayerVisibleKernel.setArg(index++, minInitWeight);
        initializeLayerVisibleKernel.setArg(index++, maxInitWeight);

        cs.getQueue().enqueueNDRangeKernel(initializeLayerVisibleKernel, cl::NullRange, cl::NDRange(prevWidth, prevHeight));

        {
            cl::size_t<3> origin;
            origin[0] = 0;
            origin[1] = 0;
            origin[2] = 0;

            cl::size_t<3> region;
            region[0] = _layerDescs[l]._width;
            region[1] = _layerDescs[l]._height;
            region[2] = 1;

            cs.getQueue().enqueueCopyImage(_layers[l]._hiddenFeedBackActivations, _layers[l]._hiddenFeedBackActivationsPrev, origin, origin, region);
        }

        {
            cl::size_t<3> origin;
            origin[0] = 0;
            origin[1] = 0;
            origin[2] = 0;

            cl::size_t<3> region;
            region[0] = prevWidth;
            region[1] = prevHeight;
            region[2] = 1;

            cs.getQueue().enqueueCopyImage(_layers[l]._visibleReconstruction, _layers[l]._visibleReconstructionPrev, origin, origin, region);
        }

        {
            cl::size_t<3> origin;
            origin[0] = 0;
            origin[1] = 0;
            origin[2] = 0;

            cl::size_t<3> region;
            region[0] = _layerDescs[l]._width;
            region[1] = _layerDescs[l]._height;
            region[2] = 1;

            cs.getQueue().enqueueCopyImage(_layers[l]._hiddenStatesFeedForward, _layers[l]._hiddenStatesFeedForwardPrev, origin, origin, region);
            cs.getQueue().enqueueCopyImage(_layers[l]._hiddenStatesFeedForward, _layers[l]._hiddenStatesFeedBack, origin, origin, region);
            cs.getQueue().enqueueCopyImage(_layers[l]._hiddenStatesFeedForward, _layers[l]._hiddenStatesFeedBackPrev, origin, origin, region);
            cs.getQueue().enqueueCopyImage(_layers[l]._hiddenStatesFeedForward, _layers[l]._hiddenStatesFeedBackPrevPrev, origin, origin, region);
        }

        {
            cl::size_t<3> origin;
            origin[0] = 0;
            origin[1] = 0;
            origin[2] = 0;

            cl::size_t<3> region;
            region[0] = _layerDescs[l]._width;
            region[1] = _layerDescs[l]._height;
            region[2] = numFeedForwardWeights;

            cs.getQueue().enqueueCopyImage(_layers[l]._feedForwardWeights, _layers[l]._feedForwardWeightsPrev, origin, origin, region);
        }

        {
            cl::size_t<3> origin;
            origin[0] = 0;
            origin[1] = 0;
            origin[2] = 0;

            cl::size_t<3> region;
            region[0] = prevWidth;
            region[1] = prevHeight;
            region[2] = 1;

            cs.getQueue().enqueueCopyImage(_layers[l]._visibleBiases, _layers[l]._visibleBiasesPrev, origin, origin, region);
        }

        {
            cl::size_t<3> origin;
            origin[0] = 0;
            origin[1] = 0;
            origin[2] = 0;

            cl::size_t<3> region;
            region[0] = _layerDescs[l]._width;
            region[1] = _layerDescs[l]._height;
            region[2] = 1;

            cs.getQueue().enqueueCopyImage(_layers[l]._hiddenBiases, _layers[l]._hiddenBiasesPrev, origin, origin, region);
        }

        {
            cl::size_t<3> origin;
            origin[0] = 0;
            origin[1] = 0;
            origin[2] = 0;

            cl::size_t<3> region;
            region[0] = _layerDescs[l]._width;
            region[1] = _layerDescs[l]._height;
            region[2] = numLateralWeights;

            cs.getQueue().enqueueCopyImage(_layers[l]._lateralWeights, _layers[l]._lateralWeightsPrev, origin, origin, region);
        }

        {
            cl::size_t<3> origin;
            origin[0] = 0;
            origin[1] = 0;
            origin[2] = 0;

            cl::size_t<3> region;
            region[0] = _layerDescs[l]._width;
            region[1] = _layerDescs[l]._height;
            region[2] = numFeedBackWeights;

            cs.getQueue().enqueueCopyImage(_layers[l]._feedBackWeights, _layers[l]._feedBackWeightsPrev, origin, origin, region);
        }

        {
            cl::size_t<3> origin;
            origin[0] = 0;
            origin[1] = 0;
            origin[2] = 0;

            cl::size_t<3> region;
            region[0] = prevWidth;
            region[1] = prevHeight;
            region[2] = numReconstructionWeights;

            cs.getQueue().enqueueCopyImage(_layers[l]._reconstructionWeights, _layers[l]._reconstructionWeightsPrev, origin, origin, region);
        }

        prevWidth = _layerDescs[l]._width;
        prevHeight = _layerDescs[l]._height;
    }

    _layerHiddenFeedForwardActivateKernel = cl::Kernel(program.getProgram(), "layerHiddenFeedForwardActivate");
    _layerHiddenFeedBackActivateKernel = cl::Kernel(program.getProgram(), "layerHiddenFeedBackActivate");
    _layerHiddenInhibitKernel = cl::Kernel(program.getProgram(), "layerHiddenInhibit");
    _layerVisibleReconstructKernel = cl::Kernel(program.getProgram(), "layerVisibleReconstruct");
    _layerHiddenWeightUpdateKernel = cl::Kernel(program.getProgram(), "layerHiddenWeightUpdate");
    _layerHiddenWeightUpdateLastKernel = cl::Kernel(program.getProgram(), "layerHiddenWeightUpdateLast");
    _layerVisibleWeightUpdateKernel = cl::Kernel(program.getProgram(), "layerVisibleWeightUpdate");
}
Example #3
0
void AgentSwarm::createRandom(sys::ComputeSystem &cs, sys::ComputeProgram &program,
                              cl_int2 inputSize, cl_int2 actionSize, cl_int firstLayerPredictorRadius, const std::vector<LayerDesc> &layerDescs,
                              cl_float2 initWeightRange,
                              std::mt19937 &rng)
{
    _layerDescs = layerDescs;
    _layers.resize(_layerDescs.size());

    cl_int2 prevLayerSize = inputSize;

    for (int l = 0; l < _layers.size(); l++) {
        std::vector<ComparisonSparseCoder::VisibleLayerDesc> scDescs(2);

        scDescs[0]._size = prevLayerSize;
        scDescs[0]._radius = _layerDescs[l]._feedForwardRadius;
        scDescs[0]._ignoreMiddle = false;
        scDescs[0]._weightAlpha = _layerDescs[l]._scWeightAlpha;
        scDescs[0]._weightLambda = _layerDescs[l]._scWeightLambda;
        scDescs[0]._useTraces = false;

        scDescs[1]._size = _layerDescs[l]._hiddenSize;
        scDescs[1]._radius = _layerDescs[l]._recurrentRadius;
        scDescs[1]._ignoreMiddle = true;
        scDescs[1]._weightAlpha = _layerDescs[l]._scWeightRecurrentAlpha;
        scDescs[1]._weightLambda = _layerDescs[l]._scWeightLambda;
        scDescs[1]._useTraces = false;

        _layers[l]._sc.createRandom(cs, program, scDescs, _layerDescs[l]._hiddenSize, _layerDescs[l]._lateralRadius, initWeightRange, rng);

        _layers[l]._modulatedFeedForwardInput = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), prevLayerSize.x, prevLayerSize.y);

        _layers[l]._modulatedRecurrentInput = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), _layerDescs[l]._hiddenSize.x, _layerDescs[l]._hiddenSize.y);

        std::vector<Predictor::VisibleLayerDesc> predDescs;

        if (l < _layers.size() - 1) {
            predDescs.resize(2);

            predDescs[0]._size = _layerDescs[l]._hiddenSize;
            predDescs[0]._radius = _layerDescs[l]._predictiveRadius;

            predDescs[1]._size = _layerDescs[l + 1]._hiddenSize;
            predDescs[1]._radius = _layerDescs[l]._feedBackRadius;
        }
        else {
            predDescs.resize(1);

            predDescs[0]._size = _layerDescs[l]._hiddenSize;
            predDescs[0]._radius = _layerDescs[l]._predictiveRadius;
        }

        _layers[l]._pred.createRandom(cs, program, predDescs, prevLayerSize, initWeightRange, false, rng);

        std::vector<Swarm::VisibleLayerDesc> swarmDescs;

        if (l == 0) {
            swarmDescs.resize(3);

            swarmDescs[0]._size = inputSize;
            swarmDescs[0]._qRadius = _layerDescs[l]._qRadiusHiddenFeedForwardAttention;
            swarmDescs[0]._startRadius = _layerDescs[l]._startRadiusHiddenFeedForwardAttention;

            swarmDescs[1]._size = _layerDescs[l]._hiddenSize;
            swarmDescs[1]._qRadius = _layerDescs[l]._qRadiusHiddenRecurrentAttention;
            swarmDescs[1]._startRadius = _layerDescs[l]._startRadiusHiddenRecurrentAttention;

            swarmDescs[2]._size = actionSize;
            swarmDescs[2]._qRadius = _layerDescs[l]._qRadiusHiddenAction;
            swarmDescs[2]._startRadius = _layerDescs[l]._startRadiusHiddenAction;
        }
        else {
            swarmDescs.resize(3);

            swarmDescs[0]._size = _layerDescs[l - 1]._hiddenSize;
            swarmDescs[0]._qRadius = _layerDescs[l]._qRadiusHiddenFeedForwardAttention;
            swarmDescs[0]._startRadius = _layerDescs[l]._startRadiusHiddenFeedForwardAttention;

            swarmDescs[1]._size = _layerDescs[l]._hiddenSize;
            swarmDescs[1]._qRadius = _layerDescs[l]._qRadiusHiddenRecurrentAttention;
            swarmDescs[1]._startRadius = _layerDescs[l]._startRadiusHiddenRecurrentAttention;

            swarmDescs[2]._size = _layerDescs[l - 1]._hiddenSize;
            swarmDescs[2]._qRadius = _layerDescs[l]._qRadiusHiddenAction;
            swarmDescs[2]._startRadius = _layerDescs[l]._startRadiusHiddenAction;
        }

        _layers[l]._swarm.createRandom(cs, program, swarmDescs, _layerDescs[l]._qSize, _layerDescs[l]._hiddenSize, _layerDescs[l]._qRadius, initWeightRange, rng);

        // Create baselines
        _layers[l]._baseLines = createDoubleBuffer2D(cs, _layerDescs[l]._hiddenSize, CL_R, CL_FLOAT);

        _layers[l]._reward = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), _layerDescs[l]._hiddenSize.x, _layerDescs[l]._hiddenSize.y);

        _layers[l]._scHiddenStatesPrev = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), _layerDescs[l]._hiddenSize.x, _layerDescs[l]._hiddenSize.y);

        cl_float4 zeroColor = { 0.0f, 0.0f, 0.0f, 0.0f };

        cl::array<cl::size_type, 3> zeroOrigin = { 0, 0, 0 };

        if (l != 0) {
            cl::array<cl::size_type, 3> actionRegion = { _layers[l]._swarm.getVisibleLayerDesc(2)._size.x, _layers[l]._swarm.getVisibleLayerDesc(2)._size.y, 1 };

            _layers[l]._inhibitedAction = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), swarmDescs[1]._size.x, swarmDescs[1]._size.y);

            cs.getQueue().enqueueFillImage(_layers[l]._inhibitedAction, zeroColor, zeroOrigin, actionRegion);
        }

        cl::array<cl::size_type, 3> layerRegion = { _layerDescs[l]._hiddenSize.x, _layerDescs[l]._hiddenSize.y, 1 };

        cs.getQueue().enqueueFillImage(_layers[l]._baseLines[_back], zeroColor, zeroOrigin, layerRegion);
        cs.getQueue().enqueueFillImage(_layers[l]._reward, zeroColor, zeroOrigin, layerRegion);
        cs.getQueue().enqueueFillImage(_layers[l]._scHiddenStatesPrev, zeroColor, zeroOrigin, layerRegion);

        prevLayerSize = _layerDescs[l]._hiddenSize;
    }

    {
        cl_float4 zeroColor = { 0.0f, 0.0f, 0.0f, 0.0f };

        cl::array<cl::size_type, 3> zeroOrigin = { 0, 0, 0 };
        cl::array<cl::size_type, 3> layerRegion = { _layerDescs.back()._hiddenSize.x, _layerDescs.back()._hiddenSize.y, 1 };

        _lastLayerAction = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), _layerDescs.back()._hiddenSize.x, _layerDescs.back()._hiddenSize.y);

        cs.getQueue().enqueueFillImage(_lastLayerAction, zeroColor, zeroOrigin, layerRegion);
    }

    _baseLineUpdateKernel = cl::Kernel(program.getProgram(), "phBaseLineUpdate");
    _baseLineUpdateSumErrorKernel = cl::Kernel(program.getProgram(), "phBaseLineUpdateSumError");
    _inhibitKernel = cl::Kernel(program.getProgram(), "phInhibit");
    _modulateKernel = cl::Kernel(program.getProgram(), "phModulate");
}
Example #4
0
void AgentER::createRandom(sys::ComputeSystem &cs, sys::ComputeProgram &program,
	cl_int2 inputSize, cl_int2 actionSize, cl_int2 qSize,
	const std::vector<LayerDesc> &layerDescs,
	cl_float2 initWeightRange,
	std::mt19937 &rng)
{
	_inputSize = inputSize;
	_actionSize = actionSize;
	_qSize = qSize;

	_layerDescs = layerDescs;
	_layers.resize(_layerDescs.size());

	cl::Kernel randomUniform2DXYKernel = cl::Kernel(program.getProgram(), "randomUniform2DXY");

	cl_int2 prevLayerSize = inputSize;

	for (int l = 0; l < _layers.size(); l++) {
		std::vector<ComparisonSparseCoder::VisibleLayerDesc> scDescs;

		if (l == 0) {
			scDescs.resize(3);

			scDescs[0]._size = prevLayerSize;
			scDescs[0]._radius = _layerDescs[l]._feedForwardRadius;
			scDescs[0]._ignoreMiddle = false;
			scDescs[0]._weightAlpha = _layerDescs[l]._scWeightAlpha;
			scDescs[0]._useTraces = false;

			scDescs[1]._size = _actionSize;
			scDescs[1]._radius = _layerDescs[l]._feedForwardRadius;
			scDescs[1]._ignoreMiddle = false;
			scDescs[1]._weightAlpha = _layerDescs[l]._scWeightAlpha;
			scDescs[1]._useTraces = false;

			scDescs[2]._size = _qSize;
			scDescs[2]._radius = _layerDescs[l]._feedForwardRadius;
			scDescs[2]._ignoreMiddle = false;
			scDescs[2]._weightAlpha = _layerDescs[l]._scWeightAlpha;
			scDescs[2]._useTraces = false;
		}
		else {
			scDescs.resize(2);

			scDescs[0]._size = prevLayerSize;
			scDescs[0]._radius = _layerDescs[l]._feedForwardRadius;
			scDescs[0]._ignoreMiddle = false;
			scDescs[0]._weightAlpha = _layerDescs[l]._scWeightAlpha;
			scDescs[0]._useTraces = false;

			scDescs[1]._size = _layerDescs[l]._size;
			scDescs[1]._radius = _layerDescs[l]._recurrentRadius;
			scDescs[1]._ignoreMiddle = true;
			scDescs[1]._weightAlpha = _layerDescs[l]._scWeightRecurrentAlpha;
			scDescs[1]._useTraces = false;
		}

		_layers[l]._sc.createRandom(cs, program, scDescs, _layerDescs[l]._size, _layerDescs[l]._lateralRadius, initWeightRange, rng);

		std::vector<Predictor::VisibleLayerDesc> predDescs;

		if (l < _layers.size() - 1) {
			predDescs.resize(2);

			predDescs[0]._size = _layerDescs[l]._size;
			predDescs[0]._radius = _layerDescs[l]._predictiveRadius;

			predDescs[1]._size = _layerDescs[l + 1]._size;
			predDescs[1]._radius = _layerDescs[l]._feedBackRadius;
		}
		else {
			predDescs.resize(1);

			predDescs[0]._size = _layerDescs[l]._size;
			predDescs[0]._radius = _layerDescs[l]._predictiveRadius;
		}

		if (l == 0)
			_layers[l]._pred.createRandom(cs, program, predDescs, _actionSize, initWeightRange, true, rng);
		else
			_layers[l]._pred.createRandom(cs, program, predDescs, _layerDescs[l - 1]._size, initWeightRange, true, rng);

		// Create baselines
		_layers[l]._predReward = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), _layerDescs[l]._size.x, _layerDescs[l]._size.y);
		_layers[l]._propagatedPredReward = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), _layerDescs[l]._size.x, _layerDescs[l]._size.y);

		cl_float4 zeroColor = { 0.0f, 0.0f, 0.0f, 0.0f };

		cl::array<cl::size_type, 3> zeroOrigin = { 0, 0, 0 };
		cl::array<cl::size_type, 3> layerRegion = { _layerDescs[l]._size.x, _layerDescs[l]._size.y, 1 };

		cs.getQueue().enqueueFillImage(_layers[l]._predReward, zeroColor, zeroOrigin, layerRegion);
		cs.getQueue().enqueueFillImage(_layers[l]._propagatedPredReward, zeroColor, zeroOrigin, layerRegion);

		_layers[l]._scStatesTemp = createDoubleBuffer2D(cs, _layerDescs[l]._size, CL_R, CL_FLOAT);
		_layers[l]._predStatesTemp = createDoubleBuffer2D(cs, prevLayerSize, CL_R, CL_FLOAT);

		prevLayerSize = _layerDescs[l]._size;
	}

	_qInput = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), _qSize.x, _qSize.y);

	_qTarget = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), _qSize.x, _qSize.y);

	_actionTarget = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), _actionSize.x, _actionSize.y);

	_qTransform = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_RG, CL_FLOAT), _qSize.x, _qSize.y);

	// Q Predictor
	{
		std::vector<Predictor::VisibleLayerDesc> predDescs;

		if (0 < _layers.size() - 1) {
			predDescs.resize(2);

			predDescs[0]._size = _layerDescs[0]._size;
			predDescs[0]._radius = _layerDescs[0]._predictiveRadius;

			predDescs[1]._size = _layerDescs[0 + 1]._size;
			predDescs[1]._radius = _layerDescs[0]._feedBackRadius;
		}
		else {
			predDescs.resize(1);

			predDescs[0]._size = _layerDescs[0]._size;
			predDescs[0]._radius = _layerDescs[0]._predictiveRadius;
		}

		_qPred.createRandom(cs, program, predDescs, _qSize, initWeightRange, true, rng);
	}

	// Random Q transform
	randomUniformXY(_qTransform, cs, randomUniform2DXYKernel, _qSize, { -1.0f, 1.0f }, rng);

	_inputWhitener.create(cs, program, _inputSize, CL_R, CL_FLOAT);
	_actionWhitener.create(cs, program, _actionSize, CL_R, CL_FLOAT);
	_qWhitener.create(cs, program, _qSize, CL_R, CL_FLOAT);

	_predictionRewardKernel = cl::Kernel(program.getProgram(), "phPredictionReward");
	_predictionRewardPropagationKernel = cl::Kernel(program.getProgram(), "phPredictionRewardPropagation");
	_setQKernel = cl::Kernel(program.getProgram(), "phSetQ");
}
Example #5
0
void HEInet::createRandom(const std::vector<EIlayer::Configuration> &eilConfigs,
	int predictionRadiusFromE, int predictionRadiusFromI,
	float minInitEWeight, float maxInitEWeight,
	float minInitIWeight, float maxInitIWeight,
	float initEThreshold, float initIThreshold,
	float sparsityE, float sparsityI,
	sys::ComputeSystem &cs, const std::shared_ptr<EIlayer::Kernels> &eilKernels,
	const std::shared_ptr<Kernels> &heiKernels, std::mt19937 &generator)
{
	_kernels = heiKernels;
	_predictionRadiusFromE = predictionRadiusFromE;
	_predictionRadiusFromI = predictionRadiusFromI;

	_eiLayers.resize(eilConfigs.size());

	// Initialize all layers
	for (int li = 0; li < _eiLayers.size(); li++) {
		_eiLayers[li].createRandom(eilConfigs[li],
			minInitEWeight, maxInitEWeight, minInitIWeight, maxInitIWeight,
			initEThreshold, initIThreshold,
			sparsityE, sparsityI,
			cs, eilKernels, generator);
	}

	int predictionFromESize = std::pow(_predictionRadiusFromE * 2 + 1, 2);
	int predictionFromISize = std::pow(_predictionRadiusFromI * 2 + 1, 2);

	_prediction = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), eilConfigs.front()._eFeedForwardWidth, eilConfigs.front()._eFeedForwardHeight);
	_predictionPrev = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), eilConfigs.front()._eFeedForwardWidth, eilConfigs.front()._eFeedForwardHeight);

	_inputSpikes = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), eilConfigs.front()._eFeedForwardWidth, eilConfigs.front()._eFeedForwardHeight);
	_inputSpikesPrev = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), eilConfigs.front()._eFeedForwardWidth, eilConfigs.front()._eFeedForwardHeight);

	_inputSpikesHistory = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), eilConfigs.front()._eFeedForwardWidth, eilConfigs.front()._eFeedForwardHeight);
	_inputSpikesHistoryPrev = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), eilConfigs.front()._eFeedForwardWidth, eilConfigs.front()._eFeedForwardHeight);

	_inputSpikeTimers = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), eilConfigs.front()._eFeedForwardWidth, eilConfigs.front()._eFeedForwardHeight);
	_inputSpikeTimersPrev = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), eilConfigs.front()._eFeedForwardWidth, eilConfigs.front()._eFeedForwardHeight);

	_eSpikeSums = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), eilConfigs.front()._eWidth, eilConfigs.front()._eHeight);
	_eSpikeSumsPrev = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), eilConfigs.front()._eWidth, eilConfigs.front()._eHeight);
	
	_iSpikeSums = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), eilConfigs.front()._iWidth, eilConfigs.front()._iHeight);
	_iSpikeSumsPrev = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), eilConfigs.front()._iWidth, eilConfigs.front()._iHeight);

	_eSpikeSumsIterPrev = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), eilConfigs.front()._eWidth, eilConfigs.front()._eHeight);
	_iSpikeSumsIterPrev = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), eilConfigs.front()._iWidth, eilConfigs.front()._iHeight);

	cl_float4 zeroColor = { 0.0f, 0.0f, 0.0f, 0.0f };

	cl::size_t<3> zeroCoord;
	zeroCoord[0] = zeroCoord[1] = zeroCoord[2] = 0;

	cl::size_t<3> eFeedForwardDimsCoord;
	eFeedForwardDimsCoord[0] = eilConfigs.front()._eFeedForwardWidth;
	eFeedForwardDimsCoord[1] = eilConfigs.front()._eFeedForwardHeight;
	eFeedForwardDimsCoord[2] = 1;

	cl::size_t<3> ePredictionWeightsDims;
	ePredictionWeightsDims[0] = eilConfigs.front()._eFeedForwardWidth;
	ePredictionWeightsDims[1] = eilConfigs.front()._eFeedForwardHeight;
	ePredictionWeightsDims[2] = predictionFromESize;

	cl::size_t<3> iPredictionWeightsDims;
	iPredictionWeightsDims[0] = eilConfigs.front()._eFeedForwardWidth;
	iPredictionWeightsDims[1] = eilConfigs.front()._eFeedForwardHeight;
	iPredictionWeightsDims[2] = predictionFromISize;

	cl::size_t<3> eDims;
	eDims[0] = eilConfigs.front()._eWidth;
	eDims[1] = eilConfigs.front()._eHeight;
	eDims[2] = 1;

	cl::size_t<3> iDims;
	iDims[0] = eilConfigs.front()._iWidth;
	iDims[1] = eilConfigs.front()._iHeight;
	iDims[2] = 1;

	cs.getQueue().enqueueFillImage(_prediction, zeroColor, zeroCoord, eFeedForwardDimsCoord);
	cs.getQueue().enqueueFillImage(_predictionPrev, zeroColor, zeroCoord, eFeedForwardDimsCoord);

	cs.getQueue().enqueueFillImage(_inputSpikes, zeroColor, zeroCoord, eFeedForwardDimsCoord);
	cs.getQueue().enqueueFillImage(_inputSpikesPrev, zeroColor, zeroCoord, eFeedForwardDimsCoord);

	cs.getQueue().enqueueFillImage(_inputSpikesHistory, zeroColor, zeroCoord, eFeedForwardDimsCoord);
	cs.getQueue().enqueueFillImage(_inputSpikesHistoryPrev, zeroColor, zeroCoord, eFeedForwardDimsCoord);

	cs.getQueue().enqueueFillImage(_inputSpikeTimers, zeroColor, zeroCoord, eFeedForwardDimsCoord);
	cs.getQueue().enqueueFillImage(_inputSpikeTimersPrev, zeroColor, zeroCoord, eFeedForwardDimsCoord);

	cs.getQueue().enqueueFillImage(_eSpikeSums, zeroColor, zeroCoord, eDims);
	cs.getQueue().enqueueFillImage(_eSpikeSumsPrev, zeroColor, zeroCoord, eDims);
	cs.getQueue().enqueueFillImage(_iSpikeSums, zeroColor, zeroCoord, iDims);
	cs.getQueue().enqueueFillImage(_iSpikeSumsPrev, zeroColor, zeroCoord, iDims);
	cs.getQueue().enqueueFillImage(_eSpikeSumsIterPrev, zeroColor, zeroCoord, eDims);
	cs.getQueue().enqueueFillImage(_iSpikeSumsIterPrev, zeroColor, zeroCoord, iDims);

	_predictionFromEWeights._weights = cl::Image3D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), eilConfigs.front()._eFeedForwardWidth, eilConfigs.front()._eFeedForwardHeight, predictionFromESize);
	_predictionFromEWeights._weightsPrev = cl::Image3D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), eilConfigs.front()._eFeedForwardWidth, eilConfigs.front()._eFeedForwardHeight, predictionFromESize);
	
	_predictionFromIWeights._weights = cl::Image3D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), eilConfigs.front()._eFeedForwardWidth, eilConfigs.front()._eFeedForwardHeight, predictionFromISize);
	_predictionFromIWeights._weightsPrev = cl::Image3D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), eilConfigs.front()._eFeedForwardWidth, eilConfigs.front()._eFeedForwardHeight, predictionFromISize);

	std::uniform_int_distribution<int> seedDist(0, 10000);

	cl_uint2 seed = { seedDist(generator), seedDist(generator) };

	int index = 0;

	_kernels->_predictionInitializeKernel.setArg(index++, _predictionFromEWeights._weightsPrev);
	_kernels->_predictionInitializeKernel.setArg(index++, _predictionFromIWeights._weightsPrev);
	_kernels->_predictionInitializeKernel.setArg(index++, predictionFromESize);
	_kernels->_predictionInitializeKernel.setArg(index++, predictionFromISize);
	_kernels->_predictionInitializeKernel.setArg(index++, minInitEWeight);
	_kernels->_predictionInitializeKernel.setArg(index++, maxInitEWeight);
	_kernels->_predictionInitializeKernel.setArg(index++, seed);

	cs.getQueue().enqueueNDRangeKernel(_kernels->_predictionInitializeKernel, cl::NullRange, cl::NDRange(eilConfigs.front()._eFeedForwardWidth, eilConfigs.front()._eFeedForwardHeight));

	cs.getQueue().enqueueCopyImage(_predictionFromEWeights._weightsPrev, _predictionFromEWeights._weights, zeroCoord, zeroCoord, ePredictionWeightsDims);
	cs.getQueue().enqueueCopyImage(_predictionFromIWeights._weightsPrev, _predictionFromIWeights._weights, zeroCoord, zeroCoord, iPredictionWeightsDims);
}
Example #6
0
void BIDInet::createRandom(sys::ComputeSystem &cs, sys::ComputeProgram &program, int inputWidth, int inputHeight, const std::vector<LayerDesc> &layerDescs, float initMinWeight, float initMaxWeight, std::mt19937 &generator) {
	_inputWidth = inputWidth;
	_inputHeight = inputHeight;

	int numInputs = inputWidth * inputHeight;

	// Inputs
	_inputs = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), _inputWidth, _inputHeight);

	_inputsTemp.clear();
	_inputsTemp.assign(numInputs, 0.0f);

	_outputsTemp.clear();
	_outputsTemp.assign(numInputs, 0.0f);

	// Q connections
	std::uniform_real_distribution<float> initWeightDist(initMinWeight, initMaxWeight);

	_layerDescs = layerDescs;

	_layers.resize(_layerDescs.size());

	cl::Kernel initializeConnectionsKernel = cl::Kernel(program.getProgram(), "initializeConnections");

	std::uniform_int_distribution<int> seedDist(0, 10000);

	int prevLayerWidth = _inputWidth;
	int prevLayerHeight = _inputHeight;

	for (int l = 0; l < _layers.size(); l++) {
		Layer &layer = _layers[l];

		LayerDesc &layerDesc = _layerDescs[l];

		int ffDiam = layerDesc._ffRadius * 2 + 1;
		int lDiam = layerDesc._lRadius * 2 + 1;
		int recDiam = layerDesc._recRadius * 2 + 1;
		int fbDiam = layerDesc._fbRadius * 2 + 1;
		int predDiam = layerDesc._predRadius * 2 + 1;

		// + 1 for biases (if applicable)
		int ffSize = ffDiam * ffDiam + 1;
		int lSize = lDiam * lDiam;
		int recSize = recDiam * recDiam;
		int fbSize = fbDiam * fbDiam + 1;
		int predSize = predDiam * predDiam;

		cl::array<cl::size_type, 3> zeroOrigin = { 0, 0, 0 };
		cl::array<cl::size_type, 3> layerRegion = { layerDesc._width, layerDesc._height, 1 };
		cl::array<cl::size_type, 3> prevLayerRegion = { prevLayerWidth, prevLayerHeight, 1 };

		cl_uint4 zeroColor = { 0, 0, 0, 0 };
		
		// Activations
		layer._ffActivations = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), layerDesc._width, layerDesc._height);
		layer._fbActivations = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), prevLayerWidth,prevLayerHeight);
		layer._fbActivationsExploratory = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), prevLayerWidth, prevLayerHeight);

		// Reconstruction
		layer._ffReconstruction = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), prevLayerWidth, prevLayerHeight);

		layer._recReconstruction = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), layerDesc._width, layerDesc._height);

		// States
		layer._ffStates = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), layerDesc._width, layerDesc._height);
		layer._ffStatesPrev = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), layerDesc._width, layerDesc._height);

		cs.getQueue().enqueueFillImage(layer._ffStatesPrev, zeroColor, zeroOrigin, layerRegion);

		layer._fbStates = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), prevLayerWidth, prevLayerHeight);
		layer._fbStatesExploratory = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), prevLayerWidth, prevLayerHeight);
		layer._fbStatesPrev = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), prevLayerWidth, prevLayerHeight);
		layer._fbStatesExploratoryPrev = cl::Image2D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), prevLayerWidth, prevLayerHeight);

		cs.getQueue().enqueueFillImage(layer._fbStatesPrev, zeroColor, zeroOrigin, prevLayerRegion);
		cs.getQueue().enqueueFillImage(layer._fbStatesExploratoryPrev, zeroColor, zeroOrigin, prevLayerRegion);

		// Connections
		{
			layer._ffConnections = cl::Image3D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), layerDesc._width, layerDesc._height, ffSize);
			layer._ffConnectionsPrev = cl::Image3D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), layerDesc._width, layerDesc._height, ffSize);

			int argIndex = 0;

			cl_uint2 seed = { seedDist(generator), seedDist(generator) };

			initializeConnectionsKernel.setArg(argIndex++, layer._ffConnectionsPrev);
			initializeConnectionsKernel.setArg(argIndex++, ffSize);
			initializeConnectionsKernel.setArg(argIndex++, seed);
			initializeConnectionsKernel.setArg(argIndex++, initMinWeight);
			initializeConnectionsKernel.setArg(argIndex++, initMaxWeight);
		
			cs.getQueue().enqueueNDRangeKernel(initializeConnectionsKernel, cl::NullRange, cl::NDRange(layerDesc._width, layerDesc._height));
		}

		{
			layer._recConnections = cl::Image3D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), layerDesc._width, layerDesc._height, recSize);
			layer._recConnectionsPrev = cl::Image3D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_R, CL_FLOAT), layerDesc._width, layerDesc._height, recSize);

			int argIndex = 0;

			cl_uint2 seed = { seedDist(generator), seedDist(generator) };

			initializeConnectionsKernel.setArg(argIndex++, layer._recConnectionsPrev);
			initializeConnectionsKernel.setArg(argIndex++, recSize);
			initializeConnectionsKernel.setArg(argIndex++, seed);
			initializeConnectionsKernel.setArg(argIndex++, initMinWeight);
			initializeConnectionsKernel.setArg(argIndex++, initMaxWeight);

			cs.getQueue().enqueueNDRangeKernel(initializeConnectionsKernel, cl::NullRange, cl::NDRange(layerDesc._width, layerDesc._height));
		}

		{
			layer._fbConnections = cl::Image3D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_RG, CL_FLOAT), prevLayerWidth, prevLayerHeight, fbSize);
			layer._fbConnectionsPrev = cl::Image3D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_RG, CL_FLOAT), prevLayerWidth, prevLayerHeight, fbSize);

			int argIndex = 0;

			cl_uint2 seed = { seedDist(generator), seedDist(generator) };

			initializeConnectionsKernel.setArg(argIndex++, layer._fbConnectionsPrev);
			initializeConnectionsKernel.setArg(argIndex++, fbSize);
			initializeConnectionsKernel.setArg(argIndex++, seed);
			initializeConnectionsKernel.setArg(argIndex++, initMinWeight);
			initializeConnectionsKernel.setArg(argIndex++, initMaxWeight);

			cs.getQueue().enqueueNDRangeKernel(initializeConnectionsKernel, cl::NullRange, cl::NDRange(prevLayerWidth, prevLayerHeight));
		}

		{
			layer._predConnections = cl::Image3D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_RG, CL_FLOAT), prevLayerWidth, prevLayerHeight, predSize);
			layer._predConnectionsPrev = cl::Image3D(cs.getContext(), CL_MEM_READ_WRITE, cl::ImageFormat(CL_RG, CL_FLOAT), prevLayerWidth, prevLayerHeight, predSize);

			int argIndex = 0;

			cl_uint2 seed = { seedDist(generator), seedDist(generator) };

			initializeConnectionsKernel.setArg(argIndex++, layer._predConnectionsPrev);
			initializeConnectionsKernel.setArg(argIndex++, predSize);
			initializeConnectionsKernel.setArg(argIndex++, seed);
			initializeConnectionsKernel.setArg(argIndex++, initMinWeight);
			initializeConnectionsKernel.setArg(argIndex++, initMaxWeight);

			cs.getQueue().enqueueNDRangeKernel(initializeConnectionsKernel, cl::NullRange, cl::NDRange(prevLayerWidth, prevLayerHeight));
		}

		// Update prevs
		prevLayerWidth = layerDesc._width;
		prevLayerHeight = layerDesc._height;
	}

	// Get kernels
	_ffActivateKernel = cl::Kernel(program.getProgram(), "ffActivate");
	_ffInhibitKernel = cl::Kernel(program.getProgram(), "ffInhibit");
	_fbActivateKernel = cl::Kernel(program.getProgram(), "fbActivate");
	_fbActivateFirstKernel = cl::Kernel(program.getProgram(), "fbActivateFirst");
	_ffReconstructKernel = cl::Kernel(program.getProgram(), "ffReconstruct");
	_recReconstructKernel = cl::Kernel(program.getProgram(), "recReconstruct");
	_ffConnectionUpdateKernel = cl::Kernel(program.getProgram(), "ffConnectionUpdate");
	_recConnectionUpdateKernel = cl::Kernel(program.getProgram(), "recConnectionUpdate");
	_fbConnectionUpdateKernel = cl::Kernel(program.getProgram(), "fbConnectionUpdate");
	_predConnectionUpdateKernel = cl::Kernel(program.getProgram(), "predConnectionUpdate");
}