首页 > 解决方案 > 如何在 python 函数中使用 Keras 函数式 API,出现错误:TypeError: float() argument must be a string or a number, not 'Dimension'

问题描述

我正在尝试在使用 Inception 样式模块的 keras 中编写卷积神经网络,例如keras 功能 API 页面中的示例。为了“简化”事情,我决定把这个模块放在一个 python 函数中,以便在不同的过滤器和输入大小下重复使用。但是,这会生成错误消息:

TypeError:float() 参数必须是字符串或数字,而不是“维度”

这个函数应该怎么写,这个有什么问题

"""This is the "inception" module."""
def incepm_v1(out_filters, input_shape)->Model:
    from keras.layers import Conv2D, MaxPooling2D, Input

    input_img = Input(shape=input_shape)

    tower_1 = Conv2D(out_filters, (1, 1), padding='same', 
        activation='relu')(input_img)
    tower_1 = Conv2D(out_filters, (3, 3), padding='same', 
        activation='relu')(tower_1)

    tower_2 = Conv2D(out_filters, (1, 1), padding='same', 
        activation='relu')(input_img)
    tower_2 = Conv2D(out_filters, (5, 5), padding='same', 
        activation='relu')(tower_2)

    tower_3 = MaxPooling2D((3, 3), strides=(1, 1), padding='same') 
        (input_img)
    tower_3 = Conv2D(out_filters, (1, 1), padding='same', 
        activation='relu')(tower_3)

    output = keras.layers.concatenate([tower_1, tower_2, tower_3], 
        axis=1)

    model = Model(inputs=input_img, outputs=output)
    return model

"This is then used in the following model"
def Unetish_model1(image_shape=(IMAGE_SIZE, IMAGE_SIZE, 3)):
    image = Input(shape=image_shape)

    #First layer 96X96
    conv1 = Conv2D(32, (3,3),padding='same', activation = 
        'relu'(image)
    conv1out = Conv2D(16, (1,1),padding = 'same', activation = 
    'relu')(conv1)
    conv1out = MaxPooling2D((2,2), strides = (2,2))(conv1out)
    aux1out = Conv2D(16, (1,1), padding = 'same', activation  = 
        'relu')(conv1)

    #Second layer 48x48
    #print(conv1out.shape)
    conv2 = incepm_v1(64, conv1out.shape[1:])(conv1out)
    conv2out = Conv2D(32, (1,1), padding = 'same', activation = 
        'relu')(conv2)
    conv2out = MaxPooling2D((2,2), strides = (2,2))(conv2out)
    aux2out = Conv2D(32, (1,1), padding = 'same', activation  = 
        'relu')(conv2)

    ".... removed for sparsity"


    model = Model(inputs =image, outputs = output)

    model.summary()
    return model

IMAGE_SIZE = 96
Unet = Unetish_model1(image_shape=(IMAGE_SIZE, IMAGE_SIZE, 3))



-------------------------------------------------------------------- 
-------
TypeError                                 Traceback (most recent 
call last)
<ipython-input-79-9f51199eb354> in <module>()
      1 IMAGE_SIZE = 96
----> 2 Unet = Unetish_model1(image_shape=(IMAGE_SIZE, IMAGE_SIZE, 
    3))

<ipython-input-78-663bab493362> in Unetish_model1(image_shape)
     10     #Second layer 48x48
     11     #print(conv1out.shape)
---> 12     conv2 = incepm_v1(64, conv1out.shape[1:])(conv1out)
     13     conv2out = Conv2D(32, (1,1), padding = 'same', 
activation = 'relu')(conv2)
     14     conv2out = MaxPooling2D((2,2), strides = (2,2)) 
    (conv2out)

<ipython-input-72-b8563ad454e6> in incepm_v1(out_filters, 
input_shape)
      4     input_img = Input(shape=input_shape)
      5 
----> 6     tower_1 = Conv2D(out_filters, (1, 1), padding='same', 
activation='relu')(input_img)
      7     tower_1 = Conv2D(out_filters, (3, 3), padding='same', 
activation='relu')(tower_1)
      8 

~/anaconda3/envs/dlib/lib/python3.5/site- 
    packages/keras/engine/topology.py in __call__(self, inputs, 
**kwargs)
    588                                          
'`layer.build(batch_input_shape)`')
    589                 if len(input_shapes) == 1:
--> 590                     self.build(input_shapes[0])
    591                 else:
    592                     self.build(input_shapes)

