简体   繁体   English

具有Tensorflow后端和Theano后端的Keras使用相同的模型和相同的输入进行不同的预测

[英]Keras with Tensorflow backend and Theano backend make different predictions with same model and same input

I tried to make predictions from a pre-trained model saved as json strings and h5 weights separately, however it seems different backend(Tensorflow and Theano) would give me different output even if the input and model are exactly the same. 我试图根据分别存储为json字符串和h5权重的预训练模型进行预测,但是即使输入和模型完全相同,后端(Tensorflow和Theano)似乎也会为我提供不同的输出。 I found even at the very first layer, which is a 1D convolution, the activations are different, here are the code to print part of the activation from 5th filter of the convolution1D layer: 我发现即使在第一层即一维卷积中,激活也不同,这是从convolution1D层的第5个过滤器打印部分激活的代码:

Theano version: Theano版本:

from keras.models import model_from_json
import numpy as np
import os
os.environ['KERAS_BACKEND'] = 'theano'

model_file = 'model.h5'
x_file = 'x.csv'

model_json = '{"class_name": "Model", "keras_version": "1.2.2", "config": {"layers": [{"class_name": "InputLayer", "config": {"batch_input_shape": [null, 1002, 6], "input_dtype": "float32", "sparse": false, "name": "input_1"}, "inbound_nodes": [], "name": "input_1"}, {"class_name": "Convolution1D", "config": {"batch_input_shape": [null, null, 6], "W_constraint": null, "b_constraint": null, "name": "convolution1d_1", "activity_regularizer": null, "trainable": true, "filter_length": 34, "init": "glorot_uniform", "bias": true, "nb_filter": 128, "input_dtype": "float32", "subsample_length": 1, "border_mode": "valid", "input_dim": 6, "b_regularizer": null, "W_regularizer": null, "activation": "relu", "input_length": null}, "inbound_nodes": [[["input_1", 0, 0]]], "name": "convolution1d_1"}], "input_layers": [["input_1", 0, 0]], "output_layers": [["convolution1d_1", 0, 0]], "name": "model_1"}}'
model = model_from_json(model_json)
model.load_weights(model_file)

x=np.loadtxt(x_file)
x = np.reshape(x,(1,x.shape[0],x.shape[1]))
y = model.predict(x)
y[0,range(230),4] 

The input and output look like: Theano version 输入和输出看起来像: Theano版本

Tensorflow version: Tensorflow版本:

from keras.models import model_from_json
import numpy as np
import os
os.environ['KERAS_BACKEND'] = 'tensorflow'

model_file = 'model.h5'
x_file = 'x.csv'

model_json = '{"class_name": "Model", "keras_version": "1.2.2", "config": {"layers": [{"class_name": "InputLayer", "config": {"batch_input_shape": [null, 1002, 6], "input_dtype": "float32", "sparse": false, "name": "input_1"}, "inbound_nodes": [], "name": "input_1"}, {"class_name": "Convolution1D", "config": {"batch_input_shape": [null, null, 6], "W_constraint": null, "b_constraint": null, "name": "convolution1d_1", "activity_regularizer": null, "trainable": true, "filter_length": 34, "init": "glorot_uniform", "bias": true, "nb_filter": 128, "input_dtype": "float32", "subsample_length": 1, "border_mode": "valid", "input_dim": 6, "b_regularizer": null, "W_regularizer": null, "activation": "relu", "input_length": null}, "inbound_nodes": [[["input_1", 0, 0]]], "name": "convolution1d_1"}], "input_layers": [["input_1", 0, 0]], "output_layers": [["convolution1d_1", 0, 0]], "name": "model_1"}}'
model = model_from_json(model_json)
model.load_weights(model_file)

x=np.loadtxt(x_file)
x = np.reshape(x,(1,x.shape[0],x.shape[1]))
y = model.predict(x)
y[0,range(230),4]

The input and output look like: Tensorflow version 输入和输出如下所示: Tensorflow版本

After a few experiments, I found Theano tend to have the "wrong" answer, here is an example to calculate the first window of the 5th filter(bias is zero in this model and I have checked that): 经过几次实验,我发现Theano往往会给出“错误”的答案,这是一个示例,用于计算第5个滤波器的第一个窗口(该模型中的bias为零,我已经检查过了):

l=model.get_layer(index=1)
w1 = l.get_weights()[0]
w2 = l.get_weights()[1]


data1 = w1[:,0,:,4]
data2 = x[0,range(34),:]
ans=0
for i in range(6):
    ans += np.sum(np.multiply(data1[:,i],data2[:,i]))

Ans equals to 0.08544020017143339 Tensorflow gives 0.08544022, identical to what should be from my calculation, however Theano gives 0.0518605. Ans等于0.08544020017143339 Tensorflow给出0.08544022,与根据我的计算应该是相同的,但是Theano给出了0.0518605。 Could anyone comes up with an explanation about that? 有人可以提出一个解释吗?

It seems the kernel weights in Theano are flipped during calcuation. 在计算过程中,看起来Theano的仁权重发生了变化。 Code below clearly showed the difference of Tensorflow and Theano: 下面的代码清楚地显示了Tensorflow和Theano的区别:

import numpy as np
import os
os.environ['KERAS_BACKEND'] = 'theano'

from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation,Convolution1D
from keras.optimizers import SGD

model = Sequential()
model.add(Convolution1D(1, 2, border_mode='valid', input_shape=(6, 1),bias=True,activation='relu'))

l=model.get_layer(index=1)
w1 = l.get_weights()[0]
w2 = l.get_weights()[1]
np.random.seed(0)
x = np.random.random((1,6,1))
y = model.predict(x)


a_tf = np.sum(np.multiply(w1[:,0,0,0],x[0,range(2),0])) # y[0,0] would equal to this with Tensorflow backend
a_th = np.sum(np.multiply(np.flip(w1[:,0,0,0]),x[0,range(2),0])) # y[0,0] would equal to this with Theano backend

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM