diff --git a/src/backends/reference/workloads/TransposeConvolution2d.cpp b/src/backends/reference/workloads/TransposeConvolution2d.cpp
index db15cef..b633d0d 100644
--- a/src/backends/reference/workloads/TransposeConvolution2d.cpp
+++ b/src/backends/reference/workloads/TransposeConvolution2d.cpp
@@ -12,162 +12,6 @@
 
 using namespace armnnUtils;
 
-struct TensorData
-{
-    TensorShape        shape;
-    std::vector<float> data;
-};
-
-TensorData SetUpStridedInput(const TensorShape& inputShape,
-                             Decoder<float>& inputDecoder,
-                             const TransposeConvolution2dDescriptor& descriptor,
-                             const DataLayoutIndexed& dataLayoutIndexed)
-{
-    const unsigned int cIndex = dataLayoutIndexed.GetChannelsIndex();
-    const unsigned int hIndex = dataLayoutIndexed.GetHeightIndex();
-    const unsigned int wIndex = dataLayoutIndexed.GetWidthIndex();
-
-    const unsigned int batches  = inputShape[0];
-    const unsigned int channels = inputShape[cIndex];
-
-    const unsigned int wInput = inputShape[wIndex];
-    const unsigned int hInput = inputShape[hIndex];
-
-    const unsigned int wStridedInput = 1u + descriptor.m_StrideX * (wInput - 1);
-    const unsigned int hStridedInput = 1u + descriptor.m_StrideY * (hInput - 1);
-
-    TensorData stridedInput;
-    stridedInput.data  = std::vector<float>(batches * channels * wStridedInput * hStridedInput, 0.0f);
-    stridedInput.shape = TensorShape(4);
-
-    stridedInput.shape[0]      = batches;
-    stridedInput.shape[cIndex] = channels;
-    stridedInput.shape[hIndex] = hStridedInput;
-    stridedInput.shape[wIndex] = wStridedInput;
-
-    // expand input data with strides
-    for (unsigned int batchIdx = 0u; batchIdx < batches; ++batchIdx)
-    {
-        for (unsigned int cInput = 0u; cInput < channels; ++cInput)
-        {
-            for (unsigned int yInput = 0u, yStrided = 0u;
-                 yInput < hInput && yStrided < hStridedInput;
-                 ++yInput, yStrided += descriptor.m_StrideY)
-            {
-                for (unsigned int xInput = 0u, xStrided = 0u;
-                     xInput < wInput && xStrided < wStridedInput;
-                     ++xInput, xStrided += descriptor.m_StrideX)
-                {
-                    unsigned int inputIdx =
-                        dataLayoutIndexed.GetIndex(inputShape, batchIdx, cInput, yInput, xInput);
-                    unsigned int stridedInputIdx =
-                        dataLayoutIndexed.GetIndex(stridedInput.shape, batchIdx, cInput, yStrided, xStrided);
-
-                    inputDecoder[inputIdx];
-                    stridedInput.data[stridedInputIdx] = inputDecoder.Get();
-                }
-            }
-        }
-    }
-
-    return stridedInput;
-}
-
-TensorData SetUpEmptyPaddedOutput(const TensorShape& outputShape,
-                                  const TransposeConvolution2dDescriptor& descriptor,
-                                  const DataLayoutIndexed& dataLayoutIndexed)
-{
-    const unsigned int cIndex = dataLayoutIndexed.GetChannelsIndex();
-    const unsigned int hIndex = dataLayoutIndexed.GetHeightIndex();
-    const unsigned int wIndex = dataLayoutIndexed.GetWidthIndex();
-
-    const unsigned int batches  = outputShape[0];
-    const unsigned int channels = outputShape[cIndex];
-
-    const unsigned int wOutput = outputShape[wIndex];
-    const unsigned int hOutput = outputShape[hIndex];
-
-    const unsigned int wPaddedOutput = wOutput + descriptor.m_PadLeft + descriptor.m_PadRight;
-    const unsigned int hPaddedOutput = hOutput + descriptor.m_PadTop  + descriptor.m_PadBottom;
-
-    TensorData paddedOutput;
-    paddedOutput.data  = std::vector<float>(batches * channels * wPaddedOutput * hPaddedOutput, 0.0f);
-    paddedOutput.shape = TensorShape(4);
-
-    paddedOutput.shape[0]      = batches;
-    paddedOutput.shape[cIndex] = channels;
-    paddedOutput.shape[hIndex] = hPaddedOutput;
-    paddedOutput.shape[wIndex] = wPaddedOutput;
-
-    return paddedOutput;
-}
-
-void Deconvolve(const TensorData& stridedInput,
-                TensorData& paddedOutput,
-                const TensorShape& weightsShape,
-                Decoder<float>& weightsDecoder,
-                const DataLayoutIndexed& dataLayoutIndexed)
-{
-    const unsigned int cIndex = dataLayoutIndexed.GetChannelsIndex();
-    const unsigned int hIndex = dataLayoutIndexed.GetHeightIndex();
-    const unsigned int wIndex = dataLayoutIndexed.GetWidthIndex();
-
-    const unsigned int batches  = stridedInput.shape[0];
-    const unsigned int channels = stridedInput.shape[cIndex];
-
-    const unsigned int wKernel = weightsShape[wIndex];
-    const unsigned int hKernel = weightsShape[hIndex];
-
-    const unsigned int wStridedInput = stridedInput.shape[wIndex];
-    const unsigned int hStridedInput = stridedInput.shape[hIndex];
-
-    // loop through all input elements
-    for (unsigned int batchIdx = 0u; batchIdx < batches; ++batchIdx)
-    {
-        for (unsigned int cInput = 0u; cInput < channels; ++cInput)
-        {
-            for (unsigned int yInput = 0u; yInput < hStridedInput; ++yInput)
-            {
-                for (unsigned int xInput = 0u; xInput < wStridedInput; ++xInput)
-                {
-                    // obtain input value
-                    unsigned int inputIdx =
-                        dataLayoutIndexed.GetIndex(stridedInput.shape, batchIdx, cInput, yInput, xInput);
-                    float inputValue = stridedInput.data[inputIdx];
-
-                    // loop through kernel
-                    for (unsigned int yKernel = 0u; yKernel < hKernel; ++yKernel)
-                    {
-                        for (unsigned int xKernel = 0; xKernel < wKernel; ++xKernel)
-                        {
-                            unsigned int kernelIdx =
-                                dataLayoutIndexed.GetIndex(weightsShape, batchIdx, cInput, yKernel, xKernel);
-
-                            weightsDecoder[kernelIdx];
-                            float kernelValue = weightsDecoder.Get();
-
-                            unsigned int xOutput = xInput + xKernel;
-                            unsigned int yOutput = yInput + yKernel;
-
-                            // compute output increment
-                            float outputValue = inputValue * kernelValue;
-
-                            unsigned int outputIdx = dataLayoutIndexed.GetIndex(paddedOutput.shape,
-                                                                                batchIdx,
-                                                                                cInput,
-                                                                                yOutput,
-                                                                                xOutput);
-
-                            // set output value
-                            paddedOutput.data[outputIdx] += outputValue;
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
-
 void TransposeConvolution2dImpl(const TransposeConvolution2dDescriptor& descriptor,
                                 const TensorShape& inputShape,
                                 Decoder<float>& inputDecoder,
@@ -181,63 +25,106 @@
     {
         throw InvalidArgumentException("Biases enabled but no bias data provided");
     }
-
     const DataLayoutIndexed dataLayoutIndexed(descriptor.m_DataLayout);
+    const unsigned int channelsIndex = dataLayoutIndexed.GetChannelsIndex();
+    const unsigned int heightIndex   = dataLayoutIndexed.GetHeightIndex();
+    const unsigned int widthIndex    = dataLayoutIndexed.GetWidthIndex();
 
-    const unsigned int cIndex = dataLayoutIndexed.GetChannelsIndex();
-    const unsigned int hIndex = dataLayoutIndexed.GetHeightIndex();
-    const unsigned int wIndex = dataLayoutIndexed.GetWidthIndex();
+    unsigned int numBatches = inputShape[0];
 
-    const unsigned int numBatches  = inputShape[0];
-    const unsigned int numChannels = inputShape[cIndex];
+    unsigned int inputWidth  = inputShape[widthIndex];
+    unsigned int inputHeight = inputShape[heightIndex];
+    unsigned int inputDepth  = inputShape[channelsIndex];
 
-    // set up temporary strided input
-    TensorData stridedInput = SetUpStridedInput(inputShape, inputDecoder, descriptor, dataLayoutIndexed);
+    unsigned int weightsHeight = weightsShape[heightIndex];
+    unsigned int weightsWidth  = weightsShape[widthIndex];
 
-    // set up temporary (empty) padded output
-    TensorData paddedOutput = SetUpEmptyPaddedOutput(outputShape, descriptor, dataLayoutIndexed);
+    unsigned int outputHeight = outputShape[heightIndex];
+    unsigned int outputWidth  = outputShape[widthIndex];
+    unsigned int outputDepth  = outputShape[channelsIndex];
 
-    // run deconvolution (without biases) on strided input to produce padded output
-    Deconvolve(stridedInput, paddedOutput, weightsShape, weightsDecoder, dataLayoutIndexed);
+    unsigned int paddingLeft = descriptor.m_PadLeft;
+    unsigned int paddingTop  = descriptor.m_PadTop;
 
-    const unsigned int wPaddedOutput = paddedOutput.shape[wIndex];
-    const unsigned int hPaddedOutput = paddedOutput.shape[hIndex];
+    unsigned int strideX = descriptor.m_StrideX;
+    unsigned int strideY = descriptor.m_StrideY;
 
-    // remove padding and apply bias (if enabled)
-    for (unsigned int batchIdx = 0u; batchIdx < numBatches; ++batchIdx)
+    // Set the initial output values to be logically 0 otherwise the algorithm doesn't work.
+    for (unsigned int i = 0u; i < outputShape.GetNumElements(); ++i)
     {
-        for (unsigned int cOutput = 0u; cOutput < numChannels; ++cOutput)
+        outputEncoder.Set(0.f);
+        ++outputEncoder;
+    }
+
+    for (unsigned int batch = 0u; batch < numBatches; ++batch)
+    {
+        for (unsigned int yInput = 0u; yInput < inputHeight; ++yInput)
         {
-            // update bias decoder iterator
-            if (descriptor.m_BiasEnabled)
+            for (unsigned int xInput = 0u; xInput < inputWidth; ++xInput)
             {
-                (*biasesDecoder)[cOutput];
-            }
+                unsigned int xOutputOrigin = xInput * strideX - paddingLeft;
+                unsigned int yOutputOrigin = yInput * strideY - paddingTop;
 
-            for (unsigned int yPaddedOutput = descriptor.m_PadTop;
-                 yPaddedOutput < (hPaddedOutput - descriptor.m_PadBottom);
-                 ++yPaddedOutput)
-            {
-                for (unsigned int xPaddedOutput = descriptor.m_PadLeft;
-                     xPaddedOutput < (wPaddedOutput - descriptor.m_PadRight);
-                     ++xPaddedOutput)
+                unsigned int weightsBaseIndex = 0u;
+                for (unsigned int dOutput = 0u; dOutput < outputDepth; ++dOutput)
                 {
-                    unsigned int xOutput = xPaddedOutput - descriptor.m_PadLeft;
-                    unsigned int yOutput = yPaddedOutput - descriptor.m_PadTop;
-
-                    unsigned int outputIdx =
-                        dataLayoutIndexed.GetIndex(outputShape, batchIdx, cOutput, yOutput, xOutput);
-                    unsigned int paddedOutputIdx =
-                        dataLayoutIndexed.GetIndex(paddedOutput.shape, batchIdx, cOutput, yPaddedOutput, xPaddedOutput);
-
-                    // encode (copy) output data
-                    outputEncoder[outputIdx];
-                    outputEncoder.Set(paddedOutput.data[paddedOutputIdx]);
-
-                    // apply bias (if enabled)
-                    if (descriptor.m_BiasEnabled)
+                    for (unsigned int yWeights = 0u; yWeights < weightsHeight; ++yWeights)
                     {
-                        outputEncoder.Set(outputEncoder.Get() + biasesDecoder->Get());
+                        for (unsigned int xWeights = 0u; xWeights < weightsWidth;
+                             ++xWeights, weightsBaseIndex += inputDepth)
+                        {
+                            unsigned int yOutput = yOutputOrigin + yWeights;
+                            unsigned int xOutput = xOutputOrigin + xWeights;
+
+                            if (yOutput < outputHeight && xOutput< outputWidth)
+                            {
+                                for (unsigned int dInput = 0u; dInput < inputDepth; dInput++)
+                                {
+                                    const unsigned int inputIndex =
+                                        dataLayoutIndexed.GetIndex(inputShape, batch, dInput, yInput, xInput);
+                                    inputDecoder[inputIndex];
+
+                                    const unsigned int weightsIndex =
+                                        dataLayoutIndexed.GetIndex(weightsShape, batch, dOutput, yWeights, xWeights);
+                                    weightsDecoder[weightsIndex];
+
+                                    const unsigned int outputIndex =
+                                        dataLayoutIndexed.GetIndex(outputShape, batch, dOutput, yOutput, xOutput);
+                                    outputEncoder[outputIndex];
+
+                                    float output = outputEncoder.Get();
+                                    output += inputDecoder.Get() * weightsDecoder.Get();
+
+                                    outputEncoder.Set(output);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    // Apply bias (if enabled)
+    if (descriptor.m_BiasEnabled)
+    {
+        outputEncoder[0];
+        Decoder<float>& rBiasesDecoder = *biasesDecoder;
+
+        for (unsigned int batch = 0u; batch < numBatches; ++batch)
+        {
+            for (unsigned int dOutput = 0u; dOutput < outputDepth; ++dOutput)
+            {
+                rBiasesDecoder[dOutput];
+                for (unsigned int yOutput = 0u; yOutput < outputHeight; ++yOutput)
+                {
+                    for (unsigned int xOutput = 0u; xOutput < outputWidth; ++xOutput)
+                    {
+                        const unsigned int outputIndex =
+                            dataLayoutIndexed.GetIndex(outputShape, batch, dOutput, yOutput, xOutput);
+
+                        outputEncoder[outputIndex];
+                        outputEncoder.Set(outputEncoder.Get() + rBiasesDecoder.Get());
                     }
                 }
             }
@@ -245,4 +132,4 @@
     }
 }
 
-} // namespace armnn
\ No newline at end of file
+} // namespace armnn
