tensorflow2.3以上keras model.fit()出现维度错误问题

  • Post author:
  • Post category:其他


将数据喂进模型的时候,发现fit模型的时候,总是出现维度不对的错误,当打印喂进模型数据的明细时,发现如某一条记录,ty为array([0.96276813, 0.46342801]) ,shape=[2,1]和ty这个特征为2维不符,

({'ty': <tf.Tensor: shape=(2,), dtype=float64, numpy=array([0.96276813, 0.46342801])>, 'a_label': <tf.Tensor: shape=(1,), dtype=float32, numpy=array([0.], dtype=float32)>, 'b_label': <tf.Tensor: shape=(1,), dtype=float32, numpy=array([0.], dtype=float32)>}, {'a': <tf.Tensor: shape=(1,), dtype=float32, numpy=array([0.], dtype=float32)>, 'b': <tf.Tensor: shape=(1,), dtype=float32, numpy=array([0.], dtype=float32)>, 'loss': <tf.Tensor: shape=(1,), dtype=float32, numpy=array([0.], dtype=float32)>})

因而会报Input 0 of layer dense_132 is incompatible with the layer: expected axis -1 of input shape to have value 2 but received input with shape [2, 1]的错误


解决方案如下

  • 1 加batch解决

构造一个简单的模型

def gen_model():
    input1 = tf.keras.layers.Input(shape=(2,), dtype=tf.float32, name='ty')
    a_label = tf.keras.layers.Input(shape=(1,), dtype=tf.float32, name='a_label')
    b_label = tf.keras.layers.Input(shape=(1,), dtype=tf.float32, name='b_label')
    input_layers= Dense(units=16,activation='relu')(input1)
    
    a_preds = tf.keras.layers.Dense(units=1, activation='sigmoid')(input_layers)
    c_preds = tf.keras.layers.Dense(units=1, activation='sigmoid')(input_layers)


    # output layer
    a_preds = tf.keras.layers.Lambda(lambda x: x, name='a')(a_preds)
    b_preds = tf.keras.layers.Multiply(name='b')([a_preds, c_preds])

    inputs.append(a_label)
    inputs.append(b_label)


    loss_inputs = [a_label, a_preds, b_label, b_preds]

    def sum_loss(inputs):
        a_true, a_pred, b_true, b_pred = inputs
        a_loss = tf.keras.losses.binary_crossentropy(y_true=a_true, y_pred=a_pred)
        b_loss = tf.keras.losses.binary_crossentropy(y_true=b_true, y_pred=b_pred)
        loss = a_loss + b_loss
        return loss

    # loss layer
    loss_layer = tf.keras.layers.Lambda(lambda x: sum_loss(x), name='loss')(loss_inputs)
    outputs = [a_preds, b_preds, loss_layer]
    loss = [lambda y_true, y_pred: tf.keras.losses.binary_crossentropy(y_true, y_pred),
            lambda y_true, y_pred: tf.keras.losses.binary_crossentropy(y_true, y_pred),
            lambda y_true, y_pred: tf.math.reduce_mean(y_pred)]

    metrics = {'a': tf.keras.metrics.AUC(),
               'b': tf.keras.metrics.AUC()}

    model = tf.keras.Model(inputs=[input1,a_label,b_label],
                           outputs=outputs,
                           name="model")
    initial_learning_rate = 0.15
    lr_schedule = tf.keras.optimizers.schedules.ExponentialDecay(
        initial_learning_rate,
        decay_steps=100000,
        decay_rate=0.8,
        staircase=True)

    model.compile(optimizer=tf.keras.optimizers.Adagrad(learning_rate=lr_schedule),
                  loss=loss,
                  loss_weights=[0, 0, 1], metrics=metrics)

    return  model


假设输入数据为feature

import numpy as np
from keras.layers import Input, Dense
from keras.models import Model
import tensorflow as tf
 
# 生成训练集
dataset_size = 128*3
rdm = np.random.RandomState(1)
X = rdm.rand(dataset_size,2)
#X= np.random.random((dataset_size,2))
Y1 = [[float(x1+x2<1)] for (x1,x2) in X]
Y2 = [[float(x1+x2*x2<0.5)] for (x1,x2) in X]
 
X_train = X[:-2]
Y_train1 = Y1[:-2]
Y_train2 = Y2[:-2]

feature_dict={'ty':X_train,'a_label':Y_train1,'b_label':Y_train2}
label_dict={'a':Y_train1,'b':Y_train2,'loss':Y_train1}
 
X_test = X[-2:dataset_size]
Y_test1 = Y1[-2:dataset_size]
Y_test2 = Y2[-2:dataset_size]


feature = tf.data.Dataset.from_tensor_slices((feature_dict,label_dict))

打印feature,如下

<TensorSliceDataset shapes: ({ty: (2,), a_label: (1,), b_label: (1,)}, {a: (1,), b: (1,), loss: (1,)}), types: ({ty: tf.float64, a_label: tf.float32, b_label: tf.float32}, {a: tf.float32, b: tf.float32, loss: tf.float32})>

对模型进行训练

model=gen_model()
model.fit(feature,epochs=10)

会出现如下错误

ValueError: Input 0 of layer dense_117 is incompatible with the layer: expected axis -1 of input shape to have value 2 but received input with shape [1, 1]

但是对feature进行batch处理

feature=feature.batch(32)

然后训练模型

model=gen_model()
model.fit(feature,epochs=10)

发现能正常训练了

对feature 进行batch之前和batch之后的结构表示如下

# 未加batch
<TensorSliceDataset shapes: ({ty: (2,), a_label: (1,), b_label: (1,)}, {a: (1,), b: (1,), loss: (1,)}), types: ({ty: tf.float64, a_label: tf.float32, b_label: tf.float32}, {a: tf.float32, b: tf.float32, loss: tf.float32})>
# 对feature进行batch(32)的处理,得到模型需要的结构
<BatchDataset shapes: ({ty: (None, 2), a_label: (None, 1), b_label: (None, 1)}, {a: (None, 1), b: (None, 1), loss: (None, 1)}), types: ({ty: tf.float64, a_label: tf.float32, b_label: tf.float32}, {a: tf.float32, b: tf.float32, loss: tf.float32})>
  • 2 对tensorflow降级处理

    降级未2.1及以下的版本



版权声明:本文为u012513618原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。