2017-09-12 21 views
1

我想創建一個自定義初始化與Gabor內核根據Keras documentationKeras內核初始化與gabor過濾器

我正在編寫這個示例以便於運行和調試代碼。

import random 
from cv2.cv2 import CV_64F 
import keras.backend as K 
import numpy as np 
from keras.layers import Conv2D 
from sklearn.model_selection import train_test_split 
from sklearn.utils import shuffle 
from keras.utils import np_utils 
from keras.layers.convolutional import MaxPooling2D 
from keras.layers.core import Dense, Dropout, Activation, Flatten 
from keras.models import Sequential 
import cv2 
from theano import shared 


images_size = 100 
img_rows = 200 
img_cols = 200 
nb_channel = 3 


def custom_gabor(shape, dtype=None): 
    total_ker = [] 
    for i in xrange(shape[3]): 
     kernels = [] 
     for j in xrange(shape[2]): 
      kernels.append(
      cv2.getGaborKernel(ksize=(shape[0], shape[1]), sigma=1, 
      theta=1, lambd=0.5, gamma=0.3, psi=(3.14) * 0.5, 
      ktype=CV_64F)) 
     total_ker.append(kernels) 
    np_tot = shared(np.array(total_ker)) 
    return K.variable(np_tot, dtype=dtype) 


def build_model(): 
    model = Sequential() 
    # Layer 1 
    model.add(Conv2D(32, (3, 3), kernel_initializer=custom_gabor, 
             input_shape=(nb_channel, img_rows, img_cols))) 
    model.add(Activation('relu')) 
    # Layer 2 
    model.add(MaxPooling2D(pool_size=(2, 2))) 
    model.add(Conv2D(32, (3, 3), kernel_initializer=custom_gabor)) 
    model.add(Activation('relu')) 
    model.add(MaxPooling2D(pool_size=(2, 2))) 

    # Layer 3 
    model.add(Conv2D(32, (3, 3), kernel_initializer=custom_gabor)) 
    model.add(Activation('relu')) 
    model.add(MaxPooling2D(pool_size=(2, 2))) 

    model.add(Dropout(0.25)) 
    model.add(Flatten()) 
    model.add(Dense(64)) 
    model.add(Activation('relu')) 
    model.add(Dropout(0.5)) 

    model.add(Dense(2)) 
    model.add(Activation('softmax')) 

    model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy']) 
    return model 


def make_dummy_data_set(): 
    img_matrix = [] 
    for i in xrange(images_size): 
     img_matrix.append([random.random() for _ in xrange(img_rows*img_cols*nb_channel)]) 

    img_matrix = np.array(img_matrix) 
    label = np.array([random.randint(0, 1) for _ in xrange(images_size)]) 

    data, label = shuffle(img_matrix, label, random_state=7) # random_state=2 
    X_train, X_test, y_train, y_test = train_test_split(data, label, test_size=0.2, random_state=7) 

    # reshape the data 
    X_train = X_train.reshape(X_train.shape[0], nb_channel, img_rows, img_cols) 
    X_test = X_test.reshape(X_test.shape[0], nb_channel, img_rows, img_cols) 

    X_train = X_train.astype('float32') 
    X_test = X_test.astype('float32') 

    # convert class vectore to binary class matrices 
    y_train = np_utils.to_categorical(y_train, 2) 
    y_test = np_utils.to_categorical(y_test, 2) 

    return X_train, X_test, y_train, y_test 


def train_model(model, X_train, X_test, y_train, y_test): 
    model.fit(X_train, 
       y_train, 
       batch_size=32, 
       epochs=5, 
       verbose=1, 
       validation_data=(X_test, y_test)) 


if __name__ == "__main__": 
    model = build_model() 
    X_train, X_test, y_train, y_test = make_dummy_data_set() 
    train_model(model, X_train, X_test, y_train, y_test) 

當我運行它,我得到錯誤「輸入尺寸不匹配」:

