Deepity
Ultra-fast, SIMD-accelerated Predictive Coding
Loading...
Searching...
No Matches
Deep::DirectKPPCLayer Class Reference

Predictive Coding layer using Direct Kolen-Pollack feedback alignment (DFA): a per-layer feedback matrix Psi, trained to gradually correlate with W's transpose chain, replaces symmetric weight transport for the feedback term. See DirectKPPCNetwork.h's class docs and the paper's Appendix A.1. More...

#include <DirectKPPCLayer.h>

Inheritance diagram for Deep::DirectKPPCLayer:
Deep::Layer

Public Member Functions

 DirectKPPCLayer (size_t size, size_t nextSize, size_t terminalSize, size_t batchSize, float learningRate, float inferenceRate, float feedback, float lmbda, ActivationType aType, ActivationType dType, IComputeBackend *backend=nullptr)
 ~DirectKPPCLayer () override=default
template<typename ArenaT>
void BindMemory (ArenaT &arena)
 Binds this layer's buffers into a pre-allocated arena (MemoryArena for CPU, DeviceMemoryArena for GPU).
size_t GetRequiredFloats () const noexcept
 Total floats this layer needs from its MemoryArena.
void RandomizeWeights (std::mt19937 &seedGenerator) noexcept
 Randomizes W and Psi.
std::map< std::string, TensorDescriptor > GetStateDict () const override
 Returns a dictionary of this.
void SetLayerAbove (DirectKPPCLayer *l) noexcept
 Sets the layer immediately above this one in the network.
void SetLayerBelow (DirectKPPCLayer *l) noexcept
 Sets the layer immediately below this one in the network.
void SetTerminalLayer (DirectKPPCLayer *l) noexcept
 Sets the network's terminal layer, for DirectFeedbackUpdate().
float CalculateState () noexcept override
 Matches Layer's virtual interface exactly (always computes real energy).
float CalculateState (bool needEnergy) noexcept
 NOT a virtual override – see SimplePCLayer's identical pattern. Lets the settling loop skip the cublasSdot-based energy reduction (and its capture-time sync) when the caller doesn't need the value.
void ComputeMuOnly () noexcept
 Computes only mu (forward prediction), skipping error/energy.
void UpdateState () noexcept override
 Updates the states after calculation.
void UpdateWeights () noexcept override
 Updates the weights after state updates.
void DirectFeedbackUpdate () noexcept
 Perturbs W using the layer above's Psi and the terminal layer's error – the DFA phase, run once per batch before settling begins.
void ClampState (const std::vector< float > &inputData) noexcept
 Clamps this layer's beliefs to inputData, fixing them against UpdateState() until UnclampState() is called.
void UnclampState () noexcept
 Releases a previous ClampState() call.
void ResetState () noexcept
 Resets this layer's beliefs (z) without touching learned weights.
bool IsClamped () const noexcept
 Whether this layer is currently clamped – needed so DirectKPPCNetwork::ProjectForward() can skip overwriting an already-clamped layer's z with a forward-projected guess. Same real bug SimplePCNetwork::ProjectForward() had; fixed here for the same reason, before it gets exercised for the first time by moving ProjectForward() inside graph capture.
void SetOptimizer (OptimizerType o) noexcept
 Sets the optimizer for W. Call before Compile().
void SetPsiOptimizer (OptimizerType o) noexcept
 Sets the optimizer for Psi. Call before Compile().
void SetLearningRate (float learningRate) noexcept
 Sets the learning rate, propagating it to the optimizer state.
void SetInferenceRate (float inferenceRate) noexcept
 Sets the inference rate.
void SetFeedbackRate (float feedbackRate) noexcept
 Sets the feedback rate, propagating it to the optimizer state.
void SetLambda (float lmbda) noexcept
 Sets the weight decay coefficient.
float * GetBeliefs () noexcept override
 Should return belief state z.
const float * GetErrors () const noexcept override
 Should return errors e.
const float * GetMu () const noexcept
 Returns this layer's forward prediction buffer.
const float * GetWeights () const noexcept
 Returns the weight matrix W, shape [nextSize, size].
