AttributeError:“numpy.ndarray”对象没有属性“transform”

Posted

技术标签:

【中文标题】AttributeError:“numpy.ndarray”对象没有属性“transform”【英文标题】:AttributeError: 'numpy.ndarray' object has no attribute 'transform' 【发布时间】:2020-11-29 10:37:35 【问题描述】:

我想创建一个包含两个步骤的sklearn 管道:

    自定义转换器功能 Keras 分类模型

这是我的数据集(当然,我提供了一个简化的子集来显示数据格式):

x_train

array([[[0.45977011, 0.16666667, 0.18373494, ..., 0.33333333,
         0.71317829, 0.7246617 ],
        [0.6091954 , 0.25      , 0.28313253, ..., 0.33333333,
         0.66666667, 0.73101353],
        [0.25287356, 0.75      , 0.34337349, ..., 0.16666667,
         0.62790698, 0.62137531],
        ...,
        [0.6091954 , 0.58333333, 0.20481928, ..., 0.33333333,
         0.62015504, 0.65009666],
        [0.41954023, 0.91666667, 0.30722892, ..., 0.33333333,
         0.71317829, 0.76719138],
        [0.31609195, 0.41666667, 0.46987952, ..., 0.33333333,
         0.5503876 , 0.71306269]],

       [[0.6091954 , 0.25      , 0.28313253, ..., 0.33333333,
         0.66666667, 0.73101353],
        [0.25287356, 0.75      , 0.34337349, ..., 0.16666667,
         0.62790698, 0.62137531],
        [0.54022989, 0.5       , 0.34337349, ..., 0.33333333,
         0.57364341, 0.66238608],
        ...,
        [0.41954023, 0.91666667, 0.30722892, ..., 0.33333333,
         0.71317829, 0.76719138],
        [0.31609195, 0.41666667, 0.46987952, ..., 0.33333333,
         0.5503876 , 0.71306269],
        [0.44252874, 0.75      , 0.48192771, ..., 0.41666667,
         0.62015504, 0.65023474]],

       [[0.25287356, 0.75      , 0.34337349, ..., 0.16666667,
         0.62790698, 0.62137531],
        [0.54022989, 0.5       , 0.34337349, ..., 0.33333333,
         0.57364341, 0.66238608],
        [0.3908046 , 0.33333333, 0.34939759, ..., 0.41666667,
         0.58914729, 0.70450152],
        ...,
        [0.31609195, 0.41666667, 0.46987952, ..., 0.33333333,
         0.5503876 , 0.71306269],
        [0.44252874, 0.75      , 0.48192771, ..., 0.41666667,
         0.62015504, 0.65023474],
        [0.60344828, 0.41666667, 0.46686747, ..., 0.25      ,
         0.66666667, 0.61391881]]]

y_train

array([[1., 0., 0.],
       [1., 0., 0.],
       [1., 0., 0.]], dtype=float32)

这是我当前的代码:

import numpy as np
from keras.wrappers.scikit_learn import KerasClassifier
import tensorflow as tf
from tensorflow.keras.models import *
from tensorflow.keras.layers import *
from tensorflow.keras.optimizers import *
from tensorflow.keras.utils import *
from tensorflow.keras.callbacks import *
from sklearn.pipeline import Pipeline

# Custom transformer
class Transformer():

    def transform(self, x):
        x_img = np.apply_along_axis(self.rec_plot, 1, x).astype('float16')
        return x_img
    
    def rec_plot(s, eps=0.10, steps=10):
        d = pdist(s[:,None])
        d = np.floor(d/eps)
        d[d>steps] = steps
        Z = squareform(d)
        return Z
    
    def fit(self, x, y=None):
        return x

def create_model():
    model = Sequential()

    model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(50, 50, 17)))
    model.add(Conv2D(32, (3, 3), activation='relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(Dropout(0.25))

    model.add(Conv2D(64, (3, 3), activation='relu'))
    model.add(Conv2D(64, (3, 3), activation='relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(Dropout(0.25))

    model.add(Flatten())
    model.add(Dense(256, activation='relu'))
    model.add(Dropout(0.5))
    model.add(Dense(3, activation='softmax'))

    #sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
    model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

    print(model.summary())
    
    return model

transformer = Transformer()
clf = KerasClassifier(build_fn=create_model, verbose=0)

blackbox_model = Pipeline([('transform', transformer),('clf',clf)])
blackbox_model.fit(x_train, y_train)

当我在我的数据集上运行此代码时,我收到以下错误:

AttributeError: 'numpy.ndarray' 对象没有属性 'transform'

好像和数据格式有关(所以上面分享了我的数据格式)。但我不确定如何解决这个问题。

【问题讨论】:

【参考方案1】:

方法Transformer().fit() 应该返回self

因为您的Transformer 对象是无状态的,所以使用sklearn.preprocessing.FunctionTransformer 可能更容易。您可以使用您的转换函数实例化该类。类似于以下内容(未经测试):

import sklearn.preprocessing

def _rec_plot(s, eps=0.10, steps=10):
    d = pdist(s[:,None])
    d = np.floor(d/eps)
    d[d>steps] = steps
    Z = squareform(d)
    return Z

def fun(x, y=None):
    return np.apply_along_axis(_rec_plot, 1, x).astype('float16')

transformer = sklearn.preprocessing.FunctionTransformer(func=fun)

我还建议不要使用语法from module import *,因为这会污染您的命名空间。当我第一次阅读您的问题时,我想知道问题是不是因为所有不必要的导入而导致对函数名称进行分类。

【讨论】:

谢谢。现在得到另一个错误TypeError: 'Transformer' object is not subscriptable。你知道如何让我的例子工作吗? 好的,我明白了。现在错误是ValueError: Found array with dim 3. Estimator expected <= 2.。事实上x_train 是一个 3 维数组。这是否意味着我应该在Pipeline 中添加从 2D 到 3D 的转换作为另一个步骤? 似乎 sklearn 适用于 2D 数组,而不是 3D。因此,您可以在 Transformer() 之前将数据重新整形为 2D,然后在将其传递给 Keras 分类器之前将其重新整形为 3D。我假设 Keras 分类器可以处理 3D 数组。 是的,Keras 可以很好地处理 3D。问题在于转换管道。我在这里发布了我的新问题,以防你能提供帮助:***.com/questions/63330277/…

以上是关于AttributeError:“numpy.ndarray”对象没有属性“transform”的主要内容,如果未能解决你的问题,请参考以下文章

AttributeError:“模块”对象没有属性“作者”

初学者 Python:AttributeError:'list' 对象没有属性

AttributeError:“字节”对象没有属性“告诉”

AttributeError: 'RDD' 对象没有属性 'show'

AttributeError:“NumpyArrayIterator”对象没有属性“类”

AttributeError:模块 'dbus' 没有属性 'lowlevel'