目次
1.異常検出
異常は、標準から逸脱し、めったに発生せず、残りの「パターン」に従わないイベントとして定義されます。例外の例は次のとおりです。
- 世界的な出来事により株式市場は急落した
- 工場/コンベヤーベルトの不良品
- 実験室で汚染されたサンプル
データが正規分布に従っていると仮定すると、異常なデータは通常、正規分布曲線の両側にあります。以下に示すように。
これまで見てきたように、これらのイベントは発生しますが、発生する可能性は非常に低いです。機械学習の観点からは、これにより異常の検出が困難になります。定義上、「標準」イベントの例は多数あり、「異常」イベントの例はごくわずかです。したがって、私たちのデータセットには大きな偏差があります。検出したい異常が1%、0.1%、または0.0001%の確率でしか発生しない場合、バランスの取れたデータセットで最適に機能する機械学習アルゴリズムはどのように機能する必要がありますか?現時点では、この種の問題に具体的に対処するために異常検出を使用する必要があります。
データセットのラベルには大きな不均衡があるため、定義上、異常なデータが発生することはめったになく、正常なデータが大量にあります。異常なデータを検出するために、孤立したフォレスト、ワンクラスSVM、楕円エンベロープ、ローカル異常因子アルゴリズムなどの従来の機械学習アルゴリズムが導出されます。ここでは1つずつ紹介しません。興味のある学生は研究に行くことができます。ここでの主なトピックは、ディープラーニングを使用してこの問題を解決する方法です。
2.自動エンコーダに基づく異常検出
オートエンコーダは教師なしニューラルネットワークであり、次のことができます。
- 入力データのセットを受け入れます。
- データをエンコードします。
- エンコードされたフィーチャをデコードして、入力データを再構築します。
通常、オートエンコーダは主にエンコーダとデコーダの2つの部分で構成されます。エンコーダーは入力データを受け入れ、それを特徴表現に変換します。次に、デコーダーは圧縮された特徴を再構築して入力データを取得しようとします。オートエンコーダーをエンドツーエンドでトレーニングすると、ネットワークは入力データのノイズを除去することさえできる強力なフィルターを学習できます。
異常検出の観点から、オートエンコーダーは損失を再構築できるという点で特別です。入力と再構築されたデータ間の平均二乗誤差(MSE)は、通常、オートエンコーダーのトレーニング時に測定されます。損失が小さい場合、再構成された画像は元のデータに似ています。
MNISTデータセット全体でオートエンコーダーをトレーニングし、オートエンコーダーに番号を指定して再構築するとします。入力データと同様に再構成できることを願っています。そうすると、これら2つの画像間のMSEが比較的低いことがわかります。
現時点で象などの非デジタル画像を提供している場合、これら2つの画像のMSEは現時点で非常に高くなっています。これは、オートエンコーダーがこれまで象を見たことがなく、さらに重要なことに、象を再構築するためのトレーニングを受けたことがないため、MSEが非常に高いためです。
このとき、再構築されたMSEが高い場合は、外れ値がある可能性があります。
第三に、異常検出Tensorflowの実装
3.1、データの読み込み
ここでは、mnistデータセットを使用し、ラベルは通常データとして1、ラベルはデータ数の1%、ラベルは異常データとして3であり、異常データを作成します。詳細は次のとおりです。
- データセットをロードする
# 加载MNIST数据集
print("[INFO] loading MNIST dataset...")
((trainX,trainY),(testX,testY))=tf.keras.datasets.mnist.load_data()
- 異常なデータを生成する
def build_unsupervised_dataset(data,labels,validLabel=1,
anomalyLabel=3, contam=0.01, seed=42):
'''制作数据集'''
# 抓取提供的类标签的所有 * 真正 * 索引特定的标签,
# 然后获取图像的索引个标签将成为我们的“异常”
validIdxs=np.where(labels==validLabel)[0]
anomalyLabelIdx=np.where(labels==anomalyLabel)[0]
#随机打乱数据
random.shuffle(validIdxs)
random.shuffle(anomalyLabelIdx)
#计算并设置异常数据的个数
i=int(len(validIdxs)*contam)
anomalyLabelIdx=anomalyLabelIdx[:i]
#提取正常数据和异常数据
validImages=data[validIdxs]
anomalyImages=data[anomalyLabelIdx]
#打包数据并进行数据打乱
images=np.vstack([validImages,anomalyImages])
return images
# 建立少量的无监督图像数据集,污染(即异常)添加到其中
print("[INFO] creating unsupervised dataset...")
images = build_unsupervised_dataset(trainX, trainY, validLabel=1,
anomalyLabel=3, contam=0.01)
3.2、自己コーディングモデルを構築する
コードは次のとおりです。
class ConvAutoencoder:
@staticmethod
def build(width,height,depth=None,filters=(32,64),latentDim=16):
'''
构建自动编码器模型
:param width: 图像的宽度
:param height: 图像的高度
:param depth: 图像的深度
:param filters: 卷积核的尺寸
:param latentDim: 全连接的维数
:return:
'''
#定义解码器
inputs=tf.keras.layers.Input(shape=(height,width,depth))
x=inputs
for filter in filters:
x=tf.keras.layers.Conv2D(filter,kernel_size=(3,3),strides=2,padding='same')(x)
x=tf.keras.layers.LeakyReLU(alpha=0.2)(x)
x=tf.keras.layers.BatchNormalization(axis=-1)(x)
volumeSize=tf.keras.backend.int_shape(x)
x=tf.keras.layers.Flatten()(x)
latent=tf.keras.layers.Dense(latentDim)(x)
encoder=tf.keras.Model(inputs=inputs,outputs=latent,name='encoder')
#定义编码器
latentinputs=tf.keras.layers.Input(shape=(latentDim,))
x=tf.keras.layers.Dense(np.prod(volumeSize[1:]))(latentinputs)
x=tf.keras.layers.Reshape((volumeSize[1],volumeSize[2],volumeSize[3]))(x)
for filter in filters[::-1]:
x=tf.keras.layers.Conv2DTranspose(filter,kernel_size=(3,3),strides=2,padding='same')(x)
x=tf.keras.layers.LeakyReLU(alpha=0.2)(x)
x=tf.keras.layers.BatchNormalization(axis=-1)(x)
x=tf.keras.layers.Conv2DTranspose(depth,(3,3),padding='same')(x)
outputs=tf.keras.layers.Activation('sigmoid')(x)
decoder=tf.keras.Model(latentinputs,outputs,name='decoder')
autoencoder=tf.keras.Model(inputs,decoder(encoder(inputs)),name='autoencoder')
return (encoder,decoder,autoencoder)
autoencoder.summary()
ネットワークフレーム構造は次のとおりです。
3.3、モデルトレーニング
epochs=20
lr=1e-3
batch_size=32
#搭建模型
print("[INFO] building autoencoder...")
(encoder, decoder, autoencoder) = ConvAutoencoder.build(28, 28,1)
#搭建优化器
opt=tf.keras.optimizers.Adam(lr=lr,decay=lr/epochs)
autoencoder.compile(loss='mse',optimizer=opt,metrics=['acc'])
#训练
H=autoencoder.fit(trainX,trainX,validation_data=(testX,testX),epochs=epochs,batch_size=batch_size)
トレーニングプロセスは次のとおりです。
3.4。モデル予測
主に自己符号化再構成画像と元画像を使用してMSEを計算し、しきい値に応じて対応する判断を行います。主な実現方法は次のとおりです。
# 加载模型
print("[INFO] loading autoencoder and image data...")
autoencoder = tf.keras.models.load_model("autoencoder.h5")
images = pickle.loads(open("mages.pickle", "rb").read())
#预测图片
images=images.reshape(-1,28,28,1)
images=images.astype('float32')
images/=255
decoded = autoencoder.predict(images)
errors = []
for (image, recon) in zip(images, decoded):
# 计算预测和真实图片之间的均方差1
mse = np.mean((image - recon) ** 2)
errors.append(mse)
# compute the q-th quantile of the errors which serves as our
# threshold to identify anomalies -- any data point that our model
# reconstructed with > threshold error will be marked as an outlier
thresh = np.quantile(errors, 0.999)
idxs = np.where(np.array(errors) >= thresh)[0]
print("[INFO] mse threshold: {}".format(thresh))
print("[INFO] {} outliers found".format(len(idxs)))
テスト結果は次のとおりです。
詳細なコードリンク:https://github.com/kingqiuol/learning_tensorflow/tree/master/cv/Anomaly_detection
参照リンク:
https://www.pyimagesearch.com/2020/03/02/anomaly-detection-with-keras-tensorflow-and-deep-learning/