59889


DCGANで画像の自動生成を行う際に「'numpy.ndarray' object is not
callable」というエラーが発生します。コードは下のものです。GoogleColaboratoryで実行しています。

[code]

    # 本物データをGeneratorで生成したデータのスケールを-1~1で揃える
    
    def scale(x, feature_ranges=(-1, 1)):
        # 0~1に変換
        x = ((x - x.min()) / (255 - x.min()))
    
        # -1~1に変換
        min, max = feature_ranges
        x = x * (max - min) + min
        return x
    
    class Dataset:
        # val_fracでテストデータを学習中と学習後用に分離する
        # スケール関数は上のものを使うためscale_func=None
        def __init__(self, shuffle= False, scale_func=None):
            self.test_x, self.valid_x = test_img2, valid_img2
            self.test_y, self.valid_y = test_index, valid_index
            self.train_x, self.train_y = train_img2, train_index
    
            if scale_func is None:
                self.scaler = scale
            else:
                self.scaler = scale_func
            self.shuffle = shuffle
    
        # ミニバッチ生成の定義
        def batches(self, batch_size):
            if (self.shuffle).any():
                idx = np.arange(len(dataset.train_x))
                np.random.shuffle(idx)
                self.train_x = self.train_x[idx]
                self.train_y = self.train_y[idx]
    
            n_batches = len(self.train_y) // batch_size
            for ii in range(0, len(self.train_y), batch_size):
                x = self.train_x[ii:ii+batch_size]
                y = self.train_y[ii:ii+batch_size]
    
                yield self.scaler(x), y
    
    　　　　　　　　　　　　　　　　（中略）
    
    # トレーニングの実行
    
    dataset = Dataset(train_img2, test_img2)
    
    losses, samples = train(net, dataset, epochs, batch_size, figsize=(10, 5))
    
[/code]

これを実行すると次のようなエラーが出ます。

[code]

    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    <ipython-input-16-79c936bb63bd> in <module>()
          2 dataset = Dataset(train_img2, test_img2)
          3 
    ----> 4 losses, samples = train(net, dataset, epochs, batch_size, figsize=(10, 5))
    
    1 frames
    <ipython-input-14-07c181927757> in train(net, dataset, epochs, batch_size, print_every, show_every, figsize)
         14         for e in range(epochs):
         15             # バッチで取り出してパラメータの更新を行う
    ---> 16             for x, y in dataset.batches(batch_size):
         17                 # for文のたびにstep数を1増加
         18                 steps += 1
    
    <ipython-input-6-f57b4d686916> in batches(self, batch_size)
         26             y = self.train_y[ii:ii+batch_size]
         27 
    ---> 28             yield self.scaler(x), y
    
    TypeError: 'numpy.ndarray' object is not callable
    
[/code]

定義した`self.scaler`を使ってxとyを返したいのですが，このようなエラーが出ます。  
どのように修正すればこのエラーを解決できるのでしょうか？


CC BY-SA 4.0
2019-10-22T13:11:59.860
59879
2019-10-23T00:01:43.160
36307
question
python tensorflow numpy
DCGANを行う際に「'numpy.ndarray' object is not callable」というエラーが発生


まず、ipythonで以下の検証コードを実行します。

[code]

    In [1]: import numpy as np
    
    In [2]: scaler = np.array([1])
    
    In [3]: scaler(1)
    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    <ipython-input-3-69fda89d0c8a> in <module>
    ----> 1 scaler(1)
    
    TypeError: 'numpy.ndarray' object is not callable
    
[/code]

これは、scalerが関数ではなく、`numpy.ndarray`
オブジェクトであることを意味しています。このオブジェクトは関数のように呼び出すことはできません。つまり、scalerはデータであり、関数ではないことを意味しています。

`Dataset`のコンストラクタは、一番目の引数に`shuffle`,
二番目の引数に`scale_func`を定義しています。`scale_func`が指定されている場合、`self.scaler`に`scale_func`が代入されるようになっています。

この`scale_func`として指定されているのは`test_img2`です。

> \---> 28 yield self.scaler(x), y  
>  TypeError: 'numpy.ndarray' object is not callable

このエラーから推測すれば、`self.scaler`に代入された`test_img2`が`numpy.ndarray`である可能性が高いです。

対処方法として、`Dataset`クラスのインスタンス化の方法を確認し、コンストラクタの引数としてデータを指定する部分を追加する必要があります。

[code]

    class Dataset:
        def __init__(self, train_img2, valid_img2, valid_img2, train_index, valid_index, test_index, shuffle= False, scale_func=None):
            self.test_x, self.valid_x = test_img2, valid_img2
            self.test_y, self.valid_y = test_index, valid_index
            self.train_x, self.train_y = train_img2, train_index
    
            if scale_func is None:
                self.scaler = scale
            else:
                self.scaler = scale_func
            self.shuffle = shuffle
    
[/code]

Datasetのコンストラクタを呼び出す部分でも、これらのデータすべてを渡すよう変更します。

[code]

    dataset = Dataset(train_img2, valid_img2, valid_img2, train_index, valid_index, test_index)
    
[/code]


CC BY-SA 4.0
2019-10-23T00:01:43.160
59889
2019-10-23T00:01:43.160
59879
answer