kolibrios/programs/develop/libraries/nnp/nnp.asm

1412 lines
34 KiB
NASM
Raw Normal View History

;MIT License
;Copyright (c) 2020 Artem Yashin
;Permission is hereby granted, free of charge, to any person obtaining a copy
;of this software and associated documentation files (the "Software"), to deal
;in the Software without restriction, including without limitation the rights
;to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
;copies of the Software, and to permit persons to whom the Software is
;furnished to do so, subject to the following conditions:
;The above copyright notice and this permission notice shall be included in all
;copies or substantial portions of the Software.
;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
;FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
;AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
;SOFTWARE.
;https://www.youtube.com/watch?v=GNcGPw_Kb_0
;https://www.youtube.com/watch?v=wzIOl4hWP3U
; 1:20 - cats images
format MS COFF
public EXPORTS
section '.flat' code readable align 16
include "..\..\..\KOSfuncs.inc"
include "..\..\..\proc32.inc"
include "..\..\..\macros.inc"
include "..\..\..\dll.inc"
include "..\..\..\bcc32\include\kos_func.inc"
include "..\..\..\bcc32\include\kos_heap.inc"
@@memcpy$qpvpxvui equ @memcpy$qpvpxvui
@@DoubleToStr$qduso equ @DoubleToStr$qduso
@@strlen$qpxc equ @strlen$qpxc
@@strstr$qpxct1 equ @strstr$qpxct1
@@strchr$qpxci equ @strchr$qpxci
@@StrToInt$qpc equ @StrToInt$qpc
@@StrToDouble$qpc equ @StrToDouble$qpc
mem.alloc dd ? ;функция для выделения памяти
mem.free dd ? ;функция для освобождения памяти
mem.realloc dd ? ;функция для перераспределения памяти
dll.load dd ?
PRECISION equ 16
NNP_FF_BIN equ 0x6e6962
NNP_FF_JSON equ 0x6e6f736a
struct Layer
c_size dd ? ;+ 0 curent size - число нейронов в текущем слое
n_size dd ? ;+ 4 next size - число нейронов на следующем слое
neurons dd ? ;+ 8 []
biases dd ? ;+12 []
weights dd ? ;+16 [][]
ends
struct NeuralNetwork
learningRate dq ? ;+ 0 скорость обучения
layers dd ? ;+ 8 [] слои
layers_length dd ? ;+12 число слоев
activation dd ? ;+16 указатель на функцию активации
derivative dd ? ;+20 указатель на функцию
errors dd ? ;+24 массив для вычислений
errorsNext dd ? ;+28
gradients dd ? ;+32
deltas dd ? ;+36
ends
align 4
_rand_x dd 0
txt_QlearningRateQ_ db '"learningRate": ',0
txt_zap_nl db ",",10,0
txt_Qlayers_lengthQ db '"layers_length": ',0
txt_QlayersQ db '"layers": [',0
txt_nl_t_Qc_sizeQ db 10,9,'{"c_size": ',0
txt_zap_nl_t_Qn_sizeQ db ",",10,9,'"n_size": ',0
txt_t_QneuronsQ db 9,'"neurons": [',0
txt_zap_sp db ", ",0
txt_sqbr_zap_nl db "],",10,0
txt_t_QbiasesQ db 9,'"biases": [',0
txt_sqbr_zap_t_QweightsQ db "],",10,9,'"weights": [',10,9,9,0
txt_zap_nl_t_t db ",",10,9,9,0
txt_sqbro db "[",0
txt_sqbr db "]",0
txt_sqbr_fbr_zap db "]},",0
txt_nl_t_sqbr db 10,9,"]",0
txt_learningRate db '"learningRate"',0
txt_layers_length db '"layers_length"',0
;txt_pri_zap db '%i,',0
txt_c_size db '"c_size"',0
txt_n_size db '"n_size"',0
txt_biases db '"biases"',0
txt_weights db '"weights"',0
txt_err_layers_neq db 'number of layers does not match',0
txt_err_c_size db "not found value 'c_size'",0
txt_err_sqbrl_b1 db "not found opening '[' for biases",0
txt_err_sqbrl_w1 db "not found opening '[' for weights",0
txt_err_sqbrl_w2 db "not found opening '[[' for weights",0
txt_err_sqbrr_w2 db "not found closing ']]' for weights",0
align 16
proc lib_init
mov [mem.alloc], eax
mov [mem.free], ebx
mov [mem.realloc], ecx
mov [dll.load], edx
or edx, edx
jz @f
invoke dll.load, @IMPORT
@@:
ret
endp
align 16
Math_random:
imul eax,dword[_rand_x],22695477
inc eax
push ecx
mov dword[_rand_x],eax
and eax,65535
mov dword[esp],eax
fild dword[esp]
fmul dword[@f]
pop edx
ret
align 4
@@:
db 0,0,128,55 ;dd 1.0/65536.0
align 16
sigmoid:
push ebp
mov ebp,esp
add esp,-8
fld qword[ebp+8]
fchs
fstp qword[esp]
call dword[_exp]
add esp,8
fadd dword[f_1_0]
fdivr dword[f_1_0]
pop ebp
ret 8
align 16
dsigmoid:
push ebp
mov ebp,esp
fld1
fsub qword[ebp+8]
fmul qword[ebp+8]
pop ebp
ret 8
align 16
Layer_Create:
push ebp
mov ebp,esp
push ebx esi edi
mov esi,[ebp+8]
mov edi,[ebp+12]
mov ebx,edi
shl ebx,3
mov dword[esi+Layer.c_size],edi
mov eax,[ebp+16]
mov dword[esi+Layer.n_size],eax
push ebx
call @$bnwa$qui
pop ecx
mov dword[esi+Layer.neurons],eax
push ebx
call @$bnwa$qui
pop ecx
mov dword[esi+Layer.biases],eax
mov eax,edi
shl eax,2
push eax
call @$bnwa$qui
pop ecx
mov dword[esi+Layer.weights],eax
xor ebx,ebx
cmp edi,ebx
jbe .end_f
@@:
mov eax,[ebp+16]
shl eax,3
push eax
call @$bnwa$qui
pop ecx
mov edx,[esi+Layer.weights]
mov dword[edx+4*ebx],eax
inc ebx
cmp edi,ebx
ja @b
.end_f:
pop edi esi ebx ebp
ret 12
;+ 8 NeuralNetwork* o
;+12 double learningRate
;+20 void* activation
;+24 void* derivative
;+28 unsigned long* sizes
;+32 long sizes_length
align 16
NNP_Create:
push ebp
mov ebp,esp
add esp,-12
push ebx esi edi
mov eax,[ebp+8] ;o
mov edx,[ebp+12] ;learningRate
mov dword[eax+NeuralNetwork.learningRate],edx
mov edx,[ebp+16] ;learningRate (2)
mov dword[eax+NeuralNetwork.learningRate+4],edx
mov ecx,[ebp+8] ;o
mov eax,[ebp+20] ;activation
or eax,eax
jnz @f
mov eax,sigmoid
@@:
mov dword[ecx+NeuralNetwork.activation],eax
mov edx,[ebp+8] ;o
mov eax,[ebp+24] ;derivative
or eax,eax
jnz @f
mov eax,dsigmoid
@@:
mov dword[edx+NeuralNetwork.derivative],eax
mov eax,[ebp+32] ;sizes_length
imul eax,sizeof.Layer
stdcall @$bnwa$qui,eax
pop ecx
mov edx,[ebp+8] ;o
mov dword[edx+NeuralNetwork.layers],eax
mov ecx,[ebp+8] ;o
mov eax,[ebp+32] ;sizes_length
mov dword[ecx+NeuralNetwork.layers_length],eax
xor edi,edi ;i=0
mov eax,[ebp+28] ;sizes
lea edx,[eax+4]
mov dword[ebp-8],edx ;save &sizes[i+1]
jmp .150
.cycle_0: ;for (i=0; i < sizes_length; i++)
xor ecx,ecx
mov dword[ebp-4],ecx ;nextSize = 0
mov eax,[ebp+32] ;sizes_length
dec eax
cmp edi,eax
jae .152
mov edx,[ebp-8]
mov ecx,[edx]
mov dword[ebp-4],ecx ;nextSize = sizes[i+1]
.152:
mov eax,[ebp-4]
push eax
mov edx,[ebp-8]
mov ecx,[edx-4]
push ecx
mov ecx,edi
imul ecx,sizeof.Layer
mov eax,[ebp+8] ;o
mov edx,[eax+NeuralNetwork.layers]
add edx,ecx
stdcall Layer_Create,edx
xor esi,esi ;j=0
mov eax,[ebp-8]
lea edx,[eax-4]
mov dword[ebp-12],edx ;save &sizes[i]
jmp .154
.cycle_1: ;for (j=0; j < sizes[i]; j++)
call Math_random
fmul dword[f_2_0]
fsub dword[f_1_0]
mov eax,[ebp+8] ;o
mov ecx,edi
imul ecx,sizeof.Layer
add ecx,[eax+NeuralNetwork.layers]
mov ecx,[ecx+Layer.biases]
fstp qword[ecx+8*esi]
xor ebx,ebx ;k=0
cmp ebx,[ebp-4]
jae .157
@@: ;for (k=0; k < nextSize; k++)
call Math_random
fmul dword[f_2_0]
fsub dword[f_1_0]
mov eax,edi
imul eax,sizeof.Layer
mov edx,[ebp+8] ;o
mov ecx,[edx+NeuralNetwork.layers]
mov eax,[ecx+eax+Layer.weights]
mov edx,[eax+4*esi]
fstp qword[edx+8*ebx]
inc ebx
cmp ebx,[ebp-4]
jb @b
.157:
inc esi
.154:
mov ecx,[ebp-12]
cmp esi,[ecx]
jb .cycle_1
inc edi
add dword[ebp-8],4
.150:
cmp edi,[ebp+32] ;sizes_length
jb .cycle_0
;create errors array
push dword[ebp+8]
call NNP_GetMaxLLen
mov esi,eax
shl esi,4
stdcall @$bnwa$qui,esi
pop ecx
mov edx,[ebp+8]
mov dword[edx+NeuralNetwork.errors],eax
shr esi,1
add eax,esi
mov dword[edx+NeuralNetwork.errorsNext],eax
;create gradients array
stdcall @$bnwa$qui,esi
pop ecx
mov edx,[ebp+8]
mov dword[edx+NeuralNetwork.gradients],eax
;create deltas array
shr esi,1
stdcall @$bnwa$qui,esi
pop ecx
mov edx,[ebp+8]
mov dword[edx+NeuralNetwork.deltas],eax
pop edi esi ebx
mov esp,ebp
pop ebp
ret 28
align 4
f_2_0:
dd 2.0
f_1_0:
dd 1.0
;заполнение случайными числами
;+ 8 NeuralNetwork* o
align 16
NNP_Reset:
push ebp
mov ebp,esp
add esp,-8
push ebx esi edi
xor edi,edi ;i=0
jmp .3
.cycle_0: ;for (i=0; i < o->layers_length; i++)
xor esi,esi ;j=0
mov eax,edi
imul eax,sizeof.Layer
mov edx,[ebp+8]
add eax,[edx+NeuralNetwork.layers]
mov edx,[eax+Layer.n_size]
mov [ebp-4],edx
mov edx,[eax+Layer.c_size]
mov [ebp-8],edx
jmp .2
.cycle_1: ;for (j=0; j < o->layers[i].c_size; j++)
call Math_random
fmul dword[f_2_0]
fsub dword[f_1_0]
mov eax,[ebp+8] ;o
mov ecx,edi
imul ecx,sizeof.Layer
add ecx,[eax+NeuralNetwork.layers]
mov ecx,[ecx+Layer.biases]
fstp qword[ecx+8*esi]
xor ebx,ebx ;k=0
cmp ebx,[ebp-4]
jae .1
@@: ;for (k=0; k < o->layers[i].n_size; k++)
call Math_random
fmul dword[f_2_0]
fsub dword[f_1_0]
mov eax,edi
imul eax,sizeof.Layer
mov edx,[ebp+8] ;o
add eax,[edx+NeuralNetwork.layers]
mov eax,[eax+Layer.weights]
mov edx,[eax+4*esi] ;edx = &o->layers[i].weights[j]
fstp qword[edx+8*ebx] ;o->layers[i].weights[j][k] = Math_random()*2.0-1.0;
inc ebx ;k++
cmp ebx,[ebp-4]
jb @b
.1:
inc esi ;j++
.2:
cmp esi,[ebp-8]
jb .cycle_1
inc edi ;i++
.3:
mov ecx,[ebp+8] ;o
cmp edi,[ecx+NeuralNetwork.layers_length]
jb .cycle_0
pop edi esi ebx
mov esp,ebp
pop ebp
ret 4
;расчет входных и выходных нейронов
;+ 8 NeuralNetwork* o
;+12 double* inputs
align 16
NNP_FeedForward:
push ebp
mov ebp,esp
add esp,-4
push ebx esi edi
mov eax,[ebp+8]
mov eax,[eax+NeuralNetwork.layers]
mov ecx,[eax+Layer.c_size]
shl ecx,1
mov edi,[eax+Layer.neurons]
mov esi,[ebp+12]
rep movsd
mov edi,[ebp+8]
mov esi,[edi+NeuralNetwork.layers]
sub esi,sizeof.Layer
mov dword[ebp-4],1 ;i = 1
jmp .3
align 4
.cycle_0:
add esi,sizeof.Layer
xor ebx,ebx ;j=0
jmp .2
align 4
.cycle_1:
mov edx,[esi+sizeof.Layer+Layer.neurons]
xor eax,eax
mov dword[edx+8*ebx],eax
mov dword[edx+8*ebx+4],eax ;l1.neurons[j] = 0
;;xor eax,eax ;k=0
jmp .1
align 4
.cycle_2:
;l1.neurons[j] += l.neurons[k] * l.weights[k][j]
mov ecx,[esi+Layer.neurons] ;l.neurons
fld qword[ecx+8*eax] ;st0 = l.neurons[k]
mov ecx,[esi+Layer.weights]
mov ecx,[ecx+4*eax]
fmul qword[ecx+8*ebx] ;st0 *= l.weights[k][j]
fadd qword[edx+8*ebx] ;st0 += l1.neurons[j]
fstp qword[edx+8*ebx]
inc eax ;k++
.1:
cmp eax,[esi+Layer.c_size] ;k < l.c_size
jb .cycle_2
mov eax,[esi+sizeof.Layer+Layer.biases]
fld qword[eax+8*ebx]
fadd qword[edx+8*ebx]
sub esp,8
fstp qword[esp] ;push l1.neurons[j]
call dword[edi+NeuralNetwork.activation]
fstp qword[edx+8*ebx]
inc ebx ;j++
.2:
cmp ebx,[esi+sizeof.Layer+Layer.c_size] ;j < l1.c_size
jb .cycle_1
inc dword[ebp-4] ;i++
.3:
mov eax,[edi+NeuralNetwork.layers_length]
cmp eax,[ebp-4]
ja .cycle_0
mov eax,[esi+sizeof.Layer+Layer.neurons]
pop edi esi ebx
mov esp,ebp
pop ebp
ret 8
;+ 8 NeuralNetwork* o
;+12 double* targets
align 16
NNP_BackPropagation:
;cycle_0 for (i = 0; i < l.c_size; i++)
;cycle_1 for (; k >= 0; k--)
;cycle_2 for (i = 0; i < l1.c_size; i++)
;cycle_3 for (i = 0; i < l1.c_size; i++)
;cycle_4 for (j = 0; j < l.c_size; j++)
;cycle_5 for (i = 0; i < l.c_size; i++)
;cycle_6 for (j = 0; j < l1.c_size; j++)
;cycle_7 for (i = 0; i < l1.c_size; i++)
;cycle_8 for (j = 0; j < l.c_size; j++)
push ebp
mov ebp,esp
add esp,-12
push ebx esi edi
mov esi,[ebp+8]
mov edi,[esi+NeuralNetwork.layers_length]
dec edi
mov dword[ebp-4],edi ;k = o->layers_length - 1
imul edi,sizeof.Layer
add edi,[esi+NeuralNetwork.layers]
xor ebx,ebx ;i=0
mov eax,[ebp+12] ;eax = targets[]
jmp .180
align 4
.cycle_0:
mov edx,[edi+Layer.neurons]
mov ecx,[esi+NeuralNetwork.errors]
fld qword[eax]
fsub qword[edx+8*ebx]
fstp qword[ecx+8*ebx]
inc ebx
add eax,8
.180:
cmp ebx,[edi+Layer.c_size]
jb .cycle_0
dec dword[ebp-4] ;k--
cmp dword[ebp-4],0
jl .end_f
align 4
.cycle_1:
sub edi,sizeof.Layer
xor ebx,ebx ;i=0
jmp .186
align 4
.cycle_2:
mov eax,[edi+sizeof.Layer+Layer.neurons]
push dword[eax+8*ebx+4]
push dword[eax+8*ebx]
call dword[esi+NeuralNetwork.derivative]
mov ecx,[esi+NeuralNetwork.errors]
fmul qword[ecx+8*ebx]
fmul qword[esi+NeuralNetwork.learningRate]
mov edx,[esi+NeuralNetwork.gradients]
fstp qword[edx+8*ebx]
inc ebx
.186:
cmp ebx,[edi+sizeof.Layer+Layer.c_size]
jb .cycle_2
mov edx,[esi+NeuralNetwork.deltas]
xor ebx,ebx
jmp .189
align 4
.cycle_3:
mov eax,[edi+Layer.c_size]
shl eax,3
push eax
call @$bnwa$qui
pop ecx
mov dword[edx],eax
xor eax,eax ;j=0
jmp .191
align 4
.cycle_4:
mov ecx,[esi+NeuralNetwork.gradients]
fld qword[ecx+8*ebx]
mov ecx,[edi+Layer.neurons]
fmul qword[ecx+8*eax]
mov ecx,[edx]
fstp qword[ecx+8*eax]
inc eax
.191:
cmp eax,[edi+Layer.c_size]
jb .cycle_4
inc ebx
add edx,4
.189:
cmp ebx,[edi+sizeof.Layer+Layer.c_size]
jb .cycle_3
xor ebx,ebx
jmp .195
align 4
.cycle_5:
mov eax,[esi+NeuralNetwork.errorsNext]
xor edx,edx
mov dword[eax+8*ebx],edx
mov dword[eax+8*ebx+4],edx
xor eax,eax ;j=0
jmp .197
align 4
.cycle_6:
mov edx,[edi+Layer.weights]
mov ecx,[edx+4*ebx]
mov edx,[esi+NeuralNetwork.errors]
fld qword[ecx+8*eax]
fmul qword[edx+8*eax]
mov ecx,[esi+NeuralNetwork.errorsNext]
fadd qword[ecx+8*ebx]
fstp qword[ecx+8*ebx]
inc eax
.197:
cmp eax,[edi+sizeof.Layer+Layer.c_size]
jb .cycle_6
inc ebx
.195:
cmp ebx,[edi]
jb .cycle_5
;copy errors to next level
mov eax,[esi+NeuralNetwork.errors]
mov edx,[esi+NeuralNetwork.errorsNext]
mov dword[esi+NeuralNetwork.errors],edx
mov dword[esi+NeuralNetwork.errorsNext],eax
mov eax,[esi+NeuralNetwork.deltas]
mov dword[ebp-12],eax
xor ebx,ebx ;i=0
jmp .201
align 4
.cycle_7:
mov ecx,[esi+NeuralNetwork.gradients]
mov eax,[edi+sizeof.Layer+Layer.biases]
fld qword[ecx+8*ebx]
fadd qword[eax+8*ebx]
fstp qword[eax+8*ebx]
xor eax,eax ;j=0
mov edx,[ebp-12] ;edx = deltas[i]
jmp .203
align 4
.cycle_8:
; mov ecx,[edx]
; mov ecx,[ecx+8*eax+4]
; and ecx,0x7ff80000
; cmp ecx,0x7ff80000
; jne @f
; push ebx
; mov ecx,[edx]
; xor ebx,ebx
; mov dword[ecx+8*eax],ebx
; mov dword[ecx+8*eax+4],ebx
; pop ebx
;@@:
mov ecx,[edx]
fld qword[ecx+8*eax]
mov ecx,[edi+Layer.weights]
mov ecx,[ecx+4*eax]
fadd qword[ecx+8*ebx]
fstp qword[ecx+8*ebx]
; mov ecx,[edi+Layer.weights]
; mov ecx,[ecx+4*eax]
; mov ecx,[ecx+8*ebx+4]
; and ecx,0x7ff80000
; cmp ecx,0x7ff80000
; jne @f
; mov ecx,[edi+Layer.weights]
; mov ecx,[ecx+4*eax]
; push edx
; xor edx,edx
; mov dword[ecx+8*ebx],edx
; mov dword[ecx+8*ebx+4],edx
; pop edx
;@@:
inc eax
.203:
cmp eax,[edi+Layer.c_size]
jb .cycle_8
mov eax,[ebp-12]
stdcall @$bdele$qpv, [eax]
pop ecx
inc ebx
add dword[ebp-12],4
.201:
cmp ebx,[edi+sizeof.Layer+Layer.c_size]
jb .cycle_7
dec dword[ebp-4]
cmp dword[ebp-4],0
jge .cycle_1
.end_f:
pop edi esi ebx
mov esp,ebp
pop ebp
ret 8
;NNP_GetMemSize:
; todo
;+ 8 NeuralNetwork* o
;+12 unsigned long fmt
;+16 char* m_data
align 16
NNP_GetMemData:
push ebp
mov ebp,esp
add esp,-12
push ebx esi edi
cmp dword[ebp+12],NNP_FF_JSON
jne .end_f
mov esi,[ebp+16]
mov byte[esi],0
stdcall [_strcat], esi,txt_QlearningRateQ_
add esp,8
push 1
push PRECISION
mov eax,[ebp+8]
push dword[eax+NeuralNetwork.learningRate+4]
push dword[eax+NeuralNetwork.learningRate]
call @@DoubleToStr$qduso
add esp,16
stdcall [_strcat], esi,eax
add esp,8
stdcall [_strcat], esi,txt_zap_nl
add esp,8
stdcall [_strcat], esi,txt_Qlayers_lengthQ
add esp,8
push 1
push 0
mov ecx,[ebp+8]
fild dword[ecx+NeuralNetwork.layers_length]
add esp,-8
fstp qword[esp]
call @@DoubleToStr$qduso
add esp,16
stdcall [_strcat], esi,eax
add esp,8
stdcall [_strcat], esi,txt_zap_nl
add esp,8
.230:
stdcall [_strcat], esi,txt_QlayersQ
add esp,8
xor edi,edi ;i=0
jmp .232
align 4
.cycle_0:
push esi
call @@strlen$qpxc
pop ecx
add esi,eax
stdcall [_strcat], esi,txt_nl_t_Qc_sizeQ
add esp,8
mov ebx,edi
imul ebx,sizeof.Layer
push 1
push 0
mov edx,[ebp+8]
mov edx,[edx+NeuralNetwork.layers]
xor eax,eax
add esp,-8
mov ecx,[edx+ebx+Layer.c_size]
mov dword[ebp-12],ecx
mov dword[ebp-8],eax
fild qword[ebp-12]
fstp qword[esp]
call @@DoubleToStr$qduso
add esp,16
stdcall [_strcat], esi,eax
add esp,8
stdcall [_strcat], esi,txt_zap_nl_t_Qn_sizeQ
add esp,8
push 1
push 0
mov ecx,[ebp+8]
mov ecx,[ecx+NeuralNetwork.layers]
xor edx,edx
add esp,-8
mov eax,[ecx+ebx+Layer.n_size]
mov dword[ebp-12],eax
mov dword[ebp-8],edx
fild qword[ebp-12]
fstp qword[esp]
call @@DoubleToStr$qduso
add esp,16
stdcall [_strcat], esi,eax
add esp,8
stdcall [_strcat], esi,txt_zap_nl
add esp,8
stdcall [_strcat], esi,txt_t_QneuronsQ
add esp,8
xor ebx,ebx ;j=0
jmp .234
align 4
.cycle_1:
test ebx,ebx
je .235
stdcall [_strcat], esi,txt_zap_sp
add esp,8
.235:
push 1
push PRECISION
mov eax,edi
imul eax,sizeof.Layer
mov edx,[ebp+8]
mov ecx,[edx+NeuralNetwork.layers]
mov eax,[ecx+eax+Layer.neurons]
push dword[eax+8*ebx+4]
push dword[eax+8*ebx]
call @@DoubleToStr$qduso
add esp,16
stdcall [_strcat], esi,eax
add esp,8
inc ebx
.234:
mov ecx,edi
imul ecx,sizeof.Layer
mov eax,[ebp+8]
add ecx,[eax+NeuralNetwork.layers]
cmp ebx,[ecx+Layer.c_size]
jb .cycle_1
stdcall [_strcat], esi,txt_sqbr_zap_nl
add esp,8
stdcall [_strcat], esi,txt_t_QbiasesQ
add esp,8
xor ebx,ebx ;j=0
jmp .238
align 4
.cycle_2:
test ebx,ebx
je .239
stdcall [_strcat], esi,txt_zap_sp
add esp,8
.239:
push 1
push PRECISION
mov eax,edi
imul eax,sizeof.Layer
mov edx,[ebp+8]
add eax,[edx+NeuralNetwork.layers]
mov eax,[eax+Layer.biases]
push dword[eax+8*ebx+4]
push dword[eax+8*ebx]
call @@DoubleToStr$qduso
add esp,16
stdcall [_strcat], esi,eax
add esp,8
inc ebx
.238:
mov ecx,edi
imul ecx,sizeof.Layer
mov eax,[ebp+8]
add ecx,[eax+NeuralNetwork.layers]
cmp ebx,[ecx+Layer.c_size]
jb .cycle_2
stdcall [_strcat], esi,txt_sqbr_zap_t_QweightsQ
add esp,8
mov eax,[ebp+8]
mov ecx,edi
imul ecx,sizeof.Layer
add ecx,[eax+NeuralNetwork.layers]
cmp dword[ecx+Layer.n_size],0
je .241
xor ebx,ebx
jmp .243
.242:
test ebx,ebx
je .244
stdcall [_strcat], esi,txt_zap_nl_t_t
add esp,8
.244:
stdcall [_strcat], esi,txt_sqbro
add esp,8
xor eax,eax
mov dword[ebp-4],eax
jmp .246
.245:
cmp dword[ebp-4],0
je .247
stdcall [_strcat], esi,txt_zap_sp
add esp,8
.247:
push 1
push PRECISION
mov edx,edi
imul edx,sizeof.Layer
mov eax,[ebp+8]
add edx,[eax+NeuralNetwork.layers]
mov edx,[edx+Layer.weights]
mov ecx,[edx+4*ebx]
mov eax,[ebp-4]
push dword[ecx+8*eax+4]
push dword[ecx+8*eax]
@@:
call @@DoubleToStr$qduso
dec dword[esp+8] ;уменьшаем PRECISION
jz @f ;для избежания зацикливания
cmp word[eax],'#'
je @b ;если число не поместилось пробуем перевести с меньшей точностью
@@:
add esp,16
stdcall [_strcat], esi,eax
add esp,8
inc dword[ebp-4]
.246:
mov ecx,edi
imul ecx,sizeof.Layer
mov eax,[ebp+8]
add ecx,[eax+NeuralNetwork.layers]
mov ecx,[ecx+Layer.n_size]
cmp ecx,[ebp-4]
ja .245
stdcall [_strcat], esi,txt_sqbr
add esp,8
inc ebx
.243:
mov eax,edi
imul eax,sizeof.Layer
mov ecx,[ebp+8]
add eax,[ecx+NeuralNetwork.layers]
cmp ebx,[eax+Layer.c_size]
jb .242
.241:
stdcall [_strcat], esi,txt_sqbr_fbr_zap
add esp,8
inc edi
.232:
mov eax,[ebp+8]
cmp edi,[eax+NeuralNetwork.layers_length]
jb .cycle_0
stdcall [_strcat], esi,txt_nl_t_sqbr
add esp,8
.end_f:
pop edi esi ebx
mov esp,ebp
pop ebp
ret 12
;+ 8 NeuralNetwork* o
align 16
NNP_GetMaxLLen:
push ebp
mov ebp,esp
push ebx esi
mov ebx,[ebp+8]
cmp dword[ebx+NeuralNetwork.layers_length],1
jge .1
xor eax,eax
jmp .end_f
.1:
mov edx,[ebx+NeuralNetwork.layers]
lea eax,[edx+sizeof.Layer]
mov ecx,[edx]
mov edx,1 ;i=1
jmp .3
.cycle_0: ;for (i=1; i < o->layers_length; i++)
mov esi,[eax]
cmp esi,ecx
jbe .2
mov ecx,esi
.2:
inc edx
add eax,sizeof.Layer
.3:
cmp edx,[ebx+NeuralNetwork.layers_length]
jl .cycle_0
mov eax,ecx
.end_f:
pop esi ebx ebp
ret 4
;+ 8 NeuralNetwork* o
;+12 unsigned long fmt
;+16 void* m_data
align 16
NNP_SetMemData:
push ebp
mov ebp,esp
add esp,-12
push ebx esi edi
mov eax,[ebp+16]
mov edx,[ebp+12]
; cmp edx,NNP_FF_BIN
; jne .191
;...
;.191:
cmp edx,NNP_FF_JSON
jne .198
.199:
stdcall @@strstr$qpxct1, eax,txt_learningRate
add esp,8
mov esi,eax
stdcall @@strstr$qpxct1, esi,txt_layers_length
add esp,8
mov esi,eax
test esi,esi
jne .200
mov eax,1
jmp .193
.200:
stdcall @@strchr$qpxci, esi,':'
add esp,8
mov ebx,eax
test ebx,ebx
jne .201
mov eax,2
jmp .193
.201:
inc ebx
stdcall @@strchr$qpxci, esi,','
add esp,8
mov esi,eax
test esi,esi
jne .202
mov eax,3
jmp .193
.202:
mov byte[esi],0
inc esi
stdcall @@StrToInt$qpc, ebx
pop ecx
mov dword[ebp-4],eax
;lea eax,[ebp-4]
;stdcall [_scanf], ebx,txt_pri_zap,eax
;add esp,12
mov eax,[ebp+8]
mov edx,[eax+12]
cmp edx,[ebp-4]
je .203
mov eax,txt_err_layers_neq
jmp .193
.203:
xor edi,edi ;i=0
jmp .205
.204: ;for(i=0;i<o->layers_length;i++)
stdcall @@strstr$qpxct1, esi,txt_c_size
add esp,8
mov esi,eax
test esi,esi
jne .206
mov eax,txt_err_c_size
jmp .193
.206:
stdcall @@strchr$qpxci, esi,':'
add esp,8
mov ebx,eax
test ebx,ebx
jne .207
mov eax,6
jmp .193
.207:
inc ebx
stdcall @@strchr$qpxci, esi,','
add esp,8
mov esi,eax
test esi,esi
jne .208
mov eax,7
jmp .193
.208:
mov byte[esi],0
inc esi
stdcall @@StrToInt$qpc, ebx
pop ecx
mov dword[ebp-4],eax
stdcall @@strstr$qpxct1, esi,txt_n_size
add esp,8
mov esi,eax
test esi,esi
jne .209
mov eax,8
jmp .193
.209:
stdcall @@strchr$qpxci, esi,':'
add esp,8
mov ebx,eax
test ebx,ebx
jne .210
mov eax,9
jmp .193
.210:
inc ebx
stdcall @@strchr$qpxci, esi,','
add esp,8
mov esi,eax
test esi,esi
jne .211
mov eax,10
jmp .193
.211:
mov byte[esi],0
inc esi
stdcall @@StrToInt$qpc,ebx
pop ecx
mov dword[ebp-8],eax
mov eax,edi
imul eax,sizeof.Layer
mov edx,[ebp+8]
add eax,[edx+NeuralNetwork.layers]
mov edx,[eax+Layer.c_size]
cmp edx,[ebp-4]
jne .213
mov edx,[eax+Layer.n_size]
cmp edx,[ebp-8]
je .214
.213:
mov ecx,[ebp+8]
stdcall NNP_GetMaxLLen,ecx
mov ecx,edi
imul ecx,sizeof.Layer
mov ebx,eax
mov eax,[ebp+8]
mov edx,[eax+NeuralNetwork.layers]
add edx,ecx
stdcall Layer_Destroy,edx
mov eax,[ebp-8]
push eax
mov edx,[ebp-4]
push edx
mov edx,edi
imul edx,sizeof.Layer
mov ecx,[ebp+8]
mov eax,[ecx+NeuralNetwork.layers]
add eax,edx
stdcall Layer_Create,eax
cmp ebx,[ebp-4] ;if(n>s || k>s)
jb .215
cmp ebx,[ebp-8]
jae .214
.215:
mov edx,[ebp+8]
mov ecx,[edx+NeuralNetwork.errors]
cmp ecx,[edx+NeuralNetwork.errorsNext]
jl @f
mov ecx,[edx+NeuralNetwork.errorsNext]
@@:
mov ebx,[ebp-4]
cmp ebx,[ebp-8]
jge @f
mov ebx,[ebp-8]
@@:
shl ebx,4
stdcall [mem.realloc], ecx,ebx
mov edx,[ebp+8]
mov dword[edx+NeuralNetwork.errors],eax
shr ebx,1
add eax,ebx
mov dword[edx+NeuralNetwork.errorsNext],eax
stdcall [mem.realloc], [edx+NeuralNetwork.gradients],ebx
mov edx,[ebp+8]
mov dword[edx+NeuralNetwork.gradients],eax
shr ebx,1
stdcall [mem.realloc], [edx+NeuralNetwork.deltas],ebx
mov edx,[ebp+8]
mov dword[edx+NeuralNetwork.deltas],eax
.214:
stdcall @@strstr$qpxct1, esi,txt_biases
add esp,8
mov esi,eax
test esi,esi
jne .216
mov eax,11
jmp .193
.216:
stdcall @@strchr$qpxci, esi,'['
add esp,8
mov ebx,eax
test ebx,ebx
jne .217
mov eax,txt_err_sqbrl_b1
jmp .193
.217:
inc ebx
xor edx,edx
mov dword[ebp-8],edx
jmp .219
.218:
dec edx
cmp eax,edx
jae .220
stdcall @@strchr$qpxci, ebx,','
add esp,8
mov esi,eax
jmp .221
.220:
stdcall @@strchr$qpxci, ebx,']'
add esp,8
mov esi,eax
.221:
test esi,esi
jne .222
mov eax,13
jmp .193
.222:
mov byte[esi],0
stdcall @@StrToDouble$qpc,ebx
pop ecx
mov edx,edi
imul edx,sizeof.Layer
mov ecx,[ebp+8]
lea ebx,[esi+1]
mov eax,[ecx+NeuralNetwork.layers]
mov ecx,[ebp-8]
mov edx,[eax+edx+Layer.biases]
fstp qword[edx+8*ecx]
inc dword[ebp-8]
.219:
mov edx,edi
imul edx,sizeof.Layer
mov ecx,[ebp+8]
add edx,[ecx+NeuralNetwork.layers]
mov edx,[edx+Layer.c_size]
mov eax,[ebp-8]
cmp edx,eax
ja .218
mov esi,ebx
stdcall @@strstr$qpxct1, esi,txt_weights
add esp,8
mov esi,eax
test esi,esi
jne .224
mov eax,14
jmp .193
.224:
stdcall @@strchr$qpxci, esi,'['
add esp,8
mov esi,eax
test esi,esi
jne .225
mov eax,txt_err_sqbrl_w1
jmp .193
.225:
inc esi
xor edx,edx
mov dword[ebp-8],edx ;k=0
jmp .227
.226: ;for(k=0;k<o->layers[i].c_size;k++)
mov eax,edi
imul eax,sizeof.Layer
mov edx,[ebp+8]
add eax,[edx+NeuralNetwork.layers]
mov eax,[eax+Layer.n_size]
or eax,eax
jnz .end_null_we
inc dword[ebp-8] ;k++
jmp .227 ;if 'weights' is null array
.end_null_we:
stdcall @@strchr$qpxci, esi,'['
add esp,8
mov ebx,eax
test ebx,ebx
jne .228
mov eax,txt_err_sqbrl_w2
jmp .193
.228:
inc ebx
xor edx,edx
mov dword[ebp-12],edx ;j=0
jmp .230
.229: ;for(j=0;j<o->layers[i].n_size;j++)
dec edx
cmp eax,edx ;eax = j, edx = n_size-1
jae .231
stdcall @@strchr$qpxci, ebx,','
add esp,8
mov esi,eax
jmp .232
.231:
stdcall @@strchr$qpxci, ebx,']'
add esp,8
mov esi,eax
.232:
test esi,esi
jne .233
mov eax,txt_err_sqbrr_w2
jmp .193
.233:
mov byte[esi],0
stdcall @@StrToDouble$qpc,ebx
pop ecx
mov edx,edi
imul edx,sizeof.Layer
mov ecx,[ebp+8]
lea ebx,[esi+1]
mov eax,[ecx+NeuralNetwork.layers]
mov ecx,[ebp-8]
mov edx,[eax+edx+Layer.weights]
mov eax,[edx+4*ecx]
mov edx,[ebp-12]
fstp qword[eax+8*edx]
inc dword[ebp-12]
.230:
mov edx,edi
imul edx,sizeof.Layer
mov ecx,[ebp+8]
add edx,[ecx+NeuralNetwork.layers]
mov edx,[edx+Layer.n_size]
mov eax,[ebp-12]
cmp edx,eax
ja .229
mov esi,ebx
inc dword[ebp-8]
.227:
mov eax,edi
imul eax,sizeof.Layer
mov edx,[ebp+8]
add eax,[edx+NeuralNetwork.layers]
mov eax,[eax+Layer.c_size]
cmp eax,[ebp-8]
ja .226
inc edi
.205:
mov edx,[ebp+8]
cmp edi,[edx+NeuralNetwork.layers_length]
jb .204
xor eax,eax
jmp .193
.198:
mov eax,1000
.193:
pop edi esi ebx
mov esp,ebp
pop ebp
ret 12
align 16
Layer_Destroy:
push ebp
mov ebp,esp
push ebx esi
mov esi,[ebp+8]
push dword[esi+Layer.neurons]
call @$bdele$qpv
pop ecx
push dword[esi+Layer.biases]
call @$bdele$qpv
pop ecx
xor ebx,ebx
jmp .143
.142:
mov eax,[esi+Layer.weights]
push dword[eax+4*ebx]
call @$bdele$qpv
pop ecx
inc ebx
.143:
cmp ebx,[esi+Layer.c_size]
jb .142
push dword[esi+Layer.weights]
call @$bdele$qpv
pop ecx
.145:
pop esi ebx ebp
ret 4
align 16
NNP_Destroy:
push ebp
mov ebp,esp
push ebx esi
mov esi,[ebp+8]
xor ebx,ebx
jmp .232
.231:
mov eax,ebx
imul eax,sizeof.Layer
add eax,[esi+NeuralNetwork.layers]
push eax
call Layer_Destroy
inc ebx
.232:
cmp ebx,[esi+NeuralNetwork.layers_length]
jb .231
push dword[esi+NeuralNetwork.layers]
call @$bdele$qpv
pop ecx
;
mov ecx,[esi+NeuralNetwork.errors]
cmp ecx,[esi+NeuralNetwork.errorsNext]
jl @f
mov ecx,[esi+NeuralNetwork.errorsNext]
@@:
push ecx
call @$bdele$qpv
pop ecx
;
push dword[esi+NeuralNetwork.gradients]
call @$bdele$qpv
pop ecx
;
push dword[esi+NeuralNetwork.deltas]
call @$bdele$qpv
pop ecx
pop esi ebx ebp
ret 4
align 16
EXPORTS:
dd sz_lib_init, lib_init
dd sz_create, NNP_Create
dd sz_reset, NNP_Reset
dd sz_feedforward, NNP_FeedForward
dd sz_backpropagation, NNP_BackPropagation
dd sz_getmemdata, NNP_GetMemData
dd sz_setmemdata, NNP_SetMemData
dd sz_destroy, NNP_Destroy
dd 0,0
sz_lib_init db 'lib_init',0
sz_create db 'NNP_Create',0
sz_reset db 'NNP_Reset',0
sz_feedforward db 'NNP_FeedForward',0
sz_backpropagation db 'NNP_BackPropagation',0
sz_getmemdata db 'NNP_GetMemData',0
sz_setmemdata db 'NNP_SetMemData',0
sz_destroy db 'NNP_Destroy',0
align 16
@IMPORT:
library \
libc, 'libc.obj'
import libc, \
_strcat, 'strcat',\
_exp, 'exp'
;_scanf, 'scanf',\ ;???