0

我是 tensorflow 的新手,正在尝试创建一个用于二进制分类的卷积神经网络,可以区分正常人脸和中风人脸之间的差异。

我的数据集的图像包含在一个名为CNNImages的目录中,并包含两个子目录:RegularFacesStrokes。在每个子目录中都是我试图输入神经网络的 PNG 图像。

按照本参考资料中建议的方法:https ://towardsdatascience.com/build-your-own-convolution-neural-network-in-5-mins-4217c2cf964f ,我已经成功使用 Spyder 创建了神经网络本身,它与 mnist.load_data() 一起运行时工作。

但是,我无法使用 tf.data.Dataset 将自己的图像上传到神经网络中。当我尝试在我创建的图像数据库上训练我的神经网络时,它返回一个 ValueError 并指出“要解包的值太多(预期为 2)”。我相信我要么错误地调用了我的数据库,要么在创建数据库时搞砸了。

import tensorflow as tf
import os
import keras
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
import numpy as np

os.chdir("/Users/Colin/CNNImages")

files = tf.data.Dataset.list_files("/Users/Colin/CNNImages/*/*.png")

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, (128, 128))

    parts = tf.strings.split(path, os.path.sep)
    bool_values = tf.equal(parts[-2], 'strokes')
    indices = tf.cast(bool_values, tf.int32)
    return image, indices

ds = files.map(load_images).batch(1)

next(iter(ds))

"""
Above: Image Formatter
Below: CNN
"""


batch_size = 128
num_classes = 2
epochs = 12

# input image dimensions
img_rows, img_cols = 128, 128

# the data, split between train and test sets
(x_train, y_train), (x_test, y_test) = ds

x_train = x_train.reshape(869,128,128,3)
x_test = x_test.reshape(217,128,128,3)

print('x_train shape:', x_train.shape)
print(x_train.shape[0], 'train samples')
print(x_test.shape[0], 'test samples')

# convert class vectors to binary class matrices
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)

model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3),
                 activation='relu',
                 input_shape=(28,28,1)))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes, activation='softmax'))

model.compile(loss=keras.losses.categorical_crossentropy,
              optimizer=keras.optimizers.Adadelta(),
              metrics=['accuracy'])

model.fit(x_train, y_train,
          batch_size=batch_size,
          epochs=epochs,
          verbose=1,
          validation_data=(x_test, y_test))
score = model.evaluate(x_test, y_test, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])

当我调用 ds for(x_train, y_train), (x_test, y_test) = ds时,我收到 ValueError,它指出“要解包的值太多(预期为 2)”。我把那条线弄乱了吗?还是我设计的 tf 数据集不正确?

4

1 回答 1

0

你的每个元素tf.data.Dataset都是一个元组(img,label)。如果要创建验证拆分,则应使用takeandskip来创建它。您也不能按照Dataset稍后在脚本中的操作方式重塑和应用函数。


要在数据集上创建训练/验证拆分,请使用skipand take

# number of element in the validation dataset
n_elem_validation_ds = 267 
val_ds = ds.take(n_elem_validation_ds)
train_ds = ds.skip(n_elem_validation_ds)

要将函数应用于您的数据集,请使用map

# convert class vectors to binary class matrices
helper_categorical = lambda x: keras.utils.to_categorical(x, num_classes)
ds = ds.map(lambda img, label: (img, helper_categorical(label)))

注意:您可以跳过该keras.utils.to_categorical(函数并将sparse_categorical_crossentropy其用作损失函数。


要在数据集上拟合您的模型,只需将 传递tf.data.Dataset给 fit 函数:

model.fit(train_ds, validation_data=val_ds)

更进一步,您应该阅读以下指南:tf.data:构建 TensorFlow 输入管道

于 2021-02-17T16:15:36.507 回答