orcnd's picture
Upload Field Orders PPO v2 soldier, commander v1, runtime and evaluation
f7eea0e verified
Raw History Blame Contribute Delete
1.43 kB
export function runNetwork(network,rows){
return rows.map(row=>{let x=network.inputMean?row.map((v,i)=>(v-network.inputMean[i])/network.inputStd[i]):row;for(let n=0;n<network.layers.length;n++){const layer=network.layers[n],y=new Float32Array(layer.bias.length);for(let j=0;j<y.length;j++){let sum=layer.bias[j],base=j*x.length;for(let k=0;k<x.length;k++)sum+=layer.weight[base+k]*x[k];y[j]=n===network.layers.length-1?sum:Math.tanh(sum);}x=y;}return Array.from(x);});
}
export function decodeControl(raw){const x=Math.tanh(raw[0]),y=Math.tanh(raw[1]),m=Math.max(1,Math.hypot(x,y)),ax=Math.tanh(raw[2]),ay=Math.tanh(raw[3]),a=Math.hypot(ax,ay);return {moveX:x/m,moveY:y/m,aimX:a>.05?ax/a:1,aimY:a>.05?ay/a:0,fire:raw[4]>0};}
export function validateNetwork(n){
if(n.schema!=='field-orders.neural-network.v1'||!Number.isInteger(n.inputDim)||!n.layers?.length||n.inputMean?.length!==n.inputDim||n.inputStd?.length!==n.inputDim||!n.inputStd.every(v=>Number.isFinite(v)&&v>0)||!n.inputMean.every(Number.isFinite))throw Error('Invalid neural network schema');
let width=n.inputDim;
for(const layer of n.layers){if(!layer.bias?.length||layer.weight?.length!==width*layer.bias.length||!layer.bias.every(Number.isFinite)||!layer.weight.every(Number.isFinite))throw Error('Invalid neural network weights');width=layer.bias.length;}
if(width!==n.outputDim)throw Error('Invalid neural network output width');
return n;
}