在Tensorflow 2.0中运行简单回归

我正在学习Tensorflow 2.0,并且我认为实现最基本的简单线性回归是一个好主意。不幸的是,我遇到了几个问题,我想知道这里是否有人可以帮助我。

考虑以下设置:

import tensorflow as tf # 2.0.0-alpha0import numpy as npx_data = np.random.randn(2000, 1)w_real = [0.7] # coefficientsb_real = -0.2 # global biasnoise = np.random.randn(1, 2000) * 0.5 # level of noisey_data = np.matmul(w_real, x_data.T) + b_real + noise

现在继续进行模型定义:

# 使用tensorflow手动建模这些数据class SimpleRegressionNN(tf.keras.Model):    def __init__(self):        super(SimpleRegressionNN, self).__init__()        self.input_layer = tf.keras.layers.Input        self.output_layer = tf.keras.layers.Dense(1)    def call(self, data_input):        model = self.input_layer(data_input)        model = self.output_layer(model)        # 开放问题:如何考虑截距/偏置项?        # 理想情况下,我们希望生成的预测值为matmult(X,W) + b        return modelnn_regressor = SimpleRegressionNN()reg_loss = tf.keras.losses.MeanSquaredError()reg_optimiser = tf.keras.optimizers.SGD(0.1)metric_accuracy = tf.keras.metrics.mean_squared_error# 定义前向步骤@tf.functiondef train_step(x_sample, y_sample):  with tf.GradientTape() as tape:    predictions = nn_regressor(x_sample)    loss = reg_loss(y_sample, predictions)    gradients = tape.gradient(loss, nn_regressor.trainable_variables) # 需要缩进这行!  reg_optimiser.apply_gradients(zip(gradients, nn_regressor.trainable_variables))    metric_accuracy(y_sample, predictions)#%%# 运行模型for epoch in range(10):    for x_point, y_point in zip(x_data.T[0], y_data[0]): # 批量大小为1        train_step(x_sample=x_point, y_sample=y_point)    print("MSE: {}".format(metric_accuracy.result()))

不幸的是,我收到了以下错误:

TypeError: You are attempting to use Python control flow in a layer that was not declared to be dynamic. Pass `dynamic=True` to the class constructor.Encountered error:"""Tensor objects are only iterable when eager execution is enabled. To iterate over this tensor use tf.map_fn."""

完整的错误输出在这里:

---------------------------------------------------------------------------TypeError                                 Traceback (most recent call last)/anaconda3/lib/python3.6/site-packages/tensorflow/python/keras/engine/base_layer.py in __call__(self, inputs, *args, **kwargs)    611                                                       inputs)) as auto_updater:--> 612                 outputs = self.call(inputs, *args, **kwargs)    613                 auto_updater.set_outputs(outputs)<ipython-input-5-8464ad8bcf07> in call(self, data_input)      7     def call(self, data_input):----> 8         model = self.input_layer(data_input)      9         model = self.output_layer(model)/anaconda3/lib/python3.6/site-packages/tensorflow/python/keras/engine/input_layer.py in Input(shape, batch_size, name, dtype, sparse, tensor, **kwargs)    232       sparse=sparse,--> 233       input_tensor=tensor)    234   # Return tensor including `_keras_history`./anaconda3/lib/python3.6/site-packages/tensorflow/python/keras/engine/input_layer.py in __init__(self, input_shape, batch_size, dtype, input_tensor, sparse, name, **kwargs)     93       if input_shape is not None:---> 94         batch_input_shape = (batch_size,) + tuple(input_shape)     95       else:/anaconda3/lib/python3.6/site-packages/tensorflow/python/framework/ops.py in __iter__(self)    448       raise TypeError(--> 449           "Tensor objects are only iterable when eager execution is "    450           "enabled. To iterate over this tensor use tf.map_fn.")TypeError: Tensor objects are only iterable when eager execution is enabled. To iterate over this tensor use tf.map_fn.During handling of the above exception, another exception occurred:TypeError                                 Traceback (most recent call last)<ipython-input-22-e1bde858b0fc> in <module>()      3     #train_step(x_sample=x_data.T[0], y_sample=y_data[0])      4     for x_point, y_point in zip(x_data.T[0], y_data[0]):----> 5         train_step(x_sample=x_point, y_sample=y_point)      6     print("MSE: {}".format(metric_accuracy.result()))      7 /anaconda3/lib/python3.6/site-packages/tensorflow/python/eager/def_function.py in __call__(self, *args, **kwds)    416       # In this case we have not created variables on the first call. So we can    417       # run the first trace but we should fail if variables are created.--> 418       results = self._stateful_fn(*args, **kwds)    419       if self._created_variables:    420         raise ValueError("Creating variables on a non-first call to a function"/anaconda3/lib/python3.6/site-packages/tensorflow/python/eager/function.py in __call__(self, *args, **kwargs)   1285   def __call__(self, *args, **kwargs):   1286     """Calls a graph function specialized to the inputs."""-> 1287     graph_function, args, kwargs = self._maybe_define_function(args, kwargs)   1288     return graph_function._filtered_call(args, kwargs)  # pylint: disable=protected-access   1289 /anaconda3/lib/python3.6/site-packages/tensorflow/python/eager/function.py in _maybe_define_function(self, args, kwargs)   1609           relaxed_arg_shapes)   1610       graph_function = self._create_graph_function(-> 1611           args, kwargs, override_flat_arg_shapes=relaxed_arg_shapes)   1612       self._function_cache.arg_relaxed[rank_only_cache_key] = graph_function   1613 /anaconda3/lib/python3.6/site-packages/tensorflow/python/eager/function.py in _create_graph_function(self, args, kwargs, override_flat_arg_shapes)   1510             arg_names=arg_names,   1511             override_flat_arg_shapes=override_flat_arg_shapes,-> 1512             capture_by_value=self._capture_by_value),   1513         self._function_attributes)   1514 /anaconda3/lib/python3.6/site-packages/tensorflow/python/framework/func_graph.py in func_graph_from_py_func(name, python_func, args, kwargs, signature, func_graph, autograph, autograph_options, add_control_dependencies, arg_names, op_return_value, collections, capture_by_value, override_flat_arg_shapes)    692                                           converted_func)    693 --> 694       func_outputs = python_func(*func_args, **func_kwargs)    695     696       # invariant: `func_outputs` contains only Tensors, IndexedSlices,/anaconda3/lib/python3.6/site-packages/tensorflow/python/eager/def_function.py in wrapped_fn(*args, **kwds)    315         # __wrapped__ allows AutoGraph to swap in a converted function. We give    316         # the function a weak reference to itself to avoid a reference cycle.--> 317         return weak_wrapped_fn().__wrapped__(*args, **kwds)    318     weak_wrapped_fn = weakref.ref(wrapped_fn)    319 /anaconda3/lib/python3.6/site-packages/tensorflow/python/framework/func_graph.py in wrapper(*args, **kwargs)    684                   optional_features=autograph_options,    685                   force_conversion=True,--> 686               ), args, kwargs)    687     688         # Wrapping around a decorator allows checks like tf_inspect.getargspec/anaconda3/lib/python3.6/site-packages/tensorflow/python/autograph/impl/api.py in converted_call(f, owner, options, args, kwargs)    390     return _call_unconverted(f, args, kwargs)    391 --> 392   result = converted_f(*effective_args, **kwargs)    393     394   # The converted function's closure is simply inserted into the function's/var/folders/8_/pl9fgq297ld3b7kgy5tmvf700000gn/T/tmpluzodr7d.py in tf__train_step(x_sample, y_sample)      2 def tf__train_step(x_sample, y_sample):      3   with tf.GradientTape() as tape:----> 4     predictions = ag__.converted_call(nn_regressor, None, ag__.ConversionOptions(recursive=True, verbose=0, strip_decorators=(tf.function, defun, ag__.convert, ag__.do_not_convert, ag__.converted_call), force_conversion=False, optional_features=(), internal_convert_user_code=True), (x_sample,), {})      5     loss = ag__.converted_call(reg_loss, None, ag__.ConversionOptions(recursive=True, verbose=0, strip_decorators=(tf.function, defun_1, ag__.convert, ag__.do_not_convert, ag__.converted_call), force_conversion=False, optional_features=(), internal_convert_user_code=True), (y_sample, predictions), {})      6     gradients = ag__.converted_call('gradient', tape, ag__.ConversionOptions(recursive=True, verbose=0, strip_decorators=(tf.function, defun_2, ag__.convert, ag__.do_not_convert, ag__.converted_call), force_conversion=False, optional_features=(), internal_convert_user_code=True), (loss, nn_regressor.trainable_variables), {})/anaconda3/lib/python3.6/site-packages/tensorflow/python/autograph/impl/api.py in converted_call(f, owner, options, args, kwargs)    265     266   if not options.force_conversion and conversion.is_whitelisted_for_graph(f):--> 267     return _call_unconverted(f, args, kwargs)    268     269   # internal_convert_user_code is for example turned off when issuing a dynamic/anaconda3/lib/python3.6/site-packages/tensorflow/python/autograph/impl/api.py in _call_unconverted(f, args, kwargs)    186     return f.__self__.call(args, kwargs)    187 --> 188   return f(*args, **kwargs)    189     190 /anaconda3/lib/python3.6/site-packages/tensorflow/python/keras/engine/base_layer.py in __call__(self, inputs, *args, **kwargs)    623                                   'dynamic. Pass `dynamic=True` to the class '    624                                   'constructor.\nEncountered error:\n"""\n' +--> 625                                   exception_str + '\n"""')    626               raise    627           else:TypeError: You are attempting to use Python control flow in a layer that was not declared to be dynamic. Pass `dynamic=True` to the class constructor.Encountered error:"""Tensor objects are only iterable when eager execution is enabled. To iterate over this tensor use tf.map_fn."""

