Построение нейронных сетей [TensorFlow 2.0] Подклассификация модели - ValueError / TypeError - PullRequest
0 голосов
/ 07 февраля 2020

Я использую TensorFlow 2.0 с Python 3.7.5 для построения нейронной сети для классификации радужной оболочки с использованием подхода подклассификации модели.

Код, который я имею, выглядит следующим образом:

import tensorflow as tf
from tensorflow.keras import Sequential, Model
from tensorflow.keras.layers import Dense, Input
import pandas as pd
import numpy as np


# Read in data-
data = pd.read_csv("iris.csv")

# Get data types for different attributes-
data.dtypes
'''
sepallength    float64
sepalwidth     float64
petallength    float64
petalwidth     float64
class           object
dtype: object
'''


# Get shape of data-
data.shape
# (150, 5)


# Check for missing values-
data.isnull().values.any()
# False

# Perform label encoding for target variable-

# Initialize a label encoder-
le = LabelEncoder()

# Label encode target attribute-
data['class'] = le.fit_transform(data['class'])

# Get different classes which are label encoded-
le.classes_
# array(['Iris-setosa', 'Iris-versicolor', 'Iris-virginica'], dtype=object)

# Split data into features (X) and target (y)-
X = data.drop('class', axis = 1)
y = data['class']


# Get training & testing sets using features and labels-
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)

# Convert from Pandas to numpy arrays-
X_train = X_train.to_numpy()
X_test = X_test.to_numpy()

y_train = y_train.to_numpy()
y_test = y_test.to_numpy()

print("\nTraining and Testing set dimensions:")
print("X_train.shape = {0}, y_train.shape = {1}".format(X_train.shape, y_train.shape))
print("X_test.shape = {0}, y_test.shape = {1}\n".format(X_test.shape, y_test.shape))
# Training and Testing set dimensions:
# X_train.shape = (105, 4), y_train.shape = (105,)
# X_test.shape = (45, 4), y_test.shape = (45,)



class IrisClassifier(Model):

    def __init__(self):
        super(IrisClassifier, self).__init__()

        '''
        self.layer1 = Dense(
            units = 4, activation = 'relu',
            kernel_initializer = tf.keras.initializers.GlorotNormal()
            )
        '''

        self.input_layer = Input(
            shape = (4,)
            )

        self.layer1 = Dense(
            units = 10, activation = 'relu',
            input_dim = 4,
            kernel_initializer = tf.keras.initializers.GlorotNormal()
            )

        self.layer2 = Dense(
            units = 10, activation = 'relu',
            kernel_initializer = tf.keras.initializers.GlorotNormal()
            )

        self.outputlayer = Dense(
            units = 3, activation = 'softmax'
            )


    def call(self, x):
        x = self.input_layer(x)
        x = self.layer1(x)
        x = self.layer2(x)
        # x = self.layer3(x)

        return self.outputlayer(x)


# Instantiate a model of defined neural network class-
model = IrisClassifier()

# Define EarlyStopping callback-
callback = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=3)

# Compile defined model-
model.compile(
    optimizer=tf.keras.optimizers.Adam(lr = 0.001),
    loss = 'sparse_categorical_crossentropy',
    metrics = ['accuracy']
     )


# Train model-
history2 = model.fit(
    x = X_train, y = y_train,
    validation_data = [X_test, y_test],
    epochs = 50, batch_size = 16,
    callbacks = [callback]
    )

Когда я выполняю код 'history2', я получаю следующую ошибку:

------------------------ -------------------------------------------------- - ValueError Traceback (последний последний вызов) в 3 validation_data = [X_test, y_test], 4 эпохах = 50, batch_size = 16, ----> 5 обратных вызовов = [callback] 6)

~ /. local / lib / python3 .7 / site-packages / tenorflow_core / python / keras / engine / training.py в соответствии (self, x, y, batch_size, эпохи, подробные, обратные вызовы, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, validation_freq, max_queue_size, рабочие, use_multiprocessing, ** kwargs) 726 max_queue_size = max_queue_size, 727 рабочих = работников, -> 728 use_multiprocessing = use_m2 7302302_302_2_302_2_322_302_2_1_2_30_32_1_2_1_2_30_32_2_1_2_1 * ~ /.local/lib/python3.7/site-packages/tensorflow_core/python/keras/engine/training_arrays.py в соответствии (self, model, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, validation_freq, ** kwargs) 640 steps = steps_per_epoch, 641 validation_split = validation_split, -> 642 shuffle = shuffle) 643 644 если 1013 * 101 * 101 * 101 * local / lib / python3 .7 / site-packages / tenorflow_core / python / keras / engine / training.py в _standardize_user_data (self, x, y, sample_weight, class_weight, batch_size, check_steps, steps_name, steps, validation_split, shuffle, extract_tensors_from_dataset) 2417 # Сначала, если необходимо, мы строим модель на лету. 2418, если не self.inputs: -> 2419 all_inputs, y_input, dict_inputs = self._build_model_with_inputs (x, y) 2420 is_build_called = True 2421 остальное:

