我有10,000张图片,每张图片都标记了20个标签。对于每张图片,每个标签要么是真要么是假。我正在尝试训练一个多输出模型,以使用一个网络执行所有这20个二元分类任务。
该网络是一个残差网络。在平展层之后,网络分支成20个分支。每个分支有两个全连接层,每个全连接层后面都跟着一个 dropout 层。最后是一个具有一个节点和 sigmoid 激活函数的密集层。
每张图片的标签和图片名称都存储在一个文本文件中,用于训练和验证集。如下所示:1.jpg 1 -1 1 -1 -1 1 -1………
我编写了自己的生成器,但无法使其正常工作。我一直遇到以下错误:
Error when checking model target: the list of Numpy arrays that you are passing to your model is not the size the model expected. Expected to see 20 array(s), but instead got the following list of 1 arrays.
函数说明:get_input
函数读取并调整图片大小。get_output
准备每张图片的标签。标签存储在一个列表中,最后返回。preprocess_input
执行预处理并将图片转换为数组。train_generator
和validation_generator
生成大小为32的批次,供模型使用。
这是我的代码:
def get_input(img_name): path = os.path.join("images", img_name) img = image.load_img(path, target_size=(224, 224)) return imgdef get_output(img_name, file_path): data = pd.read_csv(file_path, delim_whitespace=True, header=None) img_id = img_name.split(".")[0] img_id = img_id.lstrip("0") img_id = int(img_id) labels = data.loc[img_id - 1].values labels = labels[1:] labels = list(labels) label_arrays = [] for i in range(20): val = np.zeros((1)) val[0] = labels[i] label_arrays.append(val) return label_arraysdef preprocess_input(img_name): img = get_input(img_name) x = image.img_to_array(img) x = np.expand_dims(x, axis=0) return xdef train_generator(batch_size): file_path = "train.txt" data = pd.read_csv(file_path, delim_whitespace=True, header=None) while True: for i in range(math.floor(8000/batch_size)): x_batch = np.zeros(shape=(32, 224, 224, 3)) y_batch = np.zeros(shape=(32, 20)) for j in range(batch_size): img_name = data.loc[i * batch_size + j].values img_name = img_name[0] x = preprocess_input(img_name) y = get_output(img_name, file_path) x_batch[j, :, :, :] = x y_batch[j] = y yield(x_batch, y_batch)def val_generator(batch_size): file_path = "val.txt" data = pd.read_csv(file_path, delim_whitespace=True, header=None) while True: for i in range(math.floor(2000/batch_size)): x_batch = np.zeros(shape=(32, 224, 224, 3)) y_batch = np.zeros(shape=(32, 20)) for j in range(batch_size): img_name = data.loc[i * batch_size + j].values img_name = img_name[0] x = preprocess_input(img_name) y = get_output(img_name, file_path) x_batch[j, :, :, :] = x y_batch[j] = y yield(x_batch, y_batch)
编辑:有一个快速问题。这段循环和您答案中的循环有什么区别:
ys = []for i in range(batch_size): ys.append(y_batch[i, :])yield(x_batch, ys)
回答:
如果您的模型有20个输出,那么您必须提供一个包含20个数组的列表作为目标。实现这一点的一种方法是修改生成器(对于训练和验证都适用):
ys = []for i in range(20): ys.append(y_batch[:,i])yield(x_batch, ys)
另外,您提到每个样本有20个标签,那么为什么在输入形状中指定了40呢?
y_batch = np.zeros(shape=(32, 40))
此外,我不知道您具体在处理什么问题,但另一种选择是您可以只有一个大小为20的输出,而不是20个大小为1的输出。