构建神经网络 [TensorFlow 2.0] 模型子类化 - ValueError/TypeError
Posted
技术标签:
【中文标题】构建神经网络 [TensorFlow 2.0] 模型子类化 - ValueError/TypeError【英文标题】:Building Neural Networks [TensorFlow 2.0] Model sub-classing - ValueError/TypeError 【发布时间】:2020-05-23 23:51:27 【问题描述】:我正在使用 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 验证数据 = [X_test, y_test], 4 epochs = 50,batch_size = 16, ----> 5 个回调 = [回调] 6)
~/.local/lib/python3.7/site-packages/tensorflow_core/python/keras/engine/training.py in fit(self, x, y, batch_size, epochs, verbose, callbacks, validation_split,validation_data,shuffle,class_weight, sample_weight,initial_epoch,steps_per_epoch,validation_steps, 验证频率,最大队列大小,工人,使用多处理, **kwargs) 第726章 727工人=工人, --> 728 使用_多处理=使用_多处理) 729 730 def 评估(自我,
~/.local/lib/python3.7/site-packages/tensorflow_core/python/keras/engine/training_arrays.py 适合(自我,模型,x,y,batch_size,epochs,详细,回调, validation_split,validation_data,shuffle,class_weight, sample_weight,initial_epoch,steps_per_epoch,validation_steps, 验证频率,**kwargs) 640 步=steps_per_epoch, 第641章 --> 642 洗牌=洗牌) 643 第644章
~/.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_call = 真 2421 其他:
~/.local/lib/python3.7/site-packages/tensorflow_core/python/keras/engine/training.py 在 _build_model_with_inputs(self, inputs, targets) 2580 # 或 数组列表,并从传递的中提取输入的平面列表 2581#结构。 -> 2582 training_utils.validate_input_types(inputs, orig_inputs) 2583 2584 if isinstance(inputs, (list, tuple)):
~/.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 raise 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 数组后,当我执行 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
converted_call f in m.dict.values() for m in (collections, pdb, copy, inspect, re)): /home/arjun/.local/lib/python3.7/site-packages/tensorflow_core/python/autograph/impl/api.py:427 f in m.dict.values() for m in (collections, pdb, copy, inspect, re)): /home/arjun/.local/lib/python3.7/site-packages/tensorflow_core/python/ops/math_ops.py:1336 张量等于 return gen_math_ops.equal(self, other) /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(values), type(values).name, err))
TypeError: Expected float32 passed to parameter 'y' of op 'Equal', got 'collections' of type 'str' instead. Error: Expected float32, got
改为“str”类型的“集合”。
怎么了?
谢谢!
【问题讨论】:
【参考方案1】:我解决了这个问题。根据 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]
)
谢谢!
【讨论】:
如果您注意的话,我在您的其他问题上给了您类似的回复。很好,你解决了这个问题。 :D 我一直在寻找我在回答中引用的解释,因为这很清楚。但是,谢谢! :D【参考方案2】:您的问题源于您在将数据拟合到模型之前对数据进行预处理的方式。
很有可能您从 iris 传递了整个 csv 数据集,包括您的列标题,因此是您的问题。您可以从
验证这一点"你通过了:inputs= sepallength sepalwidth petallength petalwidth 117 7.7 3.8 6.7"。
确保您的 Xs 和 ys 不包含列名,而只包含值。使用X_train = X_train.to_numpy()
确保转换正常。在旧版本中,您也可以使用X_train.values
,但后者已被弃用。
【讨论】:
请至少投票,因为它解决了您的第一个问题。如果您有其他问题,请提出另一个问题,而不是在一个问题中提出一系列问题。谢谢。 这不是一系列问题。在我将训练和测试集转换为 numpy 后(如您所建议的),我收到一个新错误,即 TypeError 上一期还没跑到现在,正在研究帮助大家以上是关于构建神经网络 [TensorFlow 2.0] 模型子类化 - ValueError/TypeError的主要内容,如果未能解决你的问题,请参考以下文章
翻译: TensorFlow 2.0 中的符号和命令式 API 是什么?
python tensorflow 2.0 不使用 Keras 搭建简单的 LSTM 网络
TensorFlow2.0TensorFlow 2.0高阶API: Keras—使用Keras基于Squential的序列编排模式创建神经网络过程(附带源码)