~ / .local / lib / python3 .7 / site-packages / tenorflow_core / python / keras / engine / training.py в _build_model_with_inputs (self, input, target) 2580 # или списках массивов и извлекать плоский список входных данных из переданной структуры
2581 #. -> 2582 training_utils.validate_input_types (входные данные, orig_inputs) 2583 2584 if isinstance (входные данные, (список, кортеж)):

~ / .local / lib / python3 .7 / site-packages / tensorflow_core / python / keras / engine / training_utils.py в validate_input_types (inp, orig_inp, allow_dict, field_name) 1149 повысить ValueError (1150 'Пожалуйста, предоставьте в качестве входных данных модели либо один массив, либо список массивов' -> 1151 '. Вы передали: { } = {} '. format (field_name, orig_inp)) 1152 1153

ValueError: Пожалуйста, укажите в качестве входных данных модели либо один массив, либо список массивов. Вы прошли: inputs = sepallength sepalidth petallength petalwidth 117 7,7 3,8 6,7
2,2 7 5,0 3,4 0,2 0,2 ​​73 6,1 2,8 4,7 1,2 92 5,8 2,6 4,0 1,2 87 6,3 2,3 4,4 1,3 ... ... ... ... .. 93 5.0 2,3 3.3 1.0 30 4.8 3.1 1.6 0.2 25 5.0 3.0 1.6 0.2 31 5.4 3.4 1.5 0.4 97 6.2 2.9 4.3 1.3

[105 строк x 4 столбца]

После преобразования X_train, y_train, X_test и y_test для numpy массивов, когда я выполняю, history2 для обучения модели, я получаю следующую ошибку:

TypeError: в преобразованном коде:

<ipython-input-14-ae6111e00410>:34 call  *
    x = self.input_layer(x)
/home/arjun/.local/lib/python3.7/site-packages/tensorflow_core/python/autograph/impl/api.py:427

convert_call f в м. dict .values ​​() для m in (коллекции, pdb, копировать, проверять, повторно)): /home/arjun/.local/lib/python3 .7 / site-packages / tenorflow_core / python / autograph / impl / api.py: 427 f в м. dict .values ​​() для m in (коллекции, pdb, копировать, проверять, повторно) . /lib/python3.7/site-packages/tensorflow_core/python/ops/gen_math_ops.py:3627 равное имя = имя) /home/arjun/.local/lib/python3.7/site-packages/tensorflow_core /python/framework/op_def_library.py:536 _apply_op_helper repr (значения), тип (значения). name , err))

TypeError: Expected float32 passed to parameter 'y' of op 'Equal', got 'collections' of type 'str' instead. Error: Expected float32, got

'коллекции' типа 'str' вместо .

Что не так?

Спасибо!

Ответы [ 2 ]

1 голос
/ 07 февраля 2020

Ваша проблема связана с тем, как вы предварительно обрабатываете свои данные, прежде чем приспособить их к своей модели.

Весьма вероятно, что вы передали весь набор данных csv из iris, включая заголовки столбцов, следовательно, ваш вопрос. Вы можете проверить это из

"Вы прошли: input = sepallength sepalwidth petallength petalwidth 117 7.7 3.8 6.7".

Убедитесь, что ваши X и Y не содержат столбец имена, но только значения. Используйте X_train = X_train.to_numpy(), чтобы убедиться, что преобразование работает. В более старых версиях вы также могли использовать X_train.values, но последняя устарела.

0 голосов
/ 08 февраля 2020

Я решил проблему. Согласно Франсуа Шоле:

Подклассовая модель представляет собой фрагмент кода Python (метод вызова). Здесь нет графика слоев. Мы не можем знать, как слои связаны друг с другом (потому что это определено в теле вызова, а не в виде явной структуры данных), поэтому мы не можем вывести формы ввода / вывода

Следовательно, следующий код работает нормально (где вы не указываете форму входных данных тренировки):

# Define EarlyStopping callback-
callback = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=3)

class IrisClassifier(Model):

    def __init__(self):
        super(IrisClassifier, self).__init__()

        self.layer1 = Dense(
            units = 10, activation = 'relu',
            # input_dim = 4,
            kernel_initializer = tf.keras.initializers.GlorotNormal()
            )

        self.layer2 = Dense(
            units = 10, activation = 'relu',
            kernel_initializer = tf.keras.initializers.GlorotNormal()
            )

        self.outputlayer = Dense(
            units = 3, activation = 'softmax'
            )


    def call(self, x):
        # x = self.input_layer(x)
        x = self.layer1(x)
        x = self.layer2(x)
        # x = self.layer3(x)
        return self.outputlayer(x)


# Instantiate a model of defined neural network class-
model2 = IrisClassifier()


# Compile defined model-
model2.compile(
    optimizer=tf.keras.optimizers.Adam(lr = 0.001),
    loss = 'sparse_categorical_crossentropy',
    metrics = ['accuracy']
     )


# Train model-
history2 = model2.fit(
    x = X_train, y = y_train,
    validation_data = [X_test, y_test],
    epochs = 50, batch_size = 16,
    callbacks = [callback]
    )

Спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...