如何用 tf.data.Dataset 喂养 CNN
How to feed CNN with tf.data.Dataset
我是张量流的新手。我正在尝试 运行 用于猫狗二元分类的卷积神经网络。
数据结构如下:在名为 data 的目录中,有两个子目录:test 和 火车。在每个子目录中有两个(子)子目录,分别称为 cat 和 dog.
我想做的是使用 tf.data.Dataset 导入图像并使用 运行 CNN 对其进行分类。
按照此参考文献 (https://towardsdatascience.com/tf-data-creating-data-input-pipelines-2913461078e2) 中建议的方法,我可以将数据导入为 Dataset 对象并将其在图像和标签之间分开(我不确定它是否正确,我只是按照方法上面link中提出的。顺便问一下,有什么方法可以检查分离和标记过程是否正确执行?):
from glob import glob
import tensorflow as tf
IMAGE_PATH_LIST = glob('/Users/josea/Desktop/Deep_Learning/cats_dogs/training/*/*.jpg')
DATA = tf.data.Dataset.list_files(IMAGE_PATH_LIST)
def load_images(path):
image = tf.io.read_file(path)
image = tf.io.decode_image(image)
label = tf.strings.split(path, os.path.sep)[-2]
return image, label
DATA= DATA.map(load_images)
我有几个问题:首先,当我尝试 运行 CNN(使用下面的脚本)时,出现错误消息“层 sequential_4 的输入 0 与图层:预期 ndim=4,发现 ndim=3。收到的完整形状:[None, 265, 3]".
有人猜我做错了什么吗?此外,我想检查数据是否被正确导入。有什么好的评估方法吗?
我的 CNN 尝试如下所示:
model = Sequential()
model.add(Conv2D(64, (3,3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size = (2,2)))
model.add(Conv2D(64, (3,3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size = (2,2)))
model.add(Flatten())
model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dense(1))
model.add(Activation('sigmoid'))
model.compile(loss = 'binary_crossentropy', optimizer = 'adam', metrics = ['accuracy'])
model.fit(DATA)
提前致谢!
您需要对数据进行批处理:
DATA= DATA.map(load_images).batch(16)
您可能会遇到错误,因为您的目标似乎是一个字符串。您可以使用这样的函数将路径转换为标签:
def load_images(path):
image = tf.io.read_file(path)
image = tf.io.decode_jpeg(image)
image = tf.image.convert_image_dtype(image, tf.float32)
image = tf.image.resize(image, (224, 224))
parts = tf.strings.split(path, os.path.sep)
bool_values = tf.equal(parts[-2], 'cats')
indices = tf.cast(bool_values, tf.int32)
return image, indices
完整示例:
import tensorflow as tf
import os
os.chdir('pictures')
files = tf.data.Dataset.list_files('*jpg')
def load_images(path):
image = tf.io.read_file(path)
image = tf.io.decode_jpeg(image)
image = tf.image.convert_image_dtype(image, tf.float32)
image = tf.image.resize(image, (224, 224))
parts = tf.strings.split(path, os.path.sep)
bool_values = tf.equal(parts[-2], 'cats')
indices = tf.cast(bool_values, tf.int32)
return image, indices
ds = files.map(load_images).batch(1)
next(iter(ds))
(<tf.Tensor: shape=(1, 224, 224, 3), dtype=float32, numpy=
array([[[[0.75831336, 0.8016107 , 0.72746104],
[0.8311225 , 0.87016815, 0.79833937],
[0.79161674, 0.8425971 , 0.77475995],
...,
[0.08725347, 0.10316982, 0.11867575],
[0.09943968, 0.1140053 , 0.1350136 ],
[0.1064626 , 0.12102822, 0.14707875]]]], dtype=float32)>,
<tf.Tensor: shape=(1,), dtype=int32, numpy=array([0])>)
我是张量流的新手。我正在尝试 运行 用于猫狗二元分类的卷积神经网络。
数据结构如下:在名为 data 的目录中,有两个子目录:test 和 火车。在每个子目录中有两个(子)子目录,分别称为 cat 和 dog.
我想做的是使用 tf.data.Dataset 导入图像并使用 运行 CNN 对其进行分类。
按照此参考文献 (https://towardsdatascience.com/tf-data-creating-data-input-pipelines-2913461078e2) 中建议的方法,我可以将数据导入为 Dataset 对象并将其在图像和标签之间分开(我不确定它是否正确,我只是按照方法上面link中提出的。顺便问一下,有什么方法可以检查分离和标记过程是否正确执行?):
from glob import glob
import tensorflow as tf
IMAGE_PATH_LIST = glob('/Users/josea/Desktop/Deep_Learning/cats_dogs/training/*/*.jpg')
DATA = tf.data.Dataset.list_files(IMAGE_PATH_LIST)
def load_images(path):
image = tf.io.read_file(path)
image = tf.io.decode_image(image)
label = tf.strings.split(path, os.path.sep)[-2]
return image, label
DATA= DATA.map(load_images)
我有几个问题:首先,当我尝试 运行 CNN(使用下面的脚本)时,出现错误消息“层 sequential_4 的输入 0 与图层:预期 ndim=4,发现 ndim=3。收到的完整形状:[None, 265, 3]".
有人猜我做错了什么吗?此外,我想检查数据是否被正确导入。有什么好的评估方法吗?
我的 CNN 尝试如下所示:
model = Sequential()
model.add(Conv2D(64, (3,3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size = (2,2)))
model.add(Conv2D(64, (3,3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size = (2,2)))
model.add(Flatten())
model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dense(1))
model.add(Activation('sigmoid'))
model.compile(loss = 'binary_crossentropy', optimizer = 'adam', metrics = ['accuracy'])
model.fit(DATA)
提前致谢!
您需要对数据进行批处理:
DATA= DATA.map(load_images).batch(16)
您可能会遇到错误,因为您的目标似乎是一个字符串。您可以使用这样的函数将路径转换为标签:
def load_images(path):
image = tf.io.read_file(path)
image = tf.io.decode_jpeg(image)
image = tf.image.convert_image_dtype(image, tf.float32)
image = tf.image.resize(image, (224, 224))
parts = tf.strings.split(path, os.path.sep)
bool_values = tf.equal(parts[-2], 'cats')
indices = tf.cast(bool_values, tf.int32)
return image, indices
完整示例:
import tensorflow as tf
import os
os.chdir('pictures')
files = tf.data.Dataset.list_files('*jpg')
def load_images(path):
image = tf.io.read_file(path)
image = tf.io.decode_jpeg(image)
image = tf.image.convert_image_dtype(image, tf.float32)
image = tf.image.resize(image, (224, 224))
parts = tf.strings.split(path, os.path.sep)
bool_values = tf.equal(parts[-2], 'cats')
indices = tf.cast(bool_values, tf.int32)
return image, indices
ds = files.map(load_images).batch(1)
next(iter(ds))
(<tf.Tensor: shape=(1, 224, 224, 3), dtype=float32, numpy=
array([[[[0.75831336, 0.8016107 , 0.72746104],
[0.8311225 , 0.87016815, 0.79833937],
[0.79161674, 0.8425971 , 0.77475995],
...,
[0.08725347, 0.10316982, 0.11867575],
[0.09943968, 0.1140053 , 0.1350136 ],
[0.1064626 , 0.12102822, 0.14707875]]]], dtype=float32)>,
<tf.Tensor: shape=(1,), dtype=int32, numpy=array([0])>)