** Hinweis: [Verbesserte Version] Versuchen Sie MNIST mit Mehrwertsteuer (Virtual Adversarial Training) auf Keras ist eine bessere Implementierung. Bitte nehmen Sie Bezug darauf. ** **.
In letzter Zeit habe ich eine Lernmethode namens VAT (Virtual Adversarial Training) gelernt, aber ich konnte keine Implementierung in Keras finden, also habe ich es versucht.
Einfach ausgedrückt, die Mehrwertsteuer stammt von "normaler Eingang X-> Ausgang Y" und "Eingang (X + d) -> Ausgang Y '", wobei dem Eingang ein winziges Rauschen d hinzugefügt wird, damit sich das Ergebnis so weit wie möglich von "KL" unterscheidet. -Divergenz (Y, Y ') "wird der Verlustfunktion zum Lernen hinzugefügt.
Ich weiß nicht, was Sie damit meinen. Lesen Sie daher bitte das Originalpapier oder Erklärung dieser Person. -Training /) Ich denke du solltest einen Blick darauf werfen.
Die Mehrwertsteuer soll in Bezug auf ihre Lernposition der "Regularisierung" nahe kommen und könnte eine Alternative zum Hinzufügen von Dropout und Noise sein. Es ist auch mühsam, Parameter wie Dropout anzupassen, daher würde ich mich freuen, wenn stattdessen die Mehrwertsteuer verwendet werden könnte.
Mit Keras ist es etwas schwierig, Eingabe X für Kosten- und Regularisierungsfunktionen zu verwenden. In diesem Fall ist es jedoch in Ordnung, sie zu portieren, da sie in Chainer und Theano implementiert ist.
Es stellte sich heraus, dass es so etwas war.
Der Punkt ist
Ich denke das ist der Ort.
keras_mnist_vat.py
# coding: utf8
"""
* VAT: https://arxiv.org/abs/1507.00677
#Referenzierter Code
Original: https://github.com/fchollet/keras/blob/master/examples/mnist_cnn.py
VAT: https://github.com/musyoku/vat/blob/master/vat.py
# Result Example
use_dropout=False, use_vat=False: score=0.211949993095, accuracy=0.9877
use_dropout=True, use_vat=False: score=0.238920686956, accuracy=0.9853
use_dropout=False, use_vat=True: score=0.180048364889, accuracy=0.9916
use_dropout=True, use_vat=True: score=0.245401585515, accuracy=0.9901
"""
import numpy as np
from keras.engine.topology import Input, Container
from keras.engine.training import Model
np.random.seed(1337) # for reproducibility
from keras.datasets import mnist
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Convolution2D, MaxPooling2D
from keras.utils import np_utils
from keras import backend as K
SAMPLE_SIZE = 0
batch_size = 128
nb_classes = 10
nb_epoch = 12
# input image dimensions
img_rows, img_cols = 28, 28
# number of convolutional filters to use
nb_filters = 32
# size of pooling area for max pooling
pool_size = (2, 2)
# convolution kernel size
kernel_size = (3, 3)
def main(data, use_dropout, use_vat):
# the data, shuffled and split between train and test sets
(X_train, y_train), (X_test, y_test) = data
if K.image_dim_ordering() == 'th':
X_train = X_train.reshape(X_train.shape[0], 1, img_rows, img_cols)
X_test = X_test.reshape(X_test.shape[0], 1, img_rows, img_cols)
input_shape = (1, img_rows, img_cols)
else:
X_train = X_train.reshape(X_train.shape[0], img_rows, img_cols, 1)
X_test = X_test.reshape(X_test.shape[0], img_rows, img_cols, 1)
input_shape = (img_rows, img_cols, 1)
X_train = X_train.astype('float32')
X_test = X_test.astype('float32')
X_train /= 255.
X_test /= 255.
# convert class vectors to binary class matrices
y_train = np_utils.to_categorical(y_train, nb_classes)
y_test = np_utils.to_categorical(y_test, nb_classes)
if SAMPLE_SIZE:
X_train = X_train[:SAMPLE_SIZE]
y_train = y_train[:SAMPLE_SIZE]
X_test = X_test[:SAMPLE_SIZE]
y_test = y_test[:SAMPLE_SIZE]
my_model = MyModel(input_shape, use_dropout).build()
my_model.training(X_train, y_train, X_test, y_test, use_vat=use_vat)
score = my_model.model.evaluate(X_test, y_test, verbose=0)
print("use_dropout=%s, use_vat=%s: score=%s, accuracy=%s" % (use_dropout, use_vat, score[0], score[1]))
class MyModel:
model = None
core_layers = None
def __init__(self, input_shape, use_dropout=True):
self.input_shape = input_shape
self.use_dropout = use_dropout
def build(self):
input_layer = Input(self.input_shape)
output_layer = self.core_data_flow(input_layer)
self.model = Model(input_layer, output_layer)
return self
def core_data_flow(self, input_layer):
x = Convolution2D(nb_filters, kernel_size[0], kernel_size[1], border_mode='valid')(input_layer)
x = Activation('relu')(x)
x = Convolution2D(nb_filters, kernel_size[0], kernel_size[1])(x)
x = Activation('relu')(x)
x = MaxPooling2D(pool_size=pool_size)(x)
if self.use_dropout:
x = Dropout(0.25)(x)
x = Flatten()(x)
x = Dense(128, activation="relu")(x)
if self.use_dropout:
x = Dropout(0.5)(x)
x = Dense(nb_classes, activation='softmax')(x)
self.core_layers = Container(input_layer, x)
return x
def training(self, X_train, y_train, X_test, y_test, use_vat=False):
orig_loss_func = loss_func = K.categorical_crossentropy
if use_vat:
# y_concat to true(y_true, x_train)Verwenden Sie die anomale Verlustfunktion, um zu nehmen
loss_func = self.loss_with_vat_loss(loss_func)
self.model.compile(loss=loss_func, optimizer='adadelta', metrics=['accuracy'])
# train,teste beide y,Erstellen Sie Daten, indem Sie X horizontal verketten
yX_train = np.concatenate((y_train, X_train.reshape((X_train.shape[0], -1))), axis=1)
yX_test = np.concatenate((y_test, X_test.reshape((X_test.shape[0], -1))), axis=1)
#Lerne normal
self.model.fit(X_train, yX_train, batch_size=batch_size, nb_epoch=nb_epoch,
verbose=1, validation_data=(X_test, yX_test))
#Ich habe eine anomale LossFunction angegeben, daher muss ich sie in eine normale LossFunction ändern und erneut kompilieren oder auswerten()Wird versagen
self.model.compile(loss=orig_loss_func, optimizer='adadelta', metrics=['accuracy'])
else:
self.model.compile(loss=loss_func, optimizer='adadelta', metrics=['accuracy'])
self.model.fit(X_train, y_train, batch_size=batch_size, nb_epoch=nb_epoch,
verbose=1, validation_data=(X_test, y_test))
def loss_with_vat_loss(self, original_loss_func, eps=1, xi=10, ip=1):
def with_vat_loss(yX_train, y_pred):
nb_output_classes = y_pred.shape[1]
y_true = yX_train[:, :nb_output_classes]
# VAT
X_train = yX_train[:, nb_output_classes:].reshape((-1, ) + self.input_shape)
d = K.random_normal(X_train.shape)
for _ in range(ip):
y = self.core_layers(X_train + self.normalize_vector(d) * xi)
kld = K.sum(self.kld(y_pred, y))
d = K.stop_gradient(K.gradients(kld, [d])[0]) # stop_gradient is important!!
y_perturbation = self.core_layers(X_train + self.normalize_vector(d)*eps)
kld = self.kld(y_pred, y_perturbation)
return original_loss_func(y_pred, y_true) + kld
return with_vat_loss
@staticmethod
def normalize_vector(x):
z = K.sum(K.batch_flatten(K.square(x)), axis=1)
while K.ndim(z) < K.ndim(x):
z = K.expand_dims(z, dim=-1)
return x / (K.sqrt(z) + K.epsilon())
@staticmethod
def kld(p, q):
v = p * (K.log(p + K.epsilon()) - K.log(q + K.epsilon()))
return K.sum(K.batch_flatten(v), axis=1, keepdims=True)
data = mnist.load_data()
main(data, use_dropout=False, use_vat=False)
main(data, use_dropout=True, use_vat=False)
main(data, use_dropout=False, use_vat=True)
main(data, use_dropout=True, use_vat=True)
Ich habe mit 4 Mustern mit / ohne Ausfall und mit / ohne Mehrwertsteuer experimentiert. 1 Epochenzeit ist GeForce GTX 1080, Umgebungsvariable
KERAS_BACKEND=theano
THEANO_FLAGS=device=gpu,floatX=float32,lib.cnmem=1
Es ist, wenn es ausgeführt wird als.
Dropout | VAT | Accuracy | 1 Epoche Zeit |
---|---|---|---|
verwende nicht | verwende nicht | 98.77% | 8 Sekunden |
verwenden | verwende nicht | 98.53% | 8 Sekunden |
verwende nicht | verwenden | 99.16% | 18 Sekunden |
verwenden | verwenden | 99.01% | 19 Sekunden |
Nun, das Ergebnis ist einigermaßen gut, daher denke ich, dass es kein Problem bei der Implementierung gibt. Da die Mehrwertsteuer in einer Charge zweimal berechnet wird, wird auch die Ausführungszeit verdoppelt.
Die Mehrwertsteuer kann auch für unbeaufsichtigtes Lernen verwendet werden. Es handelt sich also um eine Lernmethode mit einem breiten Anwendungsspektrum. Ich möchte es auf verschiedene Arten verwenden.
Recommended Posts