2017-02-08 27 views
2

我想使用帶張量流後端的Keras順序模型來生成RNN。當我執行下面的代碼:重塑的輸入是一個帶有2 *「batch_size」值的張量,但所要求的形狀有「batch_size」

batch_size = 8 
batch_inputshape = (batch_size,x_train.shape[1],x_train.shape[2]) 
print(batch_inputshape) #(8, 600, 103) 
​ 
model = Sequential() 
model.add(LSTM(103, 
       batch_input_shape = batch_inputshape, 
       return_sequences = True, 
       stateful = True)) 
model.add(Dropout(0.2)) 
​ 
model.add(LSTM(50, 
       return_sequences = True, 
       stateful = True)) 
model.add(Dropout(0.2)) 
​ 
​ 
model.add(TimeDistributed(Dense(10))) 
model.add(TimeDistributed(Dense(2))) 
model.add(Activation('softmax')) 
model.compile(loss= ncce, optimizer='adam') ​ 
​ 
print (model.output_shape) #(8, 600, 2) 

model.fit(x_train,y_train, batch_size = batch_size, 
          nb_epoch = 1, validation_split=0.25) 

我得到了如下錯誤信息:

輸入重塑是16個值的張量,但被請求的形狀有8

但無論我將batch_size更改爲錯誤將僅遵循以下公式:

輸入重塑是一個張量,其值爲2 * batch_size,但請求的sha pe有batch_size

我已經看過其他Q&A,但我認爲他們沒有多大幫助。或者我不太瞭解答案。

任何幫助將不勝感激!

編輯: 作爲請求的輸入和目標的形狀:

print(x_train.shape) #(512,600,103) 
print(y_train.shape) #(512,600,2) 

編輯2:

from functools import partial 
import keras.backend as K 
from itertools import product 
​ 
def w_categorical_crossentropy(y_true, y_pred, weights): 
    # https://github.com/fchollet/keras/issues/2115#issuecomment-274101310 # 
    nb_cl = len(weights) 
    final_mask = K.zeros_like(y_pred[:, 0]) 
    y_pred_max = K.max(y_pred, axis=1) 
    y_pred_max = K.reshape(y_pred_max, (K.shape(y_pred)[0], 1)) 
    y_pred_max_mat = K.cast(K.equal(y_pred, y_pred_max), K.floatx()) 
    for c_p, c_t in product(range(nb_cl), range(nb_cl)): 
     final_mask += (weights[c_t, c_p] * y_pred_max_mat[:, c_p] * y_true[:, c_t]) 
    return K.categorical_crossentropy(y_pred, y_true) * final_mask 
​ 
w_array = np.ones((2,2)) 
w_array[1, 0] = 100 
​ 
​ 
print(w_array) 
ncce = partial(w_categorical_crossentropy, weights=w_array) 
ncce.__name__ ='w_categorical_crossentropy 

EDIT 3:UPDATE

隨着@Nassim奔幫助,他發現問題在於損失函數。他發佈了一個具有常規損失函數的代碼,然後它工作得很好。但是,自定義丟失函數代碼不起作用。正如這個問題的任何讀者可以看到我上面發佈我的costum損失函數,並有問題。目前我還不知道爲什麼存在這個錯誤,但這是目前的狀態。

+0

在您的自定義損失 - 您想要應用您的最大功能的哪個維度?要排序維度還是要素維度? –

+0

更新我的帖子,它現在應該工作。它正在我身邊 –

回答

0

編輯: 此代碼適用於我,我只是爲了簡單而改變了損失。

import keras 
from keras.layers import * 
from keras.models import Sequential 
from keras.objectives import * 
import numpy as np 

x_train = np.random.random((512,600, 103)) 
y_train = np.random.random((512,600,2)) 
batch_size = 8 
batch_inputshape = (batch_size,x_train.shape[1],x_train.shape[2]) 
print(batch_inputshape) #(8, 600, 103) 

model = Sequential() 
model.add(LSTM(103, 
      batch_input_shape = batch_inputshape, 
      return_sequences = True, 
      stateful = True)) 
model.add(Dropout(0.2)) 
model.add(LSTM(50, 
      return_sequences = True, 
      stateful = True)) 
model.add(Dropout(0.2)) 


model.add(TimeDistributed(Dense(10))) 
model.add(TimeDistributed(Dense(2))) 
model.add(Activation('softmax')) 
model.compile(loss= "mse", optimizer='adam') 

print (model.output_shape) #(8, 600, 2) 

model.fit(x_train,y_train, batch_size = batch_size, 
         nb_epoch = 1, validation_split=0.25) 

編輯2:

因此錯誤是從損失函數來了。在你從github複製的代碼中,他們有形狀的輸出(批次,10)。你有形狀的輸出(批次,600,2)。所以這裏是我對該功能的編輯:

def w_categorical_crossentropy(y_true, y_pred, weights): 
# https://github.com/fchollet/keras/issues/2115#issuecomment-274101310 # 
    nb_cl = len(weights) 
    # Create a mask with zeroes 
    final_mask = K.zeros_like(y_pred[:,:,0]) 
    # get the maximum probability value for every output (shape = (batch,600,1)) 
    y_pred_max = K.max(y_pred, axis=2, keepdims=True) 
    # Get the actual predictions for every output (shape = (batch,600,2)) 
    # This K.equal uses broadcasting, we compare two tensors of different sizes but it works (magic) 
    y_pred_max_mat = K.equal(y_pred, y_pred_max) 
    for c_p, c_t in product(range(nb_cl), range(nb_cl)): 
     # Create the mask of weights to apply to the result of the cat_crossentropy 
     final_mask += (weights[c_t, c_p] * K.cast(y_pred_max_mat[:,:, c_p], K.floatx()) * y_true[:,:, c_t]) 
    return K.categorical_crossentropy(y_pred, y_true) * final_mask 

w_array = np.ones((2,2)) 
w_array[1, 0] = 100 

正如你所看到的,我只是修改了索引播放,因爲你的特定形狀。 面具必須具有形狀(批次,600)。 最大值必須在第三維上完成,因爲存在您想要輸出的概率。 由於張量的形狀,矩陣乘法生成的最大值也需要更新。

這應該工作。

如果您需要更詳細的解釋,請隨時詢問:-)

+0

x_train.shape =(512,600,103)和, y_train.shape =(512,600,2) 我不明白你的建議解決方案。因爲在順序模型中,你的x應該是一個3維的張量,對嗎?像: (樣本,序列,功能) – NeoTT

+0

好吧,你的代碼在我的機器上運行,你的配置是什麼? Keras版本,後端? 你說得對,我的回答太快了。你的代碼在我的機器上沒問題 –

+0

我在哪裏可以找到這些版本號? – NeoTT

相關問題