const float * GetDirectFeedbackWeights () const noexcept
 Returns the direct feedback (DFA) weight matrix Psi, shape [size, terminalSize].
const float * GetBiases () const noexcept
 Returns the bias vector, length nextSize.
size_t GetBatchSize () const noexcept override
 Should return batch size.
size_t GetInputSize () const noexcept override
 Should return input size.
size_t GetOutputSize () const noexcept override
 Should return output size.
size_t GetTerminalSize () const noexcept
 Returns the network's final output layer size, as given at construction.
Public Member Functions inherited from Deep::Layer
virtual ~Layer ()=default
virtual void Flush () noexcept
 Flushes remaining batches.

Protected Types

using BackendDeleter = void (*)(IComputeBackend *)
 Custom deleter type for backend, needed since IComputeBackend is an abstract base – see the member below.

Protected Attributes

size_t size
 This layer's own belief (z) size.
size_t nextSize
 Size of the layer above (0 marks a terminal layer).
size_t terminalSize
 Size of the network's final output layer.
size_t batchSize
 Batch size.
float lr
 Learning rate for W.
float ir
 Inference rate (Euler integration step size).
float fl
 Feedback rate for Psi.
float lmbda
 Weight decay (L2 regularization) coefficient, shared between W and Psi.
bool isClamped = false
 Whether ClampState() is currently active.
bool muCacheValid = false
 Whether cachedMu holds a valid, up-to-date value.
DirectKPPCLayer * layerAbove = nullptr
 The next layer up, or nullptr if this is terminal.
DirectKPPCLayer * layerBelow = nullptr
 The next layer down, or nullptr if this is the input layer.
DirectKPPCLayer * terminalLayer = nullptr
 The network's terminal layer, for DirectFeedbackUpdate().
ActivationType activationType
 This layer's activation type.
ActivationFn activation
 Resolved function pointer for activationType.
DerivativeFn activationDerivative
 Resolved function pointer for the derivative.
DerivativeFn2 activationDerivativeInto
 Two-buffer variant of activationDerivative.
OptimizerType opt = OptimizerType::SGD
 Optimizer for W/b.
OptimizerType optPsi = OptimizerType::SGD
 Optimizer for Psi.
int t = 0
 Adam/AdamW step count for W/b.
int tPsi = 0
 Adam/AdamW step count for Psi.
std::unique_ptr< IComputeBackend, BackendDeleter > backend
 This layer's compute backend.
float * z = nullptr
 This layer's belief buffer, shape [batchSize, size].
float * e = nullptr
 This layer's error buffer, shape [batchSize, size].
float * W = nullptr
 Weight matrix, shape [nextSize, size].
float * b = nullptr
 Bias vector, length nextSize.
float * mu = nullptr
 Forward prediction buffer, shape [batchSize, nextSize].
float * cachedMu = nullptr
 Cached mu, valid when muCacheValid is true.
float * Psi = nullptr
 Direct feedback (DFA) weight matrix, shape [size, terminalSize].
float * proj = nullptr
 Scratch buffer: terminal error projected back through layerAbove's Psi, for DirectFeedbackUpdate()'s W update.
float * grad_W = nullptr
 W's gradient scratch buffer.
float * grad_b = nullptr
 b's gradient scratch buffer.
float * m_W = nullptr
 Adam/AdamW first-moment buffer for W.
float * v_W = nullptr
 Adam/AdamW second-moment buffer for W.
float * m_b = nullptr
 Adam/AdamW first-moment buffer for b.
float * v_b = nullptr
 Adam/AdamW second-moment buffer for b.
float * grad_Psi = nullptr
 Psi's gradient scratch buffer.
float * m_Psi = nullptr
 Adam/AdamW first-moment buffer for Psi.
float * v_Psi = nullptr
 Adam/AdamW second-moment buffer for Psi.
int * t_device = nullptr
 Device-resident mirror of t, for graph-captured Adam steps.
float * lr_device = nullptr
 Device-resident mirror of lr.
int * tPsi_device = nullptr
 Device-resident mirror of tPsi.
float * fl_device = nullptr
 Device-resident mirror of fl.
float * zF = nullptr
 Activated belief, phi(z), used as the forward GEMM's input.
float * zFDeriv = nullptr
 Activation derivative at z, for the feedback term.
float * feedbackScratch = nullptr
 Scratch buffer for the feedback GEMM's output.
float * biasGradScratch = nullptr
 nextSize-length scratch buffer for SumRows' output in UpdateWeights()'s SGD branch – SGD needs b += lr_batch * sum(local_grad), an accumulate, which SumRows alone can't express (it only overwrites). Allocated unconditionally (regardless of which optimizer is selected) since it's cheap – at most nextSize floats – and simpler than branching allocation on optimizer choice for this one small buffer.
std::unique_ptr< MemoryArena > localArena
 This layer's own arena, used when it isn't bound into a network-wide one.
Protected Attributes inherited from Deep::Layer
size_t size
 Size of input.
size_t nextSize
 Size of output.

Detailed Description

Predictive Coding layer using Direct Kolen-Pollack feedback alignment (DFA): a per-layer feedback matrix Psi, trained to gradually correlate with W's transpose chain, replaces symmetric weight transport for the feedback term. See DirectKPPCNetwork.h's class docs and the paper's Appendix A.1.

Member Typedef Documentation

◆ BackendDeleter

Custom deleter type for backend, needed since IComputeBackend is an abstract base – see the member below.

Constructor & Destructor Documentation

◆ DirectKPPCLayer()

Deep::DirectKPPCLayer::DirectKPPCLayer ( size_t size,
size_t nextSize,
size_t terminalSize,
size_t batchSize,
float learningRate,
float inferenceRate,
float feedback,
float lmbda,
ActivationType aType,
ActivationType dType,
IComputeBackend * backend = nullptr )
Parameters
sizeinput size
nextSizeoutput size (0 marks a terminal layer)
terminalSizethe size of the network's final output layer (e.g. 10 for MNIST) – required directly, not inferred, since the true terminal layer isn't known until the whole network has been assembled.
batchSizebatch size
learningRatelearning rate for W
inferenceRateinference rate (Euler integration step size)
feedbackfeedback rate for Psi
lmbdaweight decay (L2 regularization) coefficient, shared between W and Psi
aTypeactivation type
dTypeactivation derivative type
backendCompute backend to run on; defaults to a new CPUBackend if nullptr.

◆ ~DirectKPPCLayer()

Deep::DirectKPPCLayer::~DirectKPPCLayer ( )
overridedefault

Member Function Documentation

◆ BindMemory()

template<typename ArenaT>
template void Deep::DirectKPPCLayer::BindMemory< DeviceMemoryArena > ( ArenaT & arena)

Binds this layer's buffers into a pre-allocated arena (MemoryArena for CPU, DeviceMemoryArena for GPU).

Template Parameters
ArenaTEither MemoryArena or DeviceMemoryArena.

◆ CalculateState() [1/2]

float Deep::DirectKPPCLayer::CalculateState ( )
inlineoverridevirtualnoexcept

Matches Layer's virtual interface exactly (always computes real energy).

Implements Deep::Layer.

◆ CalculateState() [2/2]

float Deep::DirectKPPCLayer::CalculateState ( bool needEnergy)
noexcept

NOT a virtual override – see SimplePCLayer's identical pattern. Lets the settling loop skip the cublasSdot-based energy reduction (and its capture-time sync) when the caller doesn't need the value.

◆ ClampState()

void Deep::DirectKPPCLayer::ClampState ( const std::vector< float > & inputData)
noexcept

Clamps this layer's beliefs to inputData, fixing them against UpdateState() until UnclampState() is called.

◆ ComputeMuOnly()

void Deep::DirectKPPCLayer::ComputeMuOnly ( )
noexcept

Computes only mu (forward prediction), skipping error/energy.

◆ DirectFeedbackUpdate()

void Deep::DirectKPPCLayer::DirectFeedbackUpdate ( )
noexcept

Perturbs W using the layer above's Psi and the terminal layer's error – the DFA phase, run once per batch before settling begins.

◆ GetBatchSize()

size_t Deep::DirectKPPCLayer::GetBatchSize ( ) const
inlineoverridevirtualnoexcept

