我正在从 kaggle 解决这个问题。 我使用 Tensorflow.data.Dataset 作为输入管道。我想我在创建标签时遇到问题,在批处理后形状为 (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)
答案 0 :(得分:0)
如果您仔细观察,回溯会注意到对“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)
从您的代码中并不清楚,但最可能的罪魁祸首是函数 get_label
。它可能会返回 (0,5) 形状的标签张量。采用
tf.squeeze
在您从 get_label
返回之前删除大小为 0 或 1 的维度。这可能会解决您的问题。