我正在尝试使用keras的flow_from_dataframe进行语义分割(输入是尺寸(高度,宽度,3)的图像,标签也是尺寸(高度,宽度)的图像,但无法获取工作。
按照推荐的here,我(卸载了现有的并安装了)最新的keras预处理库,
pip install git+https://github.com/keras-team/keras-preprocessing.git
以下迷你示例出现以下错误
ValueError:检查目标时出错:预期conv1具有4个维,但数组的形状为(1,1)
在Pycharm的Windows 7的anaconda虚拟环境中使用以下版本
我认为错误在于我使用flow_from_dataframe,因为我能够在此blog之后编写自己的keras数据生成器。
任何建议,如何正确设置flow_from_dataframe?
一个完整的示例,它还会生成随机训练数据。
import numpy as np
import pandas as pd
import os
import scipy.misc
import keras
from keras.models import Model
from keras.layers import Input, Conv2D
from keras_preprocessing.image import ImageDataGenerator
def get_file_list(root_path):
"""
# Returns:
file_list: _list_, list of full paths to all files found
"""
file_list = []
for root, dirs, files in os.walk(root_path):
for name in files:
file_list.append(os.path.join(root, name))
return file_list
def gen_rand_img_labels(n_rand_imgs, path_img, path_label):
for i in range(n_rand_imgs):
img_rand = np.random.randint(0, 256, size=img_dim)
scipy.misc.toimage(img_rand, cmin=0, cmax=255).save(os.path.join(path_img, 'img{}.png'.format(i)))
label_rand = np.random.randint(0, n_classes, size=(img_dim[0], img_dim[1]))
print('label_rand.shape: ', label_rand.shape)
scipy.misc.toimage(label_rand, cmin=0, cmax=255).save(os.path.join(path_label, 'img{}.png'.format(i)))
if __name__ == "__main__":
img_dim = (100, 200, 3) # height, width, channels
batch_size = 1
nr_epochs = 1
n_classes = 5
n_rand_imgs = 10
savepath_img = r'/path/to/img'
savepath_label = r'/path/to/label'
# --- generate random images and random labels and save them to disk
gen_rand_img_labels(n_rand_imgs, savepath_img, savepath_label)
# --- build Data Generator
train_df = pd.DataFrame(columns=['path', 'label'])
list_img_names = get_file_list(savepath_img)
for fname in list_img_names:
fname_pure = os.path.split(fname)[1]
# read in png label file as numpy array
y = scipy.misc.imread(os.path.join(savepath_label, fname_pure))
y = keras.utils.to_categorical(y, n_classes)
print('shape y: {}'.format(y.shape))
train_df.loc[len(train_df)] = [fname, y]
datagen = ImageDataGenerator(rescale=1/255.0, validation_split=0.25)
train_generator = datagen.flow_from_dataframe(
dataframe=train_df,
x_col="path",
y_col="label",
subset="training",
batch_size=batch_size,
class_mode="raw",
target_size=(img_dim[0], img_dim[1]))
valid_generator = datagen.flow_from_dataframe(
dataframe=train_df,
x_col="path",
y_col="label",
subset="validation",
batch_size=batch_size,
class_mode="raw",
target_size=(img_dim[0], img_dim[1]))
# --- create the model and train it
input_ = Input(shape=img_dim)
x = Conv2D(n_classes, (3, 3), activation='relu', padding='same', name='conv1')(input_)
model = Model(inputs=input_, outputs=[x])
model.summary()
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=["accuracy"])
# Train model
STEP_SIZE_TRAIN = train_generator.n // train_generator.batch_size
STEP_SIZE_VALID = valid_generator.n // valid_generator.batch_size
model.fit_generator(generator=train_generator,
steps_per_epoch=STEP_SIZE_TRAIN,
validation_data=valid_generator,
validation_steps=STEP_SIZE_VALID,
epochs=nr_epochs)
答案 0 :(得分:0)
我已经更新了用于TensorFlow 2.0的代码
注意:使用scipy 1.2.0,因为更高版本不推荐使用scipy.misc.toimage
。
import tensorflow as tf
import numpy as np
import pandas as pd
import os
import scipy.misc
def get_file_list(root_path):
"""
# Returns:
file_list: _list_, list of full paths to all files found
"""
file_list = []
for root, dirs, files in os.walk(root_path):
for name in files:
file_list.append(os.path.join(root, name))
return file_list
def gen_rand_img_labels(n_rand_imgs, path_img, path_label):
for i in range(n_rand_imgs):
img_rand = np.random.randint(0, 256, size=img_dim)
PIL.Image.fromarray(img_rand, cmin=0, cmax=255).save(os.path.join(path_img, 'img{}.png'.format(i)))
label_rand = np.random.randint(0, n_classes, size=(img_dim[0], img_dim[1]))
print('label_rand.shape: ', label_rand.shape)
PIL.Image.fromarray(label_rand, cmin=0, cmax=255).save(os.path.join(path_label, 'img{}.png'.format(i)))
if __name__ == "__main__":
img_dim = (100, 200, 3) # height, width, channels
batch_size = 1
nr_epochs = 1
n_classes = 5
n_rand_imgs = 10
savepath_img = r''
savepath_label = r''
# --- generate random images and random labels and save them to disk
gen_rand_img_labels(n_rand_imgs, savepath_img, savepath_label)
# --- build Data Generator
train_df = pd.DataFrame(columns=['path', 'label'])
list_img_names = get_file_list(savepath_img)
for fname in list_img_names:
fname_pure = os.path.split(fname)[1]
# read in png label file as numpy array
y = scipy.misc.imread(os.path.join(savepath_label, fname_pure))
y = tf.keras.utils.to_categorical(y, n_classes)
print('shape y: {}'.format(y.shape))
train_df.loc[len(train_df)] = [fname, y]
datagen = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1/255.0, validation_split=0.25)
train_generator = datagen.flow_from_dataframe(
dataframe=train_df,
x_col="path",
y_col="label",
subset="training",
batch_size=batch_size,
class_mode="raw",
target_size=(img_dim[0], img_dim[1]))
valid_generator = datagen.flow_from_dataframe(
dataframe=train_df,
x_col="path",
y_col="label",
subset="validation",
batch_size=batch_size,
class_mode="raw",
target_size=(img_dim[0], img_dim[1]))
# --- create the model and train it
input_ = tf.keras.Input(shape=img_dim)
x = tf.keras.layers.Conv2D(n_classes, (3, 3), activation='relu', padding='same', name='conv1')(input_)
model = tf.keras.Model(inputs=input_, outputs=[x])
model.summary()
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=["accuracy"])
# Train model
STEP_SIZE_TRAIN = train_generator.n // train_generator.batch_size
STEP_SIZE_VALID = valid_generator.n // valid_generator.batch_size
model.fit_generator(generator=train_generator,
steps_per_epoch=STEP_SIZE_TRAIN,
validation_data=valid_generator,
validation_steps=STEP_SIZE_VALID,
epochs=nr_epochs)