質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.92%

リストをNumPy配列ndarrayに変換する方法

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 199

maguro2020

score 21

前提・実現したいこと

GitHub WeaklyAnomalyDetection
上記サイト様のコードを参考にPythonを用いて自前のデータセットで異常検知を行いたいと考えております。

発生している問題・エラーメッセージ

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-12-7bfdc75aa020> in <module>
      1 # 普通の異常検知
      2 for i in range(2):
----> 3     train_and_evaluate(i+1, False)
      4 
      5 # 弱異常検知

<ipython-input-11-ef7de7d098c9> in train_and_evaluate(number, anomaly)
     63     train = np.array(train)
     64 
---> 65     train = train.reshape((len(train),-1))
     66     test_c = test_c.reshape((len(X_test_c),-1))
     67     test_b = test_b.reshape((len(X_test_b),-1))

ValueError: cannot reshape array of size 0 into shape (0,newaxis)


また、print(train)でtrainの中身を確認しましたところ、

#print(train)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-13-246f4ac0135d> in <module>
----> 1 print(train)

NameError: name 'train' is not defined


という上記のエラーが発生してしまい、trainの中身が何故かなくなっておりました。

コード

異常検知のコード

import matplotlib.pyplot as plt
import os
import cv2
import random
import numpy as np
from keras.utils import to_categorical
from keras.preprocessing.image import ImageDataGenerator

from b_c_dataset import BCN_Dataset

bell = 0#bellは0
call = 1#callは1

# dataset
(x_train, y_train), (x_test, y_test) = BCN_Dataset.create_bcn()

x_train = x_train.reshape(x_train.shape[0], 583, 438, 3)
x_test = x_test.reshape(x_test.shape[0], 583, 438, 3)

x_train = x_train.astype('float32') / 255
x_test = x_test.astype('float32') / 255

#学習データ
x_train_sum, x_train_c, x_train_b, x_test_c, x_test_b = [], [], [], [], []
y_train_sum = []

for i in range(len(x_train)):
    if y_train[i] == bell:
        x_train_b.append(x_train[i])
    elif y_train[i] == call:
        x_train_c.append(x_train[i])
    else:
        x_train_sum.append(x_train[i])
        y_train_sum.append(y_train[i])

x_train_sum = np.array(x_train_sum)
x_train_b = np.array(x_train_b)
x_train_c = np.array(x_train_c)

#trainデータからランダムに10個抽出
number = np.random.choice(np.arange(0,x_train_sum.shape[0]),10,replace=False)

x, y = [], []

for i in number:
    x.append(x_train_sum[i])
    y.append(y_train_sum[i])

x_train_sum = np.array(x)
y_train_sum = np.array(y)

#callデータからランダムに10個抽出
number = np.random.choice(np.arange(0,x_train_c.shape[0]),10,replace=False)

x, y = [], []

for i in number:
    x.append(x_train_c[i])

#データ結合
x_train_sum = np.vstack((x_train_sum, np.array(x)))
y_train_sum = np.hstack((y_train_sum, call*np.ones(10)))

#bellデータからランダムに10個抽出
number = np.random.choice(np.arange(0,x_train_b.shape[0]),10,replace=False)

x, y = [], []

for i in number:
    x.append(x_train_b[i])

# Data Augmentation
datagen = ImageDataGenerator(rotation_range=10,
                             width_shift_range=0.1,
                             height_shift_range=0.1,
                             horizontal_flip=False)
img = []

for d in datagen.flow(np.array(x), batch_size=1):
    # このあと画像を表示するためにndarrayをPIL形式に変換して保存する
    img.append(d[0])
    # datagen.flowは無限ループするため必要な枚数取得できたらループを抜ける
    if len(img) == 10:
        print("finish")
        break

#データ結合
x_train_sum = np.vstack((x_train_sum, np.array(img)))
y_train_sum = np.hstack((y_train_sum, bell*np.ones(10)))
y_train_sum = to_categorical(y_train_sum)

#テストデータ
for i in range(len(x_test)):
    if y_test[i] == 1:#callは1
        x_test_c.append(x_test[i])

    if y_test[i] == 0:#bellは0
        x_test_b.append(x_test[i])

x_test_c = np.array(x_test_c)
x_test_b = np.array(x_test_b)

print(x_train_sum.shape)
print(y_train_sum.shape)
print(x_test_c.shape)
print(x_test_b.shape)

import cv2
from PIL import Image

def resize(x):
    x_out = []

    for i in range(len(x)):
        img = cv2.cvtColor(x[i], cv2.COLOR_RGB2BGR)
        img = cv2.resize(img,dsize=(96,96))
        x_out.append(img)

    return np.array(x_out)

X_train_sum = resize(x_train_sum)
X_test_c = resize(x_test_c)
X_test_b = resize(x_test_b)

import keras
from keras.applications import MobileNetV2
from keras.optimizers import Adam, SGD
from keras.models import Model
from keras.layers import GlobalAveragePooling2D, Dense
from keras import backend as K

from sklearn.neighbors import LocalOutlierFactor
from sklearn import metrics
from sklearn.preprocessing import MinMaxScaler


input_shape = (96, 96, 3)
classes = 3
batchsize = 128
alpha = 0.5

def train_and_evaluate(number, anomaly=True):
    # mobile net読み込み
    print("Model build...")

    mobile = MobileNetV2(include_top=True, input_shape=input_shape, alpha=alpha,
                     weights='imagenet')

    # 最終層削除
    mobile.layers.pop()
    model = Model(inputs=mobile.input,outputs=mobile.layers[-1].output)

    # L2層と全結合層を付ける
    c = keras.layers.Lambda(lambda xx: 5*(xx)/K.sqrt(K.sum(xx**2)))(model.output) #metric learning
    c = Dense(classes, activation='softmax')(c)
    model = Model(inputs=model.input,outputs=c)

    #model.summary()

    model.compile(loss='categorical_crossentropy',
                  optimizer=Adam(amsgrad=True),
                  metrics=['accuracy'])

    print(number,"training...")

    #cnnの学習
    if anomaly == True:
        train_NO = 5000
    else:
        train_NO = 4500

    hist = model.fit(X_train_sum[:train_NO],
                     y_train_sum[:train_NO],
                     batch_size=128,
                     epochs=50,
                     verbose = False)

#下記にNumPyをndarrayに変換するコードを付け足しました(※1)
    # 最終層削除
    model.layers.pop()
    model = Model(inputs=model.input,outputs=model.layers[-1].output)

    train = model.predict(X_train_sum[4000:4500], batch_size=1)#スニーカー
    test_c = model.predict(X_test_c, batch_size=1)
    test_b = model.predict(X_test_b, batch_size=1)

    train = np.array(train) #(※1)

    train = train.reshape((len(train),-1))
    test_c = test_c.reshape((len(X_test_c),-1))
    test_b = test_b.reshape((len(X_test_b),-1))

    #0-1変換
    ms = MinMaxScaler()
    train = ms.fit_transform(train)
    test_c = ms.transform(test_c)
    test_b = ms.transform(test_b)

    # LOF
    clf = LocalOutlierFactor(n_neighbors=5)
    y_pred = clf.fit(train)

    # plot the level sets of the decision function
    Z1 = -clf._decision_function(test_c)
    Z2 = -clf._decision_function(test_b)

    #ROC曲線の描画
    y_true = np.zeros(len(test_c)+len(test_b))
    y_true[len(test_c):] = 1#0:正常、1:異常

    # FPR, TPR(, しきい値) を算出
    fpr, tpr, _ = metrics.roc_curve(y_true, np.hstack((Z1, Z2)))

    # AUC
    auc = metrics.auc(fpr, tpr)

    # ROC曲線をプロット
    plt.plot(fpr, tpr, label='metric learning(AUC = %.2f)'%auc)
    plt.legend()
    plt.title(str(number)+'ROC curve')
    plt.xlabel('False Positive Rate')
    plt.ylabel('True Positive Rate')
    plt.grid(True)
    plt.show()

# 普通の異常検知
for i in range(2):
    train_and_evaluate(i+1, False)

# 弱異常検知
for i in range(2):
    train_and_evaluate(i+1)

試していること

現在、上記のエラーについて調査を行っているのですが、解決の手段が全く見えていない状況となっております。しかし、下記サイト様にNumPy配列をndarrayに変換する際に、「便宜上「変換」という言葉を使っているが、実際は元のオブジェクトはそのままで新たな型のオブジェクトが生成される。」ということが記載されており、もしかすると新しい型のオブジェクトが生成されてしまったがために中身が空になってしまったのではないか、と考えているのですが、ではコードをどのように改良すればいいのかわからず、頭を悩ませております。
NumPy配列ndarrayとPython標準のリストを相互に変換

補足

使っているPCはmacOS Catalina バージョン10.15.5
Pythonのバージョンは3.6.5です
Jupiter notebookを使用しています

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • can110

    2020/07/21 07:56

    提示コードには「print(train)」が含まれていないようですが。

    キャンセル

  • meg_

    2020/07/21 09:07

    「NameError: name 'train' is not defined」は「trainの中身が何故かなくなっておりました」とは意味の違うエラーですよね?ご確認ください。

    キャンセル

回答 1

checkベストアンサー

+1

trainを定義し値を代入しところから1つずつtrainの内容を追い、どこでなくなったかを突き止めるところからだと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.92%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る