<s> import cudarray as ca <EOL> from ... base import ParamMixin <EOL> from ... parameter import Parameter <EOL> from . . base import Unary <EOL> class Linear ( Unary , ParamMixin ) : <EOL> def __init__ ( self , n_out , weights ) : <EOL> self . n_out = n_out <EOL> self . weights = Parameter . from_any ( weights ) <EOL> def __call__ ( self , x ) : <EOL> super ( Linear , self ) . __call__ ( x ) <EOL> self . bpropable = True <EOL> return self <EOL> def setup ( self ) : <EOL> batch_size , n_in = self . x . shape <EOL> self . shape = ( batch_size , self . n_out ) <EOL> self . array = ca . zeros ( self . shape ) <EOL> self . grad_array = ca . zeros ( self . shape ) <EOL> self . weights . setup ( ( n_in , self . n_out ) ) <EOL> def fprop ( self ) : <EOL> ca . dot ( self . x . array , self . weights . array , self . array ) <EOL> def bprop ( self ) : <EOL> ca . dot ( self . x . array . T , self . grad_array , self . weights . grad_array ) <EOL> ca . dot ( self . grad_array , self . weights . array . T , self . x . grad_array ) <EOL> @ property <EOL> def params ( self ) : <EOL> return self . weights , <EOL> @ params . setter <EOL> def params ( self , params ) : <EOL> self . weights , = params <EOL> class Affine ( Linear ) : <EOL> def __init__ ( self , n_out , weights , bias = <NUM_LIT:0.0> ) : <EOL> super ( Affine , self ) . __init__ ( n_out , weights ) <EOL> self . bias = Parameter . from_any ( bias ) <EOL> def setup ( self ) : <EOL> super ( Affine , self ) . setup ( ) <EOL> self . bias . setup ( ( <NUM_LIT:1> , self . n_out ) ) <EOL> def fprop ( self ) : <EOL> super ( Affine , self ) . fprop ( ) <EOL> self . array += self . bias . array <EOL> def bprop ( self ) : <EOL> super ( Affine , self ) . bprop ( ) <EOL> ca . sum ( self . grad_array , axis = <NUM_LIT:0> , keepdims = True , <EOL> out = self . bias . grad_array ) <EOL> @ property <EOL> def params ( self ) : <EOL> return self . weights , self . bias <EOL> @ params . setter <EOL> def params ( self , params ) : <EOL> self . weights , self . bias = params </s>
