python - 使用 Tensorflow 的目标数组形状与预期输出不同
问题描述
我正在尝试制作 CNN(仍然是初学者)。尝试拟合模型时出现此错误:
ValueError: 形状为 (10000, 10) 的目标数组在用作 loss 时传递给形状 (None, 6, 6, 10) 的输出categorical_crossentropy
。这种损失期望目标具有与输出相同的形状。
标签的形状 = (10000, 10) 图像数据的形状 = (10000, 32, 32, 3)
代码:
import pickle
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import (Dense, Dropout, Activation, Flatten,
Conv2D, MaxPooling2D)
from tensorflow.keras.callbacks import TensorBoard
from keras.utils import to_categorical
import numpy as np
import time
MODEL_NAME = f"_________{int(time.time())}"
BATCH_SIZE = 64
class ConvolutionalNetwork():
'''
A convolutional neural network to be used to classify images
from the CIFAR-10 dataset.
'''
def __init__(self):
'''
self.training_images -- a 10000x3072 numpy array of uint8s. Each
a row of the array stores a 32x32 colour image.
The first 1024 entries contain the red channel
values, the next 1024 the green, and the final
1024 the blue. The image is stored in row-major
order, so that the first 32 entries of the array are the red channel values of the first row of the image.
self.training_labels -- a list of 10000 numbers in the range 0-9.
The number at index I indicates the label
of the ith image in the array data.
'''
# List of image categories
self.label_names = (self.unpickle("cifar-10-batches-py/batches.meta",
encoding='utf-8')['label_names'])
self.training_data = self.unpickle("cifar-10-batches-py/data_batch_1")
self.training_images = self.training_data[b'data']
self.training_labels = self.training_data[b'labels']
# Reshaping the images + scaling
self.shape_images()
# Converts labels to one-hot
self.training_labels = np.array(to_categorical(self.training_labels))
self.create_model()
self.tensorboard = TensorBoard(log_dir=f'logs/{MODEL_NAME}')
def unpickle(self, file, encoding='bytes'):
'''
Unpickles the dataset files.
'''
with open(file, 'rb') as fo:
training_dict = pickle.load(fo, encoding=encoding)
return training_dict
def shape_images(self):
'''
Reshapes the images and scales by 255.
'''
images = list()
for d in self.training_images:
image = np.zeros((32,32,3), dtype=np.uint8)
image[...,0] = np.reshape(d[:1024], (32,32)) # Red channel
image[...,1] = np.reshape(d[1024:2048], (32,32)) # Green channel
image[...,2] = np.reshape(d[2048:], (32,32)) # Blue channel
images.append(image)
for i in range(len(images)):
images[i] = images[i]/255
images = np.array(images)
self.training_images = images
print(self.training_images.shape)
def create_model(self):
'''
Creating the ConvNet model.
'''
self.model = Sequential()
self.model.add(Conv2D(64, (3, 3), input_shape=self.training_images.shape[1:]))
self.model.add(Activation("relu"))
self.model.add(MaxPooling2D(pool_size=(2,2)))
self.model.add(Conv2D(64, (3,3)))
self.model.add(Activation("relu"))
self.model.add(MaxPooling2D(pool_size=(2,2)))
# self.model.add(Flatten())
# self.model.add(Dense(64))
# self.model.add(Activation('relu'))
self.model.add(Dense(10))
self.model.add(Activation(activation='softmax'))
self.model.compile(loss="categorical_crossentropy", optimizer="adam",
metrics=['accuracy'])
def train(self):
'''
Fits the model.
'''
print(self.training_images.shape)
print(self.training_labels.shape)
self.model.fit(self.training_images, self.training_labels, batch_size=BATCH_SIZE,
validation_split=0.1, epochs=5, callbacks=[self.tensorboard])
network = ConvolutionalNetwork()
network.train()
非常感谢帮助,已经尝试修复了一个小时。
解决方案
Flatten
创建模型时,您需要取消注释该层。本质上,这一层的作用是接受 4D 输入(batch_size, height, width, num_filters)
并将其展开为 2D输入(batch_size, height * width * num_filters)
。这是获得您想要的输出形状所必需的。
推荐阅读
- excel - 当单元格包含引用另一个工作表中另一个单元格的公式时,如何更新时间戳?
- google-apps-script - 长时间运行后无法让 MailApp.sendEmail 在谷歌应用脚本中工作
- javascript - 如何使我的循环与 setTimeout 一起工作?
- sql - 3 个表(1 个桥)选择表 3 在表 1 中没有条目的位置
- python - 在 Django 中注释现有模型对象
- image - 在 SwiftUI 中向 TextField/SecureField 添加图像,向占位符文本添加填充
- hyperlink - Google 文档中的可点击电话号码
- python - 如何获取每个键索引(第一级)的值并使用它来做某事
- assembly - NASM 汇编器浮点加法
- sqlite - Sqlite pviot 添加带有总计的计数行