繁体   English   中英

ValueError:形状 (None, 0, 5) 和 (None, 5) 不兼容

[英]ValueError: Shapes (None, 0, 5) and (None, 5) are incompatible

我正在从kaggle解决这个问题。 我将 Tensorflow.data.Dataset 用于输入管道。 我认为我在创建 label 时遇到问题,在批处理后形状为 (0,5) 变为 (None, 0, 5)。

它引发了这个ValueError: Shapes (None, 0, 5) and (None, 5) is incompatible

但我没有得到实际的错误在哪里。

这是我的代码:


import os
import tensorflow as tf
import pandas as pd
import numpy as np


from keras.utils import to_categorical


import pathlib, datetime

from tensorflow.keras.layers import Dense,GlobalAveragePooling2D,Convolution2D,BatchNormalization
from tensorflow.keras.layers import Flatten,MaxPooling2D,Dropout

from tensorflow.keras.applications import DenseNet121, ResNet50, ResNet152V2

from tensorflow.keras.optimizers import Adam

from tensorflow.keras.callbacks import ModelCheckpoint, ReduceLROnPlateau, EarlyStopping, TensorBoard, LearningRateScheduler

from tensorflow.keras.models import Model, load_model




AUTOTUNE = tf.data.experimental.AUTOTUNE
BATCH_SIZE = 32
IMAGE_SIZE = [128, 128]
EPOCHS = 10
HEIGHT = 128
WIDTH = 128
### preaparing Data set
train = pd.read_csv("train.csv")


labels = train['label']


one_hot_label = to_categorical(labels)
columns =  ["cbb", "cbsd", "cgm", "cmd", "healthy"]
train[columns] = one_hot_label
#train.head()

data_dir = pathlib.Path("train_images")
filenames = list(data_dir.glob('*.jpg'))
print("image count: ", len(filenames))
print("first image: ", str(filenames[0]))


fnames=[]
for fname in filenames:
  fnames.append(str(fname))
  

filelist_ds = tf.data.Dataset.from_tensor_slices(fnames)

ds_size = filelist_ds.cardinality().numpy()

train_ratio = 0.9

train_data = filelist_ds.take(train_ratio*ds_size)
valid_data = filelist_ds.skip(train_ratio*ds_size)


def get_label(file_path):
  print("get_label acivated...")
  print(file_path)
  parts = tf.strings.split(file_path, '\\')
  file_name= parts[-1]
  print(file_name)
  label = train[train["image_id"]==file_name][columns]
  return tf.convert_to_tensor(label)


def process_image(image):

    #Don't use tf.image.decode_image, or the output shape will be undefined
    image = tf.image.decode_jpeg(image, channels=3)
    
    image = tf.image.random_flip_left_right(image)

    image = tf.image.random_brightness(image, max_delta=32.0 / 255.0)
    image = tf.image.random_saturation(image, lower=0.5, upper=1.5)

    #This will convert to float values in [0, 1]
    image = tf.image.convert_image_dtype(image, tf.float32)

    resized_image = tf.image.resize(image, [128, 128])
    return resized_image


def combine_images_labels(file_path: tf.Tensor):
    image = tf.io.read_file(file_path)
    image = process_image(image)
    label = get_label(file_path)
    return image, label


ds_train = train_data.map(lambda x: combine_images_labels(x))
ds_test = valid_data.map(lambda x: combine_images_labels(x))


ds_train_batched=ds_train.batch(BATCH_SIZE).cache().prefetch(tf.data.experimental.AUTOTUNE) 
ds_test_batched=ds_test.batch(BATCH_SIZE).cache().prefetch(tf.data.experimental.AUTOTUNE)



base_model=ResNet50(weights='imagenet',include_top=False, input_shape = (128,128,3)) 
#base_model.summary()

x= base_model.output


for layer in base_model.layers:
    layer.trainable=False

x=Flatten()(x)
#new_x  = model.output
x=Dense(512,activation='relu')(x)
preds=Dense(5,activation='softmax')(x)

model=Model(inputs=base_model.input,outputs=preds)
    
#model.summary()

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

checkpoint = ModelCheckpoint('model_1.h5', verbose=1, save_best_only=True, monitor='val_auc')

history = model.fit(
               ds_train_batched,
               steps_per_epoch=100,
               epochs=2,
               verbose=1,
               callbacks=[checkpoint],
               validation_data=ds_test_batched)


这是我的回溯: 在此处输入图像描述

如果您仔细观察,回溯会注意到对“categorical_crossentropy”的调用。 您的损失, tf.keras.losses.categorical_crossentropy预计会有这种输入:

y_true = [[0, 1, 0], [0, 0, 1]]
y_pred = [[0.05, 0.95, 0], [0.1, 0.8, 0.1]]
loss = tf.keras.losses.categorical_crossentropy(y_true, y_pred)
assert loss.shape == (2,)
loss.numpy() # -> array([0.0513, 2.303], dtype=float32)

您的代码尚不清楚,但最可能的罪魁祸首是 function get_label 它可能返回 (0,5) 形状的 label 张量。 在从get_label返回之前使用tf.squeeze以删除大小为 0 或 1 的维度。这可能会解决您的问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM