我正在尝试根据Keras documentation创建一个带有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学习阶段而改变,但我想从gabor内核开始(只有真正的部分) 我的数据是图片,而不是随机的...... :)
感谢。
答案 0 :(得分: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)
答案 1 :(得分:1)
根据错误消息中的输入形状,我们可以确定(32,3,169,198)
是您的输入图像。
然后我假设另一个形状(1,32,1,1)
是你的滤镜形状。
过滤器的输出形状必须为32.好的,那里有一个32,但我不确定它是否在正确的位置。 (一旦我得到其他评论中提到的形状的印刷品,我就可以更新这些尺寸的顺序 - 但是现在,我正在运行重要的代码,我无法更改我的设置)
但其他方面都是错误的。您的过滤器应该塑造为: