【问题标题】:Fitting of Keras model with custom layer failedKeras 模型与自定义层的拟合失败
【发布时间】:2017-08-03 12:09:21
【问题描述】:

我在 keras (1.1) 中创建了我的自定义层:

from keras import backend as K
from keras.engine.topology import Layer
import numpy as np

class MyLayer(Layer):

def __init__(self,input_shape,**kwargs):
    self.W_init = np.random.rand(input_shape[0], input_shape[1], input_shape[2])
    self.input_len = input_shape[0]
    self.output_dim = 1
    super(MyLayer, self).__init__(**kwargs)

def build(self, input_shape):
    # Create a trainable weight variable for this layer.
    self.W = K.variable(self.W_init, name="W")
    self.trainable_weights = [ self.W ]
    super(MyLayer, self).build(input_shape)  # Be sure to call this somewhere!

def call(self, x, mask=None):
    res= K.sum(x*self.W,axis=(1,2))
    res= K.expand_dims(res, -1)
    res = K.expand_dims(res, -1)
    return res

def get_output_shape_for(self, input_shape):
    return (input_shape[0], self.input_len, self.output_dim, self.output_dim)

模型编译成功:

但是当我尝试安装它时,我得到了错误:

ValueError: cannot reshape array of size 64 into shape (1,4)
Apply node that caused the error: Reshape{2}(HostFromGpu.0, MakeVector{dtype='int64'}.0)
Toposort index: 895
Inputs types: [TensorType(float32, vector), TensorType(int64, vector)]
Inputs shapes: [(64,), (2,)]
Inputs strides: [(4,), (8,)]
Inputs values: ['not shown', array([1, 4])]
Inputs type_num: [11, 7]
Outputs clients: [[InplaceDimShuffle{0,1,x,x}(Reshape{2}.0)]]

Backtrace when the node is created(use Theano flag traceback.limit=N to make it longer):
  File "<ipython-input-155-09ee1207017c>", line 22, in get_my_model_2
    Dense(10, activation='softmax')
  File "/home/universal/anaconda3/envs/practicecourse2/lib/python2.7/site-packages/keras/models.py", line 255, in __init__
    self.add(layer)

我的自定义层中的可训练权重有问题吗?

【问题讨论】:

    标签: python keras layer


    【解决方案1】:

    由于您使用的是 Theano,因此宽度和高度轴是 (2,3),而不是 (1,2)

    也就是说,你应该换行:

        res= K.sum(x*self.W,axis=(1,2))
    

    进入

        res= K.sum(x*self.W,axis=(2,3))
    

    引发错误是因为call() 函数的输出具有(None, 4, 1, 1) 而不是(None, 64, 1, 1) 的形状,如get_output_shape_for() 中指定的那样。

    【讨论】:

    • 非常感谢!是不是因为轴编号以 1 开头,而不是 0?
    • 是的,在call() 内部,数组x 的轴0 将是批量大小。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多