Should return batch size.

Returns
? = 0

Implements Deep::Layer.

◆ GetBeliefs()

float * Deep::DirectKPPCLayer::GetBeliefs ( )
inlineoverridevirtualnoexcept

Should return belief state z.

Returns
? = 0

Implements Deep::Layer.

◆ GetBiases()

const float * Deep::DirectKPPCLayer::GetBiases ( ) const
inlinenoexcept

Returns the bias vector, length nextSize.

◆ GetDirectFeedbackWeights()

const float * Deep::DirectKPPCLayer::GetDirectFeedbackWeights ( ) const
inlinenoexcept

Returns the direct feedback (DFA) weight matrix Psi, shape [size, terminalSize].

◆ GetErrors()

const float * Deep::DirectKPPCLayer::GetErrors ( ) const
inlineoverridevirtualnoexcept

Should return errors e.

Returns
? = 0

Implements Deep::Layer.

◆ GetInputSize()

size_t Deep::DirectKPPCLayer::GetInputSize ( ) const
inlineoverridevirtualnoexcept

Should return input size.

Returns
? = 0

Implements Deep::Layer.

◆ GetMu()

const float * Deep::DirectKPPCLayer::GetMu ( ) const
inlinenoexcept

Returns this layer's forward prediction buffer.

◆ GetOutputSize()

size_t Deep::DirectKPPCLayer::GetOutputSize ( ) const
inlineoverridevirtualnoexcept

Should return output size.

Returns
? = 0

Implements Deep::Layer.

◆ GetRequiredFloats()

size_t Deep::DirectKPPCLayer::GetRequiredFloats ( ) const
noexcept

Total floats this layer needs from its MemoryArena.

◆ GetStateDict()

std::map< std::string, Deep::TensorDescriptor > Deep::DirectKPPCLayer::GetStateDict ( ) const
overridevirtual

Returns a dictionary of this.

Reimplemented from Deep::Layer.

◆ GetTerminalSize()

size_t Deep::DirectKPPCLayer::GetTerminalSize ( ) const
inlinenoexcept

Returns the network's final output layer size, as given at construction.

◆ GetWeights()

const float * Deep::DirectKPPCLayer::GetWeights ( ) const
inlinenoexcept

Returns the weight matrix W, shape [nextSize, size].

◆ IsClamped()

bool Deep::DirectKPPCLayer::IsClamped ( ) const
inlinenoexcept

Whether this layer is currently clamped – needed so DirectKPPCNetwork::ProjectForward() can skip overwriting an already-clamped layer's z with a forward-projected guess. Same real bug SimplePCNetwork::ProjectForward() had; fixed here for the same reason, before it gets exercised for the first time by moving ProjectForward() inside graph capture.

◆ RandomizeWeights()

void Deep::DirectKPPCLayer::RandomizeWeights ( std::mt19937 & seedGenerator)
noexcept

Randomizes W and Psi.

◆ ResetState()

void Deep::DirectKPPCLayer::ResetState ( )
noexcept

Resets this layer's beliefs (z) without touching learned weights.

◆ SetFeedbackRate()

void Deep::DirectKPPCLayer::SetFeedbackRate ( float feedbackRate)
noexcept

Sets the feedback rate, propagating it to the optimizer state.

◆ SetInferenceRate()

void Deep::DirectKPPCLayer::SetInferenceRate ( float inferenceRate)
inlinenoexcept

Sets the inference rate.

◆ SetLambda()

void Deep::DirectKPPCLayer::SetLambda ( float lmbda)
inlinenoexcept

Sets the weight decay coefficient.

◆ SetLayerAbove()

void Deep::DirectKPPCLayer::SetLayerAbove ( DirectKPPCLayer * l)
inlinenoexcept

Sets the layer immediately above this one in the network.

◆ SetLayerBelow()

void Deep::DirectKPPCLayer::SetLayerBelow ( DirectKPPCLayer * l)
inlinenoexcept

Sets the layer immediately below this one in the network.

◆ SetLearningRate()

void Deep::DirectKPPCLayer::SetLearningRate ( float learningRate)
noexcept

