package Ġcom . res nik . intel . neural . conv čĊč Ċ import Ġcom . res nik . math .* č Ċ import Ġcom . res nik . math . linear . array . Array Tensor č Ċ import Ġcom . res nik . math . linear . array . Array Dimension č Ċ import Ġcom . res nik . math . linear . array . Array Tensor Region Value Iterator č Ċ import Ġcom . res nik . math . linear . array . Array Tensor Value Iterator č Ċ import Ġjava . lang . IllegalStateException č Ċ import Ġjava . util .* č Ċ import Ġjava . util . stream . Int Stream č Ċ import Ġkotlin . math . sqrt čĊč Ċ class ĠConvolution al Layer ( val Ġnum Kernel s : ĠInt , Ġk ern al Dims Ġ: ĠInt Array , Ġval Ġinput Dims Ġ: ĠInt Array ) Ġ: ĠTensor Layer Ġ{ čĊčĊĠĠĠ Ġvar Ġkernels Ġ: ĠArray Tensor čĊĠĠĠ Ġval Ġkernel Dims Ġ: ĠInt Array čĊĠĠĠ Ġval Ġcross Correlation Map Sizes Ġ: ĠInt Array čĊĠĠĠ Ġval Ġoutput Dims Ġ: ĠInt Array čĊĠĠĠ Ġlateinit Ġvar Ġlast Input Ġ: ĠArray Tensor čĊčĊĠĠĠ Ġinit Ġ{ čĊĠĠĠĠĠĠĠ Ġthis . kernel Dims Ġ= ĠInt Array ( input Dims . size ){ 1 } čĊĠĠĠĠĠĠĠ Ġk ern al Dims . indices . forEach Ġ{ Ġthis . kernel Dims [ it ] Ġ= Ġk ern al Dims [ it ] Ġ} čĊĠĠĠĠĠĠĠ Ġcross Correlation Map Sizes Ġ= ĠInt Array ( input Dims . size ){ input Dims [ it ] Ġ- Ġthis . kernel Dims [ it ] Ġ+ Ġ 1 } čĊĠĠĠĠĠĠĠ Ġval Ġfilter Dims Ġ= Ġthis . kernel Dims . to Mutable List () čĊĠĠĠĠĠĠĠ Ġfilter Dims . add ( num Kernel s ) čĊĠĠĠĠĠĠĠ Ġval Ġrand Limit Ġ= Ġsqrt ( 2 . 0 ) Ġ/ Ġinput Dims . product () čĊĠĠĠĠĠĠĠ Ġval Ġrandom Ġ= ĠRandom () čĊĠĠĠĠĠĠĠ Ġthis . kernels Ġ= ĠArray Tensor ( Array Dimension (* filter Dims . to IntArray ())) Ġ{ Ġrandom . next Gaussian () Ġ* Ġrand Limit Ġ} čĊĠĠĠĠĠĠĠ Ġval Ġcross Correlation Map List Ġ= Ġcross Correlation Map Sizes . to Mutable List () čĊĠĠĠĠĠĠĠ Ġcross Correlation Map List . add ( num Kernel s ) čĊĠĠĠĠĠĠĠ Ġoutput Dims Ġ= Ġcross Correlation Map List . to IntArray () čĊĠĠĠ Ġ} čĊčĊĠĠĠ Ġoverride Ġfun Ġforward ( input : ĠArray Tensor ) Ġ: ĠArray Tensor Ġ{ čĊĠĠĠĠĠĠĠ Ġlast Input Ġ= Ġinput čĊĠĠĠĠĠĠĠ Ġvar Ġoutput Ġ: ĠArray Tensor ? Ġ= Ġnull čĊĠĠĠĠĠĠĠ Ġval Ġkernel Iterator Ġ= Ġkernels . region Iterator ( kernel Dims , ĠInt Array ( 0 )) čĊĠĠĠĠĠĠĠ Ġwhile ( kernel Iterator . hasNext ()){ čĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Map Ġ= Ġconv olve ( input , Ġkernel Iterator . next (), Ġcross Correlation Map Sizes ) čĊĠĠĠĠĠĠĠĠĠĠĠ Ġif ( output Ġ== Ġnull ){ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoutput Ġ= Ġnew Map čĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} else { čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoutput . append ( new Map , Ġkernels . dim . size ()) čĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠ Ġif ( output Ġ== Ġnull ){ čĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalStateException (" Output Ġcannot Ġbe Ġnull ") čĊĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠ Ġreturn Ġoutput čĊĠĠĠ Ġ} čĊčĊĠĠĠ Ġoverride Ġfun Ġbackward ( output Grad s : ĠArray Tensor , Ġlearning Rate : ĠDouble ): ĠArray Tensor Ġ{ čĊĠĠĠĠĠĠĠ Ġvar Ġkernel Grad s Ġ: ĠArray Tensor ? Ġ= Ġnull čĊĠĠĠĠĠĠĠ Ġvar Ġinput Grad s Ġ= Ġlast Input . clone Ġ{ Ġ 0 . 0 Ġ} čĊčĊĠĠĠĠĠĠĠ Ġval Ġoutput Grad Size Ġ= Ġoutput Grad s . dim . strip Last (). values čĊĠĠĠĠĠĠĠ Ġval Ġoutput Iterator Ġ= Ġoutput Grad s . region Iterator ( output Grad Size ) čĊĠĠĠĠĠĠĠ Ġval Ġkernel Iterator Ġ= Ġkernels . region Iterator ( kernel Dims ) čĊčĊĠĠĠĠĠĠĠ Ġwhile ( output Iterator . hasNext () Ġ&& Ġkernel Iterator . hasNext ()){ čĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġoutput Layer Ġ= Ġoutput Iterator . next () čĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġkernel Layer Ġ= Ġkernel Iterator . next () čĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Map Ġ= Ġconv olve ( last Input , Ġoutput Layer , Ġkernel Dims ) čĊĠĠĠĠĠĠĠĠĠĠĠ Ġif ( kernel Grad s Ġ== Ġnull ){ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġkernel Grad s Ġ= Ġnew Map čĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} else { čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġkernel Grad s Ġ= Ġkernel Grad s . append ( new Map , Ġoutput Grad s . dim . size ()) čĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpadding Ġ= ĠInt Array ( kernel Layer . dim . size ()){ kernel Layer . dim [ it ] Ġ- Ġ 1 } čĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġf lipped Kernel Ġ= Ġkernel Layer . flip () čĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġinput Grad Ġ= Ġconv olve ( output Layer , Ġf lipped Kernel , Ġinput Grad s . dim . values , Ġpadding ) čĊĠĠĠĠĠĠĠĠĠĠĠ Ġinput Grad s Ġ+= Ġinput Grad čĊĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠ Ġif ( kernel Grad s Ġ== Ġnull ){ čĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalStateException (" Kernel Ġgradients Ġcannot Ġbe Ġnull ") čĊĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠ Ġkernels Ġ= Ġkernels . minus ( kernel Grad s , Ġlearning Rate ) čĊĠĠĠĠĠĠĠ Ġreturn Ġinput Grad s čĊĠĠĠ Ġ} čĊčĊĠĠĠ Ġoverride Ġfun Ġinput Dimensions (): ĠArray Dimension Ġ= čĊĠĠĠĠĠĠĠ ĠArray Dimension (* input Dims ) čĊčĊĠĠĠ Ġoverride Ġfun Ġoutput Dimensions (): ĠArray Dimension Ġ= čĊĠĠĠĠĠĠĠ ĠArray Dimension (* output Dims ) čĊčĊĠĠĠ Ġcompanion Ġobject { čĊčĊĠĠĠĠĠĠĠ Ġ@ Jvm Static čĊĠĠĠĠĠĠĠ Ġfun Ġconv olve ( base Ġ: ĠArray Tensor , Ġkernel Ġ: ĠArray Tensor , Ġcc Map Size Ġ: ĠInt Array , Ġpadding Ġ: ĠInt Array Ġ= ĠInt Array ( 0 )) Ġ: ĠArray Tensor Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcc Map Values Ġ= ĠDouble Array ( cc Map Size . product ()){ 0 . 0 } čĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġregions Ġ= Ġmutable ListOf < Array Tensor Value Iterator >() čĊĠĠĠĠĠĠĠĠĠĠĠ ĠArray Tensor Region Value Iterator ( čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbase , čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġkernel . dim . values , čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpadding čĊĠĠĠĠĠĠĠĠĠĠĠ Ġ). forEach Remaining Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġregions . add ( it ) čĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠĠĠĠĠ ĠInt Stream . range ( 0 , Ġcc Map Values . size ). parallel (). forEach Ġ{ čĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcc Map Values [ it ] Ġ= Ġregions [ it ]. inner Product ( kernel ) čĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} čĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠArray Tensor ( Array Dimension (* cc Map Size )) Ġ{ Ġcc Map Values [ it ] Ġ} čĊĠĠĠĠĠĠĠ Ġ} čĊčĊĠĠĠ Ġ} čĊčĊč Ċ }