建立神经网络[TensorFlow 2.0]模型子类-ValueError / TypeError

时间:2020-02-07 20:00:34

标签: python-3.x keras neural-network tensorflow2.0

我正在使用带有Python 3.7.5的TensorFlow 2.0,以使用模型子分类方法构建用于虹膜分类的神经网络。

我的代码如下:

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追踪(最近的呼叫 最后) 3validation_data = [X_test,y_test], 4个时期= 50,batch_size = 16 ----> 5个回调= [回调] 6)

〜/ .local / lib / python3.7 / site-packages / tensorflow_core / python / keras / engine / training.py 适合(自我,x,y,batch_size,时代,冗长,回调, validate_split,validation_data,随机播放,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_multiprocessing) 729 730 def评价(self,

〜/ .local / lib / python3.7 / site-packages / tensorflow_core / python / keras / engine / training_arrays.py 适合(自我,模型,x,y,batch_size,历元,冗长,回调, validate_split,validation_data,随机播放,class_weight, sample_weight,initial_epoch,steps_per_epoch,validation_steps, validation_freq,** kwargs) 640个步骤= steps_per_epoch, 641 validate_split = validation_split, -> 642 shuffle = shuffle) 643 644如果validation_data:

〜/ .local / lib / python3.7 / site-packages / tensorflow_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 / tensorflow_core / python / keras / engine / training.py 在_build_model_with_inputs(自己,输入,目标)2580#或 数组列表,并从传递的列表中提取输入的平面列表
2581#结构。 -> 2582 training_utils.validate_input_types(输入,orig_inputs)2583 2584如果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:请提供一个数组或一个数组作为模型输入 数组列表。您通过了:输入= sepallength sepalwidth 花瓣长度花瓣宽度117 7.7 3.8 6.7
2.2 7 5.0 3.4 1.5 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数组后,执行历史2训练模型时,出现以下错误:

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

converted_call m中的f中的m。 dict .values()(收集,pdb,复制,检查,重新)): /home/arjun/.local/lib/python3.7/site-packages/tensorflow_core/python/autograph/impl/api.py:427 m中的f中的m。 dict .values()(收集,pdb,复制,检查,重新)): /home/arjun/.local/lib/python3.7/site-packages/tensorflow_core/python/ops/math_ops.py:1336 张量等于 返回gen_math_ops.equal(自己,其他) /home/arjun/.local/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(值),类型(值)。名称,错误))

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

类型为“ str”的“收藏”。

怎么了?

谢谢!

2 个答案:

答案 0 :(得分:1)

您的问题源于在将数据拟合到模型之前对其进行预处理的方式。

很有可能您从虹膜传递了整个csv数据集,包括列标题,因此出现了问题。您可以从

进行验证

“您通过了:input = sepallength sepalwidth花瓣长度petalwidth 117 7.7 3.8 6.7“。

确保X和y不包含列名,而仅包含值。使用X_train = X_train.to_numpy()以确保转换有效。在较早的版本中,您也可以使用X_train.values,但不建议使用后者。

答案 1 :(得分:0)

我解决了这个问题。根据弗朗索瓦·乔勒(Francois Chollet)的说法:

子类化模型是一段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]
    )

谢谢!