Sets the learning rate, propagating it to the optimizer state.

◆ SetOptimizer()

void Deep::DirectKPPCLayer::SetOptimizer ( OptimizerType o)
inlinenoexcept

Sets the optimizer for W. Call before Compile().

◆ SetPsiOptimizer()

void Deep::DirectKPPCLayer::SetPsiOptimizer ( OptimizerType o)
inlinenoexcept

Sets the optimizer for Psi. Call before Compile().

◆ SetTerminalLayer()

void Deep::DirectKPPCLayer::SetTerminalLayer ( DirectKPPCLayer * l)
inlinenoexcept

Sets the network's terminal layer, for DirectFeedbackUpdate().

◆ UnclampState()

void Deep::DirectKPPCLayer::UnclampState ( )
noexcept

Releases a previous ClampState() call.

◆ UpdateState()

void Deep::DirectKPPCLayer::UpdateState ( )
overridevirtualnoexcept

Updates the states after calculation.

Implements Deep::Layer.

◆ UpdateWeights()

void Deep::DirectKPPCLayer::UpdateWeights ( )
overridevirtualnoexcept

Updates the weights after state updates.

Implements Deep::Layer.

Member Data Documentation

◆ activation

ActivationFn Deep::DirectKPPCLayer::activation
protected

Resolved function pointer for activationType.

◆ activationDerivative

DerivativeFn Deep::DirectKPPCLayer::activationDerivative
protected

Resolved function pointer for the derivative.

◆ activationDerivativeInto

DerivativeFn2 Deep::DirectKPPCLayer::activationDerivativeInto
protected

Two-buffer variant of activationDerivative.

◆ activationType

ActivationType Deep::DirectKPPCLayer::activationType
protected

This layer's activation type.

◆ b

float* Deep::DirectKPPCLayer::b = nullptr
protected

Bias vector, length nextSize.

◆ backend

std::unique_ptr<IComputeBackend, BackendDeleter> Deep::DirectKPPCLayer::backend
protected

This layer's compute backend.

◆ batchSize

size_t Deep::DirectKPPCLayer::batchSize
protected

Batch size.

◆ biasGradScratch

float* Deep::DirectKPPCLayer::biasGradScratch = nullptr
protected

nextSize-length scratch buffer for SumRows' output in UpdateWeights()'s SGD branch – SGD needs b += lr_batch * sum(local_grad), an accumulate, which SumRows alone can't express (it only overwrites). Allocated unconditionally (regardless of which optimizer is selected) since it's cheap – at most nextSize floats – and simpler than branching allocation on optimizer choice for this one small buffer.

◆ cachedMu

float* Deep::DirectKPPCLayer::cachedMu = nullptr
protected

Cached mu, valid when muCacheValid is true.

◆ e

float* Deep::DirectKPPCLayer::e = nullptr
protected

This layer's error buffer, shape [batchSize, size].

◆ feedbackScratch

float* Deep::DirectKPPCLayer::feedbackScratch = nullptr
protected

Scratch buffer for the feedback GEMM's output.

◆ fl

float Deep::DirectKPPCLayer::fl
protected

Feedback rate for Psi.

◆ fl_device

float* Deep::DirectKPPCLayer::fl_device = nullptr
protected

Device-resident mirror of fl.

◆ grad_b

float* Deep::DirectKPPCLayer::grad_b = nullptr
protected

b's gradient scratch buffer.

◆ grad_Psi

float* Deep::DirectKPPCLayer::grad_Psi = nullptr
protected

Psi's gradient scratch buffer.

◆ grad_W

float* Deep::DirectKPPCLayer::grad_W = nullptr
protected

W's gradient scratch buffer.

◆ ir

float Deep::DirectKPPCLayer::ir
protected

Inference rate (Euler integration step size).

◆ isClamped

bool Deep::DirectKPPCLayer::isClamped = false
protected

Whether ClampState() is currently active.

◆ layerAbove

DirectKPPCLayer* Deep::DirectKPPCLayer::layerAbove = nullptr
protected

The next layer up, or nullptr if this is terminal.

◆ layerBelow

DirectKPPCLayer* Deep::DirectKPPCLayer::layerBelow = nullptr
protected

