2017-10-11 27 views
0

我想爲我的模型(用於訓練)得到categorical_crossentropy損失,它有最後一層:model.add(Dense(num_classes, activation='softmax'))。所以我想借此層,並使用follwing代碼的輸出使用下面的代碼獲取損失輸出:categorical_crossentropy損失,無屬性'get_shape'

from sklearn.metrics import confusion_matrix 
from __future__ import print_function 
import keras 
from keras.datasets import mnist 
from keras.models import Sequential 
from keras.layers import Dense, Dropout, Flatten 
from keras.layers import Conv2D, MaxPooling2D 
from keras import backend as K 
from keras.callbacks import TensorBoard 
import numpy as np 
from sklearn.model_selection import train_test_split 
import tensorflow as tf 
batch_size = 128 
num_classes = 3 
epochs = 1 

# input image dimensions 
img_rows, img_cols = 28, 28 


(x_train, y_train), (x_test, y_test) = mnist.load_data() 
x1_train=x_train[y_train==0]; y1_train=y_train[y_train==0] 
x1_test=x_test[y_test==0];y1_test=y_test[y_test==0] 
x2_train=x_train[y_train==1];y2_train=y_train[y_train==1] 
x2_test=x_test[y_test==1];y2_test=y_test[y_test==1] 
x3_train=x_train[y_train==2];y3_train=y_train[y_train==2] 
x3_test=x_test[y_test==2];y3_test=y_test[y_test==2] 

X=np.concatenate((x1_train,x2_train,x3_train,x1_test,x2_test,x3_test),axis=0) 
Y=np.concatenate((y1_train,y2_train,y3_train,y1_test,y2_test,y3_test),axis=0) 

# the data, shuffled and split between train and test sets 
x_train, x_test, y_train, y_test = train_test_split(X,Y) 

if K.image_data_format() == 'channels_first': 
    x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols) 
    x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols) 
    input_shape = (1, img_rows, img_cols) 
else: 
    x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1) 
    x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1) 
    input_shape = (img_rows, img_cols, 1) 

x_train = x_train.astype('float32') 
x_test = x_test.astype('float32') 
x_train /= 255 
x_test /= 255 
print('x_train shape:', x_train.shape) 
print(x_train.shape[0], 'train samples') 
print(x_test.shape[0], 'test samples') 

# convert class vectors to binary class matrices 
y_train = keras.utils.to_categorical(y_train, num_classes) 
y_test = keras.utils.to_categorical(y_test, num_classes) 

model = Sequential() 
model.add(Conv2D(1, kernel_size=(3, 3), 
       activation='relu', 
       input_shape=input_shape)) 
model.add(MaxPooling2D(pool_size=(2,2))) 

model.add(Flatten()) 

model.add(Dense(num_classes, activation='softmax')) 

model.compile(loss=keras.losses.categorical_crossentropy, 
       optimizer=keras.optimizers.Adadelta(), 
       metrics=['accuracy']) 

model.fit(x_train, y_train, 
      batch_size=batch_size, 
      epochs=epochs, 
      verbose=1, 
      validation_data=(x_test, y_test)) 
model.summary() 
get_dense_layer_output = K.function([model.layers[0].input], 
            [model.layers[3].output]) 
layer_output = get_dense_layer_output([x_train])[0] 
g=K.categorical_crossentropy(layer_output, y_train) 

,並收到錯誤:AttributeError: 'numpy.ndarray' object has no attribute 'get_shape'。如何解決它。

+0

恰好在您的代碼中發生錯誤的位置? – desertnaut

+0

g = K.categorical_crossentropy(layer_output,y_train)在這一行中 – Hitesh

+1

未來,最好省略代碼中與問題無關的所有部分(這裏是'x1,x2,x3' staff,'' Tensorboard','confusion_matrix','X,Y'等) - 他們只會使問題看起來不必要的長,並可能阻止潛在的受訪者... – desertnaut

回答

1

出於所有實際目的,Matias的回答是正確的。

教育目的(或任何其它目的,你可能有),這裏是與你的腳本發生&錯誤:

在所有Keras喪失功能,如K.categorical_crossentropy(),參數是張量(它確實有一個get_shape參數),而不是numpy數組(不這樣做) - 檢查docs。所以,你應該將numpy的陣列轉換爲張量,但在這之前,你必須扮演他們在同類型的(不是),否則你會得到一個錯誤:

y_train.dtype 
# dtype('float64') 

layer_output.dtype 
# dtype('float32') 

y_train = y_train.astype('float32') 
y_true = K.constant(y_train) 
y_pred = K.constant(layer_output) 
g = K.categorical_crossentropy(target=y_true, output=y_pred) 
g 
# <tf.Tensor 'Neg_1:0' shape=(16327,) dtype=float32> 

正如你所看到的,結果g爲(Tensorflow)張量,其需要進行評估:

ce = K.eval(g) # 'ce' for cross-entropy 
type(ce) 
# numpy.ndarray 
ce.shape 
# (16327,) 

結果是一個numpy的陣列爲您16327個訓練樣本中的每一個的損失。

+0

Thnx作爲有用的答案。但是損失函數應該返回一個值。像均方誤差損失,如以下代碼 '進口tensorflow作爲TF #Initialize會話 SESS = tf.InteractiveSession() 從keras進口後端爲K 進口numpy的作爲NP y_true = np.array([ ([1,1,1]) c = K.mean (c.eval()) #關閉會話以釋放資源 sess。close()' – Hitesh

+1

當然,因爲這裏包含'K.mean()'! 'K.categorical_crossentropy()'是每個樣本,就像你的例子中的K.square(y_pred - y_true) - 從我的答案中取出'ce'的平均值,你將會在那裏! – desertnaut

+0

是正確的。但爲什麼它沒有包含在函數定義[這裏](https://github.com/fchollet/keras/blob/master/keras/losses.py)第49行和第50行中 – Hitesh

1

您的網絡已在使用categorical_crossentropy正在接受培訓。爲了得到一個數據集的損耗值,你可以只使用model.evaluate

values = model.evaluate(X_train, y_train) 

然後values[0]將損失價值和values[1]是準確度量。

+0

我重新構建我的問題:在下面的代碼中,我想要c的值,這裏是真實labes,b是預測標籤:'從keras導入後端作爲K import numpy as np a = np.array ([1,2,3]) b = np.array([1,1,1]) c = K.categorical_crossentropy(a,b)'。但得到錯誤'AttributeError:'numpy.ndarray'對象沒有屬性'get_shape'' – Hitesh