首页 > 解决方案 > 构建用于多类图像分类的 ANN 模型

问题描述

我正在尝试创建基线 ANN 和改进的 ANN 模型,并比较它们在图像分类中的有效性。我有一个由水果(苹果、香蕉、橙子、番茄)图像组成的训练和测试数据集。原始图像为 480 x 320,但我将它们重新整形并转换为一维数组。

下面是通过数据生成器 UDF 进行转换的代码。

import os
import glob
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
import re
from tensorflow import keras
from tensorflow.keras import layers

def train_generator_func(info=False, image=False):
train_data_generator = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1./255, shear_range=0.2,
                                                                           zoom_range=0.2, horizontal_flip=True)
    train_generator = train_data_generator.flow_from_directory('data/Train', target_size=(68, 46),
                                                               batch_size=32, class_mode='sparse')
    if info:
        print('The image shape of each training observation is:', train_generator.image_shape)
        print('\n We can see how:')
        for i in range(len(train_generator.class_indices)):
            print(list(train_generator.class_indices.keys())[i],
                  'is labeled as', list(train_generator.class_indices.values())[i])

    if image:
        fig, axs = plt.subplots(2, 2, figsize=(10, 10))
        for i, ax in enumerate(axs.flatten()):
            img, label = train_generator.next()
            _ = ax.set_title(f'Label = {np.argmax(label[i])}')
            _ = ax.imshow(img[i])
        plt.show()
    return train_generator

测试标签 UDF

def test_label_func():
"""
:return: returns a vector with the labels of the test files
"""
data_path = os.path.join('data/Test', '*g')
files = glob.glob(data_path)

test_label_fruit = list()
test_label = list()
label = None
for f in files:
    photo = re.sub(r"data/Test/", "", f)
    photo = re.findall(r"[a-zA-Z]", photo)
    photo = ''.join(photo)
    photo = re.sub(r"png", "", photo)
    if photo == 'Apple':
        label = 0
    if photo == 'Banana':
        label = 1
    if photo == 'Orange':
        label = 2
    if photo == 'Tamotoes':
        photo = 'Tomato'
test_label.append(photo)
return files, test_label
label = 3
test_label_fruit.append(photo)
test_label.append(label)
return files, test_label, test_label_fruit

构建 ANN 模型

#ANN Model
import tensorflow as tf
import numpy as np
from sklearn.model_selection import train_test_split
from keras.preprocessing.image import ImageDataGenerator
from train_test_split import train_generator_func
from train_test_split import test_label_func
from sklearn.metrics import accuracy_score

train_generator = train_generator_func(info=True)
files, test_label, test_label_fruit = test_label_func()

model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Dense(units = 3128, activation = 'relu', input_shape = (100096,3)))
#model.add(tf.keras.layers.Dropout(0.2)) #Dropout Layer to help avoid overfitting
model.add(tf.keras.layers.Dense(units = 4, activation = 'softmax')) #Dense Layer, Units = # of Classes 4
model.compile(optimizer = 'adam', loss = 'sparse_categorical_crossentropy', metrics = ['sparse_categorical_accuracy'])

这按预期返回

Found 12834 images belonging to 4 classes.
The image shape of each training observation is: (68, 46, 3)

 We can see how:
Apple is labeled as 0
Banana is labeled as 1
Orange is labeled as 2
Tomato is labeled as 3

当我尝试拟合模型时 - 我收到此错误:

model.fit(train_generator, epochs =1)

InvalidArgumentError:logits 和标签必须具有相同的第一维,得到 logits 形状 [100096,4] 和标签形状 [128] [[node sparse_categorical_crossentropy/SparseSoftmaxCrossEntropyWithLogits/SparseSoftmaxCrossEntropyWithLogits(定义于:1)]] [Op:__inference_train_function_26958]

函数调用栈:train_function

我不确定我在这里做错了什么。此外,从概念上讲,您如何设置 ANN 模型的神经元数量以及如何确定设置多少?我觉得这是错误所在,但我不确定。

标签: pythontensorflowimage-processingkerasimage-classification

解决方案


推荐阅读