The next layer down, or nullptr if this is the input layer.

◆ lmbda

float Deep::DirectKPPCLayer::lmbda
protected

Weight decay (L2 regularization) coefficient, shared between W and Psi.

◆ localArena

std::unique_ptr<MemoryArena> Deep::DirectKPPCLayer::localArena
protected

This layer's own arena, used when it isn't bound into a network-wide one.

◆ lr

float Deep::DirectKPPCLayer::lr
protected

Learning rate for W.

◆ lr_device

float* Deep::DirectKPPCLayer::lr_device = nullptr
protected

Device-resident mirror of lr.

◆ m_b

float* Deep::DirectKPPCLayer::m_b = nullptr
protected

Adam/AdamW first-moment buffer for b.

◆ m_Psi

float* Deep::DirectKPPCLayer::m_Psi = nullptr
protected

Adam/AdamW first-moment buffer for Psi.

◆ m_W

float* Deep::DirectKPPCLayer::m_W = nullptr
protected

Adam/AdamW first-moment buffer for W.

◆ mu

float* Deep::DirectKPPCLayer::mu = nullptr
protected

Forward prediction buffer, shape [batchSize, nextSize].

◆ muCacheValid

bool Deep::DirectKPPCLayer::muCacheValid = false
protected

Whether cachedMu holds a valid, up-to-date value.

◆ nextSize

size_t Deep::DirectKPPCLayer::nextSize
protected

Size of the layer above (0 marks a terminal layer).

◆ opt

OptimizerType Deep::DirectKPPCLayer::opt = OptimizerType::SGD
protected

Optimizer for W/b.

◆ optPsi

OptimizerType Deep::DirectKPPCLayer::optPsi = OptimizerType::SGD
protected

Optimizer for Psi.

◆ proj

float* Deep::DirectKPPCLayer::proj = nullptr
protected

Scratch buffer: terminal error projected back through layerAbove's Psi, for DirectFeedbackUpdate()'s W update.

◆ Psi

float* Deep::DirectKPPCLayer::Psi = nullptr
protected

Direct feedback (DFA) weight matrix, shape [size, terminalSize].

◆ size

size_t Deep::DirectKPPCLayer::size
protected

This layer's own belief (z) size.

◆ t

int Deep::DirectKPPCLayer::t = 0
protected

Adam/AdamW step count for W/b.

◆ t_device

int* Deep::DirectKPPCLayer::t_device = nullptr
protected

Device-resident mirror of t, for graph-captured Adam steps.

◆ terminalLayer

DirectKPPCLayer* Deep::DirectKPPCLayer::terminalLayer = nullptr
protected

The network's terminal layer, for DirectFeedbackUpdate().

◆ terminalSize

size_t Deep::DirectKPPCLayer::terminalSize
protected

Size of the network's final output layer.

◆ tPsi

int Deep::DirectKPPCLayer::tPsi = 0
protected

Adam/AdamW step count for Psi.

◆ tPsi_device

int* Deep::DirectKPPCLayer::tPsi_device = nullptr
protected

Device-resident mirror of tPsi.

◆ v_b

float* Deep::DirectKPPCLayer::v_b = nullptr
protected

Adam/AdamW second-moment buffer for b.

◆ v_Psi

float* Deep::DirectKPPCLayer::v_Psi = nullptr
protected

Adam/AdamW second-moment buffer for Psi.

◆ v_W

float* Deep::DirectKPPCLayer::v_W = nullptr
protected

Adam/AdamW second-moment buffer for W.

◆ W

float* Deep::DirectKPPCLayer::W = nullptr
protected

Weight matrix, shape [nextSize, size].

◆ z

float* Deep::DirectKPPCLayer::z = nullptr
protected

This layer's belief buffer, shape [batchSize, size].

◆ zF

float* Deep::DirectKPPCLayer::zF = nullptr
protected

Activated belief, phi(z), used as the forward GEMM's input.

◆ zFDeriv

float* Deep::DirectKPPCLayer::zFDeriv = nullptr
protected

Activation derivative at z, for the feedback term.


The documentation for this class was generated from the following files: