Richard Schumi Jun Sun
Singapore Management University
ICSE'22
layer(average).
layer(flatten).
ai_components(X) :- layer(X).
?- ai_components(flatten).
?- ai_components(X).
# Prolog
Term
model = tf.keras.models.Sequential([
tf.keras.layers.Flatten(input_shape=(28, 28)),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Dense(10)
])
predictions = model(x_train[:1]).numpy()
# Tensorflow
# Semantics
# Def: Dense
For 1-D input and output, a dense layer is an affine transformation.
dense_layer ([I|Is], IWs , Bs , [O|Os ]) :-
depth ([I|Is ] ,2),
dense_node_comp (I, IWs , Bs , O),
dense_layer (Is , IWs , Bs , Os).
dense_layer ([I|Is], IWs , Bs , [O|Os ]) :-
depth ([I|Is],D), D > 2,
dense_layer (I, IWs , Bs , O),
dense_layer (Is , IWs , Bs , Os).
dense_layer ([] , _, _, []).
dense_node_comp ([I|Is ],[ IW|IWs],Res0 ,Res) :-
multiply_list_with (IW ,I, Res1 ),
add_lists (Res0 ,Res1 , Res2 ),
dense_node_comp (Is ,IWs ,Res2 ,Res).
dense_node_comp ([] ,[] , Res ,Res).
# Semantics: Dense
# Def: Conv1D
arguments:
conv1D_layer (Is , KernelSize ,IWs ,Bs , Strides , Padding ,Os):-
check_dimensions (Is ,3) ,
check_valid_kernel (Is , KernelSize , Padding ),
check_valid_weight_shapes (Is , KernelSize ,IWs ,Bs),
pool1D (sum ,Is , KernelSize , Strides , Padding ,IWs ,Bs ,false ,Os).
pool1D ( Poolfunc ,[I|Is], PoolSize , Strides , Padding ,IWs ,Bs , MultiLayerPool ,[O|Os ]):-
pool1D ( Poolfunc ,I ,0,0, PoolSize , Strides , Padding ,IWs ,Bs , MultiLayerPool ,[] ,O),
pool1D ( Poolfunc ,Is , PoolSize , Strides , Padding ,IWs ,Bs , MultiLayerPool ,Os).
pool1D (_ ,[] ,_,_,_,_,_,_ ,[]) .
pool1D ( Poolfunc ,[[I|Is0 ]| Is ],0,0, PoolSize , Strides ,true ,IWs ,Bs , MultiLayerPool ,[] , Os) :-
atomic (I),length ([[I|Is0 ]| Is],L),
calc_padding (L, PoolSize , Strides ,LeftP , RightP ),
padding1D ([[I|Is0 ]| Is], x,LeftP , RightP , Is1),
pool1D ( Poolfunc ,Is1 ,0,0, PoolSize , Strides ,false ,IWs ,Bs , MultiLayerPool ,[] , Os).
pool1D ( Poolfunc ,[[I|Is0 ]| Is],X ,0, PoolSize , Strides ,false ,IWs ,Bs ,false ,Os0 ,Os) :-
atomic (I),length ([[I|Is0 ]| Is],LX),
get_pool_res1D ( Poolfunc ,[[I|Is0 ]| Is],X,Y, PoolSize , Strides , IWs ,Bs ,false ,O),
insert_pool_field (Os0 ,O,true ,X,Y, Strides ,Os1),
(X+ Strides + PoolSize =< LX -> X1 is X+ Strides ; X1 is LX +1) ,
pool1D ( Poolfunc ,[[I|Is0 ]| Is],X1 ,0, PoolSize , Strides ,false ,IWs ,Bs ,false ,Os1 ,Os).
pool1D ( Poolfunc ,[[I|Is0 ]| Is],X,Y, PoolSize , Strides , Padding ,IWs , Bs ,true ,Os0 ,Os) :-
atomic (I),length ([[I|Is0 ]| Is],LX),
get_pool_res1D ( Poolfunc ,[[I|Is0 ]| Is],X,Y, PoolSize , Strides , IWs ,Bs ,true ,O),
insert_pool_field (Os0 ,O,true ,X,Y, Strides ,Os1),
(X+ Strides + PoolSize =< LX -> X1 is X+ Strides ,Y1 is Y; X1 is 0,Y1 is Y+1) ,
pool1D ( Poolfunc ,[[I|Is0 ]| Is],X1 ,Y1 , PoolSize , Strides , Padding , IWs ,Bs ,true ,Os1 ,Os).
pool1D (_ ,[[I|Is0 ]| Is],X,Y,_,_,false ,_,_,_,Os ,Os) :-
atomic (I),
( length ([[I|Is0 ]| Is],LX), X >= LX;
length ([I|Is0],LY), Y >= LY).
# Semantics: Conv1D
# Def: Dropout
dropout_layer (Is , Os , Rate , AcceptedRateDiff ) :-
count_atoms (Is ,N), count_atoms (Os ,NO), NO = N,
count_occurrences (Is ,0, NZeroOrig ),
count_occurrences (Os ,0, NZeroNew ),
RealRate is ( NZeroNew - NZeroOrig ) / (N -NZeroOrig ),
Diff is abs( Rate - RealRate ),
( Diff > AcceptedRateDiff -> ( write (" Expected Rate : "),
writeln ( Rate ), write (" Actual Rate : "), writeln (
RealRate ), false ); true ).
# Semantics: Dropout
# Recap
# Testing
A = max_pool1D_layer ([[[1.313 ,1.02] ,[1.45 ,1.92]]] ,1 ,1 , false , Max),
B = conv1D_layer ([[[0.9421 ,0.7879] ,[0.809 ,0.855]]] ,1 ,[[[0.572 , 0.621] ,[0.5388 , 0.5741]]] ,[0 ,0] , 1, false , 1, Con),
C = cropping1D_layer (Con , 5, 5, Cro),
D = concatenate_layer ([ Max ,Cro], 1, Con1 ),
exec_layers ([A,B,C,D],["Max","Con","Cro"," Con1 "],Con1 ," Con1 ")
# Model Validation
10,000 testcases generated in 35h
100 invalid models generated