问题在于,2.0默认设置为启用急切执行模式!

除了这个问题之外,我还有一些额外的问题:

  1. 在这里考虑截距项的最佳方法是什么?
  2. 这种方法是否合理,或者我在这里做了一些奇怪的事情?(忽略批量大小和没有验证数据的事实,这只是一个玩具示例)

非常感谢!


回答:

我有以下几点评论:

  • 在你的SimpleRegression模型中不需要Input层。另外,不要在call()方法中将层的张量输出命名为”model“。这真的很容易混淆。
  • 你没有向train_step函数传递正确的形状。它期望接收(n_samples, input_dim),而你传递的是(input_dim, )。
  • 记住,在tensorflow中,张量的第一个维度总是批量大小(即样本数量)。始终这样使用,不要进行转置操作。
  • 你为什么将metric_accuracy = tf.keras.metrics.mean_squared_error称为准确度?你有一个回归问题,回归中没有准确度这种说法。另外,你为什么定义了两次并计算了两次mse
  • 如果你使用tf.convert_to_tensor()转换你的数据,执行速度会更快。
  • 函数train_step()执行了前向和后向传递,而不仅仅是前向传递。
  • 对于玩具示例,请使用小数据集(2-10个样本,而不是2000个),特别是如果你不知道你的代码是否工作的情况下!
  • 你的函数train_step()不返回任何东西,你如何期望打印mse损失的值。

这是你代码的更正版本:

import tensorflow as tf # 2.0.0-alpha0import numpy as npx_data = np.random.randn(5, 2)w_real = 0.7 # coefficientsb_real = -0.2 # global biasnoise = np.random.randn(5, 2) * 0.01 # level of noisey_data = w_real * x_data + b_real + noiseclass SimpleRegressionNN(tf.keras.Model):    def __init__(self):        super(SimpleRegressionNN, self).__init__()        self.output_layer = tf.keras.layers.Dense(1, input_shape=(2, ))    def call(self, data_input):        result = self.output_layer(data_input)        return resultreg_loss = tf.keras.losses.MeanSquaredError()reg_optimiser = tf.keras.optimizers.SGD(0.1)nn_regressor = SimpleRegressionNN()@tf.functiondef train_step(x_sample, y_sample):    with tf.GradientTape() as tape:        predictions = nn_regressor(x_sample)        loss = reg_loss(y_sample, predictions)    gradients = tape.gradient(loss, nn_regressor.trainable_variables) # 需要缩进这行!    reg_optimiser.apply_gradients(zip(gradients, nn_regressor.trainable_variables))      return lossfor x_point, y_point in zip(x_data, y_data): # 批量大小为1    x_point, y_point = tf.convert_to_tensor([x_point]), tf.convert_to_tensor([y_point])    mse = train_step(x_sample=x_point, y_sample=y_point)    print("MSE: {}".format(mse.numpy()))

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注