TensorFlow:在我自己的图像上进行训练

Posted

技术标签:

【中文标题】TensorFlow:在我自己的图像上进行训练【英文标题】:TensorFlow: training on my own image 【发布时间】:2016-09-17 07:57:46 【问题描述】:

我是 TensorFlow 新手。我正在寻找图像识别方面的帮助,我可以在其中训练我自己的图像数据集。

有没有训练新数据集的例子?

【问题讨论】:

我已经阅读了这个googleresearch.blogspot.hk/2016/03/… 但是,我不知道我应该在哪里更改代码。 新链接位置ai.googleblog.com/2016/03/… 【参考方案1】:

如果你对如何在TensorFlow中输入自己的数据感兴趣,可以看看this tutorial。 我还在斯坦福 here 编写了一份关于 CS230 最佳实践的指南。


新答案(带有tf.data)和标签

通过在r1.4 中引入tf.data,我们可以创建一批没有占位符和没有队列的图像。步骤如下:

    创建一个包含图像文件名和相应标签列表的列表 创建一个tf.data.Dataset 读取这些文件名和标签 预处理数据 从 tf.data.Dataset 创建一个迭代器,它将产生下一批

代码是:

# step 1
filenames = tf.constant(['im_01.jpg', 'im_02.jpg', 'im_03.jpg', 'im_04.jpg'])
labels = tf.constant([0, 1, 0, 1])

# step 2: create a dataset returning slices of `filenames`
dataset = tf.data.Dataset.from_tensor_slices((filenames, labels))

# step 3: parse every image in the dataset using `map`
def _parse_function(filename, label):
    image_string = tf.read_file(filename)
    image_decoded = tf.image.decode_jpeg(image_string, channels=3)
    image = tf.cast(image_decoded, tf.float32)
    return image, label

dataset = dataset.map(_parse_function)
dataset = dataset.batch(2)

# step 4: create iterator and final input tensor
iterator = dataset.make_one_shot_iterator()
images, labels = iterator.get_next()

现在我们可以直接运行sess.run([images, labels]),而无需通过占位符提供任何数据。


旧答案(使用 TensorFlow 队列)

总结起来有多个步骤:

    创建文件名列表(例如:图像的路径) 创建 TensorFlow 文件名队列 读取和解码每个图像,将它们调整为固定大小(批处理所必需的) 输出一批这些图像

最简单的代码是:

# step 1
filenames = ['im_01.jpg', 'im_02.jpg', 'im_03.jpg', 'im_04.jpg']

# step 2
filename_queue = tf.train.string_input_producer(filenames)

# step 3: read, decode and resize images
reader = tf.WholeFileReader()
filename, content = reader.read(filename_queue)
image = tf.image.decode_jpeg(content, channels=3)
image = tf.cast(image, tf.float32)
resized_image = tf.image.resize_images(image, [224, 224])

# step 4: Batching
image_batch = tf.train.batch([resized_image], batch_size=8)

【讨论】:

你说得对,tf.train.batchtf.train.shuffle_batch 的第一个参数应该是一个列表[image] 而不仅仅是image。我在代码中修复了它。 再一次你是对的,我在代码中修复了它。您必须将所有图像的大小调整为相同的形状才能制作一批。 如果您有训练图像的标签,您还应该将它们作为输入并将它们与图像一起批处理:image_batch, label_batch = tf.train.batch([resized_image, label], batch_size=8)。然后,您必须构建一个以图像为输入、标签为输出的模型,请参阅this tutorial 了解更多信息。 @datdinhquoc:如果您只有两个文件和标签,批量大小为 2,您只能进行一次迭代,然后您将收到 OutOfRange 错误。 @AadnanFarooqA:在这种情况下,您需要更改 _parse_function 才能读取 .mat 文件【参考方案2】:

使用 Tensorflow Hub 的 2.0 兼容答案Tensorflow Hub 是由Tensorflow 提供的供应/产品,其中包括 Google 开发的文本和图像模型数据集。

saves Thousands of Hours of Training Time and Computational Effort,因为它重用了现有的预训练模型。

如果我们有一个图像数据集,我们可以从 TF Hub 获取现有的预训练模型,并将其应用于我们的数据集。

使用预训练模型 MobileNet 重新训练我们的图像数据集的代码如下所示:

import itertools
import os

import matplotlib.pylab as plt
import numpy as np

import tensorflow as tf
import tensorflow_hub as hub

module_selection = ("mobilenet_v2_100_224", 224) #@param ["(\"mobilenet_v2_100_224\", 224)", "(\"inception_v3\", 299)"] type:"raw", allow-input: true
handle_base, pixels = module_selection
MODULE_HANDLE ="https://tfhub.dev/google/imagenet//feature_vector/4".format(handle_base)
IMAGE_SIZE = (pixels, pixels)
print("Using  with input size ".format(MODULE_HANDLE, IMAGE_SIZE))

BATCH_SIZE = 32 #@param type:"integer"

#Here we need to Pass our Dataset

data_dir = tf.keras.utils.get_file(
    'flower_photos',
    'https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz',
    untar=True)

model = tf.keras.Sequential([
    hub.KerasLayer(MODULE_HANDLE, trainable=do_fine_tuning),
    tf.keras.layers.Dropout(rate=0.2),
    tf.keras.layers.Dense(train_generator.num_classes, activation='softmax',
                          kernel_regularizer=tf.keras.regularizers.l2(0.0001))
])
model.build((None,)+IMAGE_SIZE+(3,))
model.summary()

图像再训练教程的完整代码可在此Github Link 中找到。

有关 Tensorflow Hub 的更多信息,请访问TF Blog。

与图像相关的预训练模块可以在TF Hub Link找到。

所有与图像、文本、视频等相关的预训练模块都可以在TF HUB Modules Link 中找到。

最后,这是Basic Page for Tensorflow Hub。

【讨论】:

【参考方案3】:

基于 @olivier-moindrot 的回答,但适用于 Tensorflow 2.0+:

# step 1
filenames = tf.constant(['im_01.jpg', 'im_02.jpg', 'im_03.jpg', 'im_04.jpg'])
labels = tf.constant([0, 1, 0, 1])

# step 2: create a dataset returning slices of `filenames`
dataset = tf.data.Dataset.from_tensor_slices((filenames, labels))

def im_file_to_tensor(file, label):
    def _im_file_to_tensor(file, label):
        path = f"../foo/bar/file.numpy().decode()"
        im = tf.image.decode_jpeg(tf.io.read_file(path), channels=3)
        im = tf.cast(image_decoded, tf.float32) / 255.0
        return im, label
    return tf.py_function(_im_file_to_tensor, 
                          inp=(file, label), 
                          Tout=(tf.float32, tf.uint8))

dataset = dataset.map(im_file_to_tensor)

如果您遇到类似的问题:

ValueError: 无法获取具有未知等级的形状的长度

将 tf.data.Dataset 张量传递给 model.fit 时,请查看 https://github.com/tensorflow/tensorflow/issues/24520。对上面代码 sn-p 的修复是:

def im_file_to_tensor(file, label):
    def _im_file_to_tensor(file, label):
        path = f"../foo/bar/file.numpy().decode()"
        im = tf.image.decode_jpeg(tf.io.read_file(path), channels=3)
        im = tf.cast(image_decoded, tf.float32) / 255.0
        return im, label

    file, label = tf.py_function(_im_file_to_tensor, 
                                 inp=(file, label), 
                                 Tout=(tf.float32, tf.uint8))
    file.set_shape([192, 192, 3])
    label.set_shape([])
    return (file, label)

【讨论】:

【参考方案4】:

如果您的数据集包含子文件夹,您可以使用 ImageDataGenerator 它有 flow_from_directory 它有助于从目录加载数据,

train_batches = ImageDataGenerator().flow_from_directory(
    directory=train_path, target_size=(img_height,img_weight), batch_size=32 ,color_mode="grayscale")

文件夹层次结构可以如下,

train 
    -- cat
    -- dog
    -- moneky

【讨论】:

以上是关于TensorFlow:在我自己的图像上进行训练的主要内容,如果未能解决你的问题,请参考以下文章

用于车牌识别的预训练 LeNet 模型

将训练有素的 Tensorflow 模型保存到另一台机器上进行推理 [重复]

Tensorflow 训练模型在云端机器上工作,但在我的本地电脑上使用时出错

理解和跟踪对象检测中的指标

在树莓派 (tensorflow) 上进行对象检测的项目

如何将 Landsat 图像裁剪成更小的块进行训练,然后在原始图像上进行预测