【问题标题】:How do I load my local data into my tensorflow/keras-model?如何将本地数据加载到我的 tensorflow/keras-model 中?
【发布时间】:2019-12-05 10:06:42
【问题描述】:

我是 tensorflow 和 keras 的新手,不知道如何加载我的数据以适应模型。

我尝试使用从图像路径和标签列表构建的 tf.dataset,但无济于事。我知道下面代码中的模型本身可能不太适合我的任务。我只是想尝试 tf 并学习如何建立模型并训练它。我的图片有多种格式(tiff、png、jpg)并且有不同的尺寸。这就是为什么我需要调整它们的大小并将它们转换为 numpy-arrays。我按照这个帖子试了一下:TensorFlow: training on my own image

import tensorflow as tf
import random
import numpy
import cv2
from PIL import Image
from pathlib import Path
import os
from tensorflow.keras.preprocessing.image import ImageDataGenerator

training_data_path = Path("/home/xxxx/validation_data")

validation_data_path = Path("/home/xxxx/validation_data")
test_data_paths = Path("/home/xxxx/test_data")
validation_image_paths = list(validation_data_path.glob("**/*"))
label_array = ["DIS","ANG", "FEA", "SAD", "SUR", "JOY", "NEU"]
label_to_index = dict((name, index) for index,name in      enumerate(label_array))

def getLabelDict(image_paths):

    all_image_labels = [label_to_index[Path(path).absolute().name[0:3]]
                    for path in image_paths]
    return all_image_labels

def getLabelList(image_paths):
    all_img_labels = list()
    for path in image_paths:
        all_img_labels.append(Path(path).absolute().name[0:3])
    return all_img_labels


def preProcessPath(path):
   return path.absolute().name


def get_ds(data_path):
    image_paths = list(data_path.glob("**/*"))
    img_paths = tf.constant(image_paths)

    dataset = tf.data.Dataset.from_tensor_slices((img_paths,     getLabelList(image_paths)))
    for path in image_paths:
        dataset.map(getPic(path))

    return dataset

def getPic(path):
    image = Image.open(path).convert('RGB')
    image = image.resize((256,256,3))
    array = numpy.array(image.getdata())
    array = array.reshape((256,256,3))
    return array


os.environ['CUDA_VISIBLE_DEVICES'] = '-1'


ds_inputs, ds_labels =  get_ds(test_data_paths).make_one_shot_iterator()
val_inputs, val_labels=  validation_data=get_ds(validation_data_path).make_one_shot_iterator()

model = tf.keras.Sequential([
    tf.keras.layers.Input(shape=(256,256,3)),
    tf.keras.layers.Dense(128, activation=tf.nn.relu),
    tf.keras.layers.Dense(10, activation=tf.nn.softmax)
])

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

model.fit(ds_inputs, epochs=1,  steps_per_epoch=3,validation_data=val_inputs)

编辑:删除代码中不必要的行

现在我收到一个类型错误:TypeError: 无法将类型对象转换为张量。内容:

【问题讨论】:

  • 你能修复你的代码缩进吗? for path in training_data_path.glob("**/*"): 下面的行应该缩进。此外,您可能会考虑将所有函数定义放在主代码之前,以使其更具可读性。

标签: python tensorflow keras neural-network


【解决方案1】:

代码中的问题:

  1. PIL 调整大小:将大小作为 2 元组(宽度,高度)。您传入了 3 个值。
  2. get_ds:标签应编码为数字而不是字符串
  3. 模型架构:由于您使用 3 通道图像作为神经网络的输入,因此您必须先将它们展平。

工作代码 ---(在 cmets 中解释)

label_array = ["DIS","ANG", "FEA", "SAD", "SUR", "JOY", "NEU"]
label_to_index = dict((name, index) for index,name in enumerate(label_array))
  
# Takes as input path to image file and returns 
# resized 3 channel RGB image of as numpy array of size (256, 256, 3)
def getPic(img_path):
    return np.array(Image.open(img_path).convert('RGB').resize((256,256),Image.ANTIALIAS))

# returns the Label of the image based on its first 3 characters
def get_label(img_path):
    return Path(img_path).absolute().name[0:3]

# Return the images and corresponding labels as numpy arrays
def get_ds(data_path):
    img_paths = list()
    # Recursively find all the image files from the path data_path
    for img_path in glob.glob(data_path+"/**/*"):
        img_paths.append(img_path)
    images = np.zeros((len(img_paths),256,256,3))
    labels = np.zeros(len(img_paths))
      
    # Read and resize the images
    # Get the encoded labels
    for i, img_path in enumerate(img_paths):
        images[i] = getPic(img_path)
        labels[i] = label_to_index[get_label(img_path)]
        
    return images,labels

# Model Architecture
model = tf.keras.Sequential([
    tf.keras.layers.Input(shape=(256,256,3)),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(128, activation=tf.nn.relu),
    tf.keras.layers.Dense(10, activation=tf.nn.softmax)
])

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

# Load the train and validation data
train_X, train_y = get_ds("./images/")
val_X, val_y = get_ds("./v_images/")

# Finally train it
model.fit(train_X,train_y, validation_data=(val_X,val_y))

# Predictions 
model.predict(val_X)

【讨论】:

  • 我已经尝试过你的实现。它可以工作和训练......并以 0.085 的准确度进行分类......但那是另一回事了。谢谢
  • @mrFunkus 是的,因为上面代码中的模型非常糟糕。理想情况下,您应该在这里使用 CNN。
【解决方案2】:

在此处查看“flow_from_directory” https://keras.io/preprocessing/image/

根据 keras 文档,这将获取目录的路径并生成成批的增强数据。 每个子目录目录树内的任何 PNG、JPG、BMP、PPM 或 TIF 图像都将包含在生成器中。

【讨论】:

  • 我已经尝试过了,它似乎可以加载数据,但现在我收到以下错误:tensorflow.python.framework.errors_impl.InvalidArgumentError:无法挤压昏暗[1],需要一个维度1,得到 7 [[{{node metrics/acc/Squeeze}}]]
  • 我现在无法对此进行测试,但请检查此答案。我希望它可以帮助stackoverflow.com/a/55419238/7645361
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-12-17
  • 1970-01-01
  • 2020-07-13
  • 2012-10-12
  • 1970-01-01
  • 1970-01-01
  • 2021-12-08
相关资源
最近更新 更多