Tensorflow predict function doesn't behave like I would expect

Viewed 39

I try to understand the calculations of tensorflow and created a simple example with the mnist dataset. First I train this model (I know this won't train well):

model.add(Conv2D(4, (1, 1), activation='relu', kernel_initializer='he_uniform', padding='valid', strides=1, input_shape = input_shape))
model.add(MaxPooling2D((7, 7), padding='valid'))
model.add(Flatten())
model.add(Dense(10, activation='relu', kernel_initializer='he_uniform'))

Then I create arrays with weights and biases:

CNN Layer:
[[ 1.54 -0.  ]  <- filter 1: [weight bias] 
 [-2.43  0.  ] 
 [ 1.2  -0.11]  
 [-2.06  0.  ]] <- filter 4: [weight bias] 
NN Layer:
[[ 0.09 -0.07 -0.29  0.29 ... -0.03] <- output 1: [weight1-64 bias]
 [-0.35 -0.01 -0.3  -0.1  ...  0.05]
 ...
 [-0.13  0.26 -0.42  0.29 ... 0.04]] <- output 10: [weight1-64 bias]

For that I use this code:

cnn = np.zeros((4,2))

for f in range(0,4):
  cnn[f][0] = model.layers[0].weights[0][0][0][0][f]
  cnn[f][1] = model.layers[0].bias[f]

print(cnn)

nn = np.zeros((10,65))
for f in range(0,10):
  for i in range(0,64):
    nn[f][i] = model.layers[3].weights[0][i][f]
  nn[f][64] = float(model.layers[3].bias[f])

print(nn)

I assume that the order of the weights are: row * 16 + column * 4 + f Because this is how the flatten layer works.

After that I calculate the prediction myself with this code:

max=np.zeros((4,4,4))
out=np.zeros(10)

#Conv2D
for f in range(0,4):
  for y in range(0,28):
    for x in range(0,28):
      #Calculate convolution for pixel with one weight and bias
      d = test_data[0][y][x][0] * cnn[f][0] + cnn[f][1]
      #Only keep maximum value in 7x7 area -> Max Pooling
      if max[f][int(y/7)][int(x/7)] < d:
        max[f][int(y/7)][int(x/7)] = d

#Dense
for o in range(0,10):
  #Add Bias
  out[o] = nn[o][64]
  for f in range(0,4):
    for y in range(0,4):
      for x in range(0,4):
        #Apply weight to output from Max Pooling
        out[o] = out[o] + max[f][y][x] * nn[o][y*16+x*4+f]
    #ReLu
    if out[o] < 0:
      out[o] = 0

Sometimes I get exactly the same results as the prediction function. But often I get slightly different results like:

my calculation -> tensorflow
0.4958455 -> 0.4100589
0.0
0.3867072 -> 0.3395536
0.3473713
0.5230042 -> 0.2298216
0.7953386 -> 0.7953387
0.6598828 -> 0.5722865
1.6494241
0.6117965 -> 0.5601089
1.4232064

Is there some specific operation that I miss or is there documentation on how the tensorflow calculations work or the order of weights from the get_weights() function? My calculation can't be that way off, but maybe you spot an error. Or is there a way to calculate the result after one layer, so I could compare the result of my Conv2D and tensorflow's Conv2D calculation?

0 Answers
Related