训练深度学习模型时出错
Error while training a deep learning model
所以我设计了一个 CNN 并使用以下参数进行编译,
training_file_loc = "8-SignLanguageMNIST/sign_mnist_train.csv"
testing_file_loc = "8-SignLanguageMNIST/sign_mnist_test.csv"
def getData(filename):
images = []
labels = []
with open(filename) as csv_file:
file = csv.reader(csv_file, delimiter = ",")
next(file, None)
for row in file:
label = row[0]
data = row[1:]
img = np.array(data).reshape(28,28)
images.append(img)
labels.append(label)
images = np.array(images).astype("float64")
labels = np.array(labels).astype("float64")
return images, labels
training_images, training_labels = getData(training_file_loc)
testing_images, testing_labels = getData(testing_file_loc)
print(training_images.shape, training_labels.shape)
print(testing_images.shape, testing_labels.shape)
training_images = np.expand_dims(training_images, axis = 3)
testing_images = np.expand_dims(testing_images, axis = 3)
training_datagen = ImageDataGenerator(
rescale = 1/255,
rotation_range = 45,
width_shift_range = 0.2,
height_shift_range = 0.2,
shear_range = 0.2,
zoom_range = 0.2,
horizontal_flip = True,
fill_mode = "nearest"
)
training_generator = training_datagen.flow(
training_images,
training_labels,
batch_size = 64,
)
validation_datagen = ImageDataGenerator(
rescale = 1/255,
rotation_range = 45,
width_shift_range = 0.2,
height_shift_range = 0.2,
shear_range = 0.2,
zoom_range = 0.2,
horizontal_flip = True,
fill_mode = "nearest"
)
validation_generator = training_datagen.flow(
testing_images,
testing_labels,
batch_size = 64,
)
model = tf.keras.Sequential([
keras.layers.Conv2D(16, (3, 3), input_shape = (28, 28, 1), activation = "relu"),
keras.layers.MaxPooling2D(2, 2),
keras.layers.Conv2D(32, (3, 3), activation = "relu"),
keras.layers.MaxPooling2D(2, 2),
keras.layers.Flatten(),
keras.layers.Dense(256, activation = "relu"),
keras.layers.Dropout(0.25),
keras.layers.Dense(512, activation = "relu"),
keras.layers.Dropout(0.25),
keras.layers.Dense(26, activation = "softmax")
])
model.compile(
loss = "categorical_crossentropy",
optimizer = RMSprop(lr = 0.001),
metrics = ["accuracy"]
)
但是,当我 运行 model.fit() 时,出现以下错误,
ValueError: Shapes (None, 1) and (None, 24) are incompatible
将损失函数更改为sparse_categorical_crossentropy
后,程序运行正常。
我不明白为什么会这样。
谁能解释一下这个以及这些损失函数之间的区别?
问题是,categorical_crossentropy
需要单热编码标签,这意味着,对于每个样本,它需要一个长度为 num_classes
的张量,其中设置了第 label
个元素为 1,其他一切为 0。
另一方面,sparse_categorical_crossentropy
直接使用整数标签(因为这里的用例是大量的类,所以one-hot-encoded标签会浪费内存很多零)。我相信,但我无法证实这一点,categorical_crossentropy
比它的稀疏对应物更快 运行。
对于你的情况,使用 26 类 我建议使用非稀疏版本并将你的标签转换为单热编码,如下所示:
def getData(filename):
images = []
labels = []
with open(filename) as csv_file:
file = csv.reader(csv_file, delimiter = ",")
next(file, None)
for row in file:
label = row[0]
data = row[1:]
img = np.array(data).reshape(28,28)
images.append(img)
labels.append(label)
images = np.array(images).astype("float64")
labels = np.array(labels).astype("float64")
return images, tf.keras.utils.to_categorical(labels, num_classes=26) # you can omit num_classes to have it computed from the data
旁注:除非你有理由对图像使用 float64
,否则我会切换到 float32
(它将数据集所需的内存减半,并且模型可能会将它们转换为 float32
作为第一个操作)
简单,对于输出 类 为整数 sparse_categorical_crosentropy 的分类问题,对于标签在一个热编码标签中转换的分类问题,我们使用 categorical_crosentropy.
所以我设计了一个 CNN 并使用以下参数进行编译,
training_file_loc = "8-SignLanguageMNIST/sign_mnist_train.csv"
testing_file_loc = "8-SignLanguageMNIST/sign_mnist_test.csv"
def getData(filename):
images = []
labels = []
with open(filename) as csv_file:
file = csv.reader(csv_file, delimiter = ",")
next(file, None)
for row in file:
label = row[0]
data = row[1:]
img = np.array(data).reshape(28,28)
images.append(img)
labels.append(label)
images = np.array(images).astype("float64")
labels = np.array(labels).astype("float64")
return images, labels
training_images, training_labels = getData(training_file_loc)
testing_images, testing_labels = getData(testing_file_loc)
print(training_images.shape, training_labels.shape)
print(testing_images.shape, testing_labels.shape)
training_images = np.expand_dims(training_images, axis = 3)
testing_images = np.expand_dims(testing_images, axis = 3)
training_datagen = ImageDataGenerator(
rescale = 1/255,
rotation_range = 45,
width_shift_range = 0.2,
height_shift_range = 0.2,
shear_range = 0.2,
zoom_range = 0.2,
horizontal_flip = True,
fill_mode = "nearest"
)
training_generator = training_datagen.flow(
training_images,
training_labels,
batch_size = 64,
)
validation_datagen = ImageDataGenerator(
rescale = 1/255,
rotation_range = 45,
width_shift_range = 0.2,
height_shift_range = 0.2,
shear_range = 0.2,
zoom_range = 0.2,
horizontal_flip = True,
fill_mode = "nearest"
)
validation_generator = training_datagen.flow(
testing_images,
testing_labels,
batch_size = 64,
)
model = tf.keras.Sequential([
keras.layers.Conv2D(16, (3, 3), input_shape = (28, 28, 1), activation = "relu"),
keras.layers.MaxPooling2D(2, 2),
keras.layers.Conv2D(32, (3, 3), activation = "relu"),
keras.layers.MaxPooling2D(2, 2),
keras.layers.Flatten(),
keras.layers.Dense(256, activation = "relu"),
keras.layers.Dropout(0.25),
keras.layers.Dense(512, activation = "relu"),
keras.layers.Dropout(0.25),
keras.layers.Dense(26, activation = "softmax")
])
model.compile(
loss = "categorical_crossentropy",
optimizer = RMSprop(lr = 0.001),
metrics = ["accuracy"]
)
但是,当我 运行 model.fit() 时,出现以下错误,
ValueError: Shapes (None, 1) and (None, 24) are incompatible
将损失函数更改为sparse_categorical_crossentropy
后,程序运行正常。
我不明白为什么会这样。
谁能解释一下这个以及这些损失函数之间的区别?
问题是,categorical_crossentropy
需要单热编码标签,这意味着,对于每个样本,它需要一个长度为 num_classes
的张量,其中设置了第 label
个元素为 1,其他一切为 0。
另一方面,sparse_categorical_crossentropy
直接使用整数标签(因为这里的用例是大量的类,所以one-hot-encoded标签会浪费内存很多零)。我相信,但我无法证实这一点,categorical_crossentropy
比它的稀疏对应物更快 运行。
对于你的情况,使用 26 类 我建议使用非稀疏版本并将你的标签转换为单热编码,如下所示:
def getData(filename):
images = []
labels = []
with open(filename) as csv_file:
file = csv.reader(csv_file, delimiter = ",")
next(file, None)
for row in file:
label = row[0]
data = row[1:]
img = np.array(data).reshape(28,28)
images.append(img)
labels.append(label)
images = np.array(images).astype("float64")
labels = np.array(labels).astype("float64")
return images, tf.keras.utils.to_categorical(labels, num_classes=26) # you can omit num_classes to have it computed from the data
旁注:除非你有理由对图像使用 float64
,否则我会切换到 float32
(它将数据集所需的内存减半,并且模型可能会将它们转换为 float32
作为第一个操作)
简单,对于输出 类 为整数 sparse_categorical_crosentropy 的分类问题,对于标签在一个热编码标签中转换的分类问题,我们使用 categorical_crosentropy.