~/anaconda3/envs/dlib/lib/python3.5/site- 
    packages/keras/layers/convolutional.py in build(self, 
    input_shape)
    136                                       name='kernel',
    137                                       
    regularizer=self.kernel_regularizer,
--> 138                                       
 constraint=self.kernel_constraint)
    139         if self.use_bias:
    140             self.bias = self.add_weight(shape= 
    (self.filters,),

    ~/anaconda3/envs/dlib/lib/python3.5/site- 
    packages/keras/legacy/interfaces.py in wrapper(*args, **kwargs)
         89                 warnings.warn('Update your `' + 
    object_name +
     90                               '` call to the Keras 2 API: ' 
    + signature, stacklevel=2)
    ---> 91             return func(*args, **kwargs)
     92         wrapper._original_function = func
     93         return wrapper

     ~/anaconda3/envs/dlib/lib/python3.5/site- 
    packages/keras/engine/topology.py in add_weight(self, name, 
    shape, dtype, initializer, regularizer, trainable, constraint)
    409         if dtype is None:
    410             dtype = K.floatx()
--> 411         weight = K.variable(initializer(shape),
    412                             dtype=dtype,
    413                             name=name,

 ~/anaconda3/envs/dlib/lib/python3.5/site- 
    packages/keras/initializers.py in __call__(self, shape, dtype)
    207             scale /= max(1., fan_out)
    208         else:
--> 209             scale /= max(1., float(fan_in + fan_out) / 2)
    210         if self.distribution == 'normal':
    211             stddev = np.sqrt(scale)

TypeError: float() argument must be a string or a number, not 
    'Dimension'

我在 anaconda 环境中使用 keras 版本 2.1.3,TensorFlow 以 gpu 为后端

标签: pythonkerasdeep-learning

解决方案


layer_name.shape会给你一个tensorflow.python.framework.tensor_shape.TensorShape包含tensorflow.python.framework.tensor_shape.Dimension.

在这种情况下,您应该使用K.int_shape(layer_name),它为您提供整数元组。

from keras.layers import Conv2D, MaxPooling2D, Input, Concatenate
from keras.models import Model
import keras.backend as K

"""This is the "inception" module."""
def incepm_v1(out_filters, input_shape)->Model:
    input_img = Input(shape=input_shape)

    tower_1 = Conv2D(out_filters, (1, 1), padding='same', 
        activation='relu')(input_img)
    tower_1 = Conv2D(out_filters, (3, 3), padding='same', 
        activation='relu')(tower_1)

    tower_2 = Conv2D(out_filters, (1, 1), padding='same', 
        activation='relu')(input_img)
    tower_2 = Conv2D(out_filters, (5, 5), padding='same', 
        activation='relu')(tower_2)

    tower_3 = MaxPooling2D((3, 3), strides=(1, 1), padding='same')(input_img)
    tower_3 = Conv2D(out_filters, (1, 1), padding='same', 
        activation='relu')(tower_3)

    output = Concatenate(axis=1)([tower_1, tower_2, tower_3])

    model = Model(inputs=input_img, outputs=output)
    return model

"""This is then used in the following model"""
def Unetish_model1(image_shape=(IMAGE_SIZE, IMAGE_SIZE, 3)):
    image = Input(shape=image_shape)

    #First layer 96X96
    conv1 = Conv2D(32, (3,3),padding='same', activation = 'relu')(image)
    conv1out = Conv2D(16, (1,1),padding = 'same', activation = 
    'relu')(conv1)
    conv1out = MaxPooling2D((2,2), strides = (2,2))(conv1out)
    aux1out = Conv2D(16, (1,1), padding = 'same', activation  = 'relu')(conv1)

    #Second layer 48x48
    #conv2 = incepm_v1(64, conv1out.shape[1:])(conv1out)
    conv2 = incepm_v1(64, K.int_shape(conv1out)[1:])(conv1out)
    conv2out = Conv2D(32, (1,1), padding = 'same', activation = 
        'relu')(conv2)
    conv2out = MaxPooling2D((2,2), strides = (2,2))(conv2out)
    aux2out = Conv2D(32, (1,1), padding = 'same', activation  = 
        'relu')(conv2)

    #".... removed for sparsity"
    model = Model(inputs =image, outputs = output)
    model.summary()
    return model

IMAGE_SIZE = 96
Unet = Unetish_model1(image_shape=(IMAGE_SIZE, IMAGE_SIZE, 3))

上面的代码还修复了Concatenatelayer 的使用。

Unetish_model1请注意,由于省略了部分代码,这段代码仍然可以成功运行。


推荐阅读