Using Theano backend. 
Train on 80 samples, validate on 20 samples 
Epoch 1/5 
Traceback (most recent call last): 
File "/home/naor/Desktop/workspace/reflux_analyze/core/tests/test.py", 
line 104, in <module> 
train_model(model, X_train, X_test, y_train, y_test) 
File "/home/naor/Desktop/workspace/reflux_analyze/core/tests/test.py", line 98, in train_model 
validation_data=(X_test, y_test)) 
File "/home/naor/Desktop/workspace/reflux_analyze/local/lib/python2.7/site-packages/keras/models.py", line 867, in fit 
initial_epoch=initial_epoch) 
File "/home/naor/Desktop/workspace/reflux_analyze/local/lib/python2.7/site-packages/keras/engine/training.py", line 1598, in fit 
validation_steps=validation_steps) 
File "/home/naor/Desktop/workspace/reflux_analyze/local/lib/python2.7/site-packages/keras/engine/training.py", line 1183, in _fit_loop 
outs = f(ins_batch) 
File "/home/naor/Desktop/workspace/reflux_analyze/local/lib/python2.7/site-packages/keras/backend/theano_backend.py", line 1222, in __call__ 
return self.function(*inputs) 
File "/home/naor/Desktop/workspace/reflux_analyze/local/lib/python2.7/site-packages/theano/compile/function_module.py", line 898, in __call__ 
storage_map=getattr(self.fn, 'storage_map', None)) 
File "/home/naor/Desktop/workspace/reflux_analyze/local/lib/python2.7/site-packages/theano/gof/link.py", line 325, in raise_with_op 
reraise(exc_type, exc_value, exc_trace) 
File "/home/naor/Desktop/workspace/reflux_analyze/local/lib/python2.7/site-packages/theano/compile/function_module.py", line 884, in __call__ 
self.fn() if output_subset is None else\ 
ValueError: Input dimension mis-match. (input[0].shape[1] = 3, input[1].shape[1] = 32) 
Apply node that caused the error: Elemwise{Add}[(0, 0)](CorrMM{valid, 
(1, 1), (1, 1)}.0, InplaceDimShuffle{x,0,x,x}.0) 
Toposort index: 73 
Inputs types: [TensorType(float32, 4D), TensorType(float32, (True, 
False, True, True))] 
Inputs shapes: [(32, 3, 169, 198), (1, 32, 1, 1)] 
Inputs strides: [(401544, 133848, 792, 4), (128, 4, 4, 4)] 
Inputs values: ['not shown', 'not shown'] 
Outputs clients: [[Elemwise{Composite{(i0 * (i1 + Abs(i1)))}} 
(TensorConstant{(1, 1, 1, 1) of 0.5}, Elemwise{Add}[(0, 0)].0), 
Elemwise{Composite{((i0 * i1) + (i0 * i1 * sgn(i2)))}}[(0, 1)] 
(TensorConstant{(1, 1, 1, 1) of 0.5}, MaxPoolGrad{ignore_border=True, 
mode='max', ndim=2}.0, Elemwise{Add}[(0, 0)].0)]] 

HINT: Re-running with most Theano optimization disabled could give you a back-trace of when this node was created. This can be done with by setting the Theano flag 'optimizer=fast_compile'. If that does not work, Theano optimizations can be disabled with 'optimizer=None'. 
HINT: Use the Theano flag 'exception_verbosity=high' for a debugprint and storage map footprint of this apply node. 

Process finished with exit code 1 

我知道這個內核將被CNN學習階段變化,但我想從thows的Gabor內核啓動(只有實際的部分) 而我的數據是一張圖片,而不是一個隨機... :)

謝謝。

+0

你有沒有在keras到'channels_first'改變你的標準'data_format'?它使用'channels_last'作爲默認值。在'cannels_last'中,你的過濾器形狀應該是'(kernel_rows,kernel_columns,input_channels,output_channels)'。我不確定'channels_first'的正確形狀是什麼。 –

+0

是的,我keras.json看起來像這樣: { 「小量」:1E-07, 「floatx」: 「FLOAT32」, 「image_data_format」: 「channels_first」, 「後臺」: 「theano」 「image_dim_ordering」:「th」 } 請儘量幫助我,我真的堅持這一點。 – Naor88

+0

您能否打印以下內容? - 定義你的模型沒有gabor並且打印:'model.layers [1] .get_weights [0] .shape'(確保'layers [1]'是第一個卷積層。) –

回答

1

根據錯誤信息中的輸入形狀,我們可以確定(32,3,169,198)是您的輸入圖像。

  • 他們是32個圖像(batch_size),有3個通道,邊169,198。

然後我假設其他形狀(1,32,1,1)是你的過濾器形狀。

你的過濾器的輸出形狀必須是32.好的,那裏有32個,但我不確定它在正確的位置。 (一旦我得到我在其他評論中詢問的形狀圖案,我可以更新這些尺寸的順序 - 但現在,我正在運行重要的代碼,我無法更改我的設置)

但其他維度都是錯誤的。您的過濾器應被成形爲:

  • 32,與在卷積層
  • 3(nb_channel)的32個單元(輸出通道),與進入該層
  • 3的輸入信道,與內核的大小1
  • 3,關於內核大小2
+1

感謝您的幫助!問題在於custom_gabor返回的形狀,更準確地說是cv2.getGaborKernel返回與我們期望的通過ksize變量不同的大小。 我會在另一條評論中添加固定代碼 – Naor88

2
def custom_gabor(shape, dtype=None): 
    total_ker = [] 
    for i in xrange(shape[0]): 
     kernels = [] 
     for j in xrange(shape[1]): 
     # gk = gabor_kernel(frequency=0.2, bandwidth=0.1) 
     tmp_filter = cv2.getGaborKernel(ksize=(shape[3], shape[2]), sigma=1, theta=1, lambd=0.5, gamma=0.3, psi=(3.14) * 0.5, 
          ktype=CV_64F) 
      filter = [] 
      for row in tmp_filter: 
       filter.append(np.delete(row, -1)) 
      kernels.append(filter) 
       # gk.real 
     total_ker.append(kernels) 
    np_tot = shared(np.array(total_ker)) 
    return K.variable(np_tot, dtype=dtype)