forked from animatedread/Warrior_EA
CaclHiddenGradient computed this layer's gradient as matrix_w[(outputs+1)*i + k] against a buffer whose actual layout (one row per NEXT-layer neuron, stride inputs+1) makes the correct read matrix_w[k*(inputs+1) + i]: the transpose for square layers, and for the non-square boundaries this EA actually builds (tapered stacks, the 3-neuron head) a mis-strided walk that ran past the buffer end - garbage on OpenCL, zeroed reads on the CPU DLL, so the tiers did not even agree with each other. Every gradient crossing a dense boundary on its way down - the entire learning signal reaching the BN/conv/LSTM front ends - passed through a fixed wrong matrix: feedback-alignment dynamics, not backprop, which is why nets still "learned something" and this survived. The book reference (NeuroNet_DNG) fixed this in a later article version; our kernel descended from the earlier one. Confounds every model-based negative verdict to date. Also in this commit, same root cause family: - per-sample UpdateWeightsAdam (OpenCL): input for slot group j was read at matrix_i[j] instead of matrix_i[j*4] (corrupted outer product past group 0), and dispatch dim 1 sized on ceil(inputs/4) left the bias column unreachable whenever inputs%4==0 - dense biases never trained on OpenCL. Rewritten as a lane-guarded scalar loop keeping our Adam conventions (sqrt-stored v, decoupled decay, both clamps, no sign gate). The batched accum path never had either bug; this kernel is what SetBatchSize(1) runs - including online continual learning on client machines, where OpenCL is the only tier. - conv backward passed raw (int)Activation() where the kernels expect NativeActivationCode(): NONE took the tanh branch (clamping a BN layer's unbounded z-scores), TANH took sigmoid, PRELU took none. Dormant only because the conv sits at layer 1 today. - hidden-gradient dispatch over Neurons()+1 dropped to Neurons(): biases get no backprop gradient and the extra work-item only ever read past matrix_o. All three backends (Network.cl, WarriorCPU.cpp, WarriorDML.cpp HLSL) changed in lockstep; DML gained an `inputs` constant to derive the row stride. New dense_backprop_check.cpp proves the CPU kernel is central-finite-difference consistent with the real forward kernel on 8x8, 64x3, 33x64, 5x3 (max diff 3e-9) and that all three activation branches match transcription. All 16 checks pass. Offline math check only - the in-situ proof remains the per-layer dW/W report on a real era. FORCES FULL RETRAIN. Both DLLs rebuilt and redeployed to MQL5\Libraries. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
35 lines
1.2 KiB
Batchfile
35 lines
1.2 KiB
Batchfile
@echo off
|
|
REM Builds and runs dense_backprop_check.exe - the offline math check for the
|
|
REM 2026-08-11 dense hidden-gradient transpose fix. Locates the VS build
|
|
REM environment itself, exactly like build_cpu.bat beside it.
|
|
REM Run build_cpu.bat FIRST so WarriorCPU.lib/.dll match the current source.
|
|
setlocal
|
|
|
|
set VSWHERE="%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe"
|
|
if not exist %VSWHERE% (
|
|
echo Could not find vswhere.exe - is Visual Studio / Build Tools installed?
|
|
exit /b 1
|
|
)
|
|
|
|
for /f "usebackq tokens=*" %%i in (`%VSWHERE% -latest -products * -property installationPath`) do (
|
|
set VSINSTALL=%%i
|
|
)
|
|
if not defined VSINSTALL (
|
|
echo Could not find any Visual Studio / Build Tools installation.
|
|
exit /b 1
|
|
)
|
|
|
|
call "%VSINSTALL%\VC\Auxiliary\Build\vcvars64.bat"
|
|
if errorlevel 1 exit /b 1
|
|
|
|
cd /d "%~dp0"
|
|
cl.exe /nologo /EHsc /O2 /std:c++17 dense_backprop_check.cpp WarriorCPU.lib /Fe:dense_backprop_check.exe
|
|
if errorlevel 1 (
|
|
echo Build failed.
|
|
exit /b 1
|
|
)
|
|
|
|
REM ".\" prefix on purpose - some shells refuse to launch an executable by bare
|
|
REM relative name, and the failure reads as "build produced nothing".
|
|
.\dense_backprop_check.exe
|
|
exit /b %errorlevel%
|