目录
ModelSVMWrapper包:
应用实现:
构建输入模型(model)
开始训练模型:
ModelSVMWrapper包:
ModelSVMWrapper函数提供一个包,该包内用SVM有效替换Keras模型的softmax。 model_svm_wrapper.py代码实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
from keras.models import Model from sklearn.svm import SVC from keras.utils import to_categorical class ModelSVMWrapper: """ Linear stack of layers with the option to replace the end of the stack with a Support Vector Machine # Arguments layers: list of layers to add to the model. svm: The Support Vector Machine to use. """ def __init__(self, model, svm=None): super().__init__() self.model = model self.intermediate_model = None # type: Model self.svm = svm if svm is None: self.svm = SVC(kernel='linear') def add(self, layer): return self.model.add(layer) def fit(self, x=None, y=None, batch_size=None, epochs=1, verbose=1, callbacks=None, validation_split=0., validation_data=None, shuffle=True, class_weight=None, sample_weight=None, initial_epoch=0, steps_per_epoch=None, validation_steps=None, **kwargs): fit = self.model.fit(x, to_categorical(y), batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, **kwargs) self.fit_svm(x, y, self.__get_split_layer()) return fit def fit_svm(self, x, y, split_layer): # Store intermediate model self.intermediate_model = Model(inputs=self.model.input, outputs=split_layer.output) # Use output of intermediate model to train SVM intermediate_output = self.intermediate_model.predict(x) self.svm.fit(intermediate_output, y) def evaluate(self, x=None, y=None, batch_size=None, verbose=1, steps=None): if self.intermediate_model is None: raise Exception("A model must be fit before running evaluate") output = self.predict(x, batch_size, verbose, steps) correct = [output[i] == y[i] for i in range(len(output))] accuracy = sum(correct) / len(correct) return accuracy def predict(self, x, batch_size=None, verbose=0, steps=None): intermediate_prediction = self.intermediate_model.predict(x, batch_size, verbose, steps) output = self.svm.predict(intermediate_prediction) return output def __get_split_layer(self): if len(self.model.layers) < 3: raise ValueError('self.layers to small for a relevant split') for layer in self.model.layers: if layer.name == "split_layer": return layer # if no specific cut of point is specified we can assume we need to remove only the last (softmax) layer return self.model.layers[-3] |
其中:
x:大量需要训练的数据输入。
y:目标(标签)数据的数字数组。
model:是已经定义好的模型;
应用实现:
构建输入模型(model)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
# Build a classical model def build_model(): model = models.Sequential() model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1))) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Conv2D(64, (3, 3), activation='relu')) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Conv2D(64, (3, 3), activation='relu')) model.add(layers.Flatten(name="intermediate_output")) model.add(layers.Dense(64, activation='relu')) model.add(layers.Dense(10, activation='softmax')) # The extra metric is important for the evaluate function model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy']) return model # Wrap it in the ModelSVMWrapper wrapper = ModelSVMWrapper(build_model()) |
开始训练模型:
1 2 3 4 5 6 7 8 9 10 |
accuracy = { "with_svm": [], "without_svm": [] } epochs = 10 for i in range(epochs): print('Starting run: {}'.format(i)) wrapper.fit(train_images, train_labels, epochs=1, batch_size=64) accuracy["with_svm"].append(wrapper.evaluate(test_images, test_labels)) |