Maison >développement back-end >Tutoriel Python >Exemple de code pour implémenter des machines vectorielles de support multiclasses à l'aide de TensorFlow

Exemple de code pour implémenter des machines vectorielles de support multiclasses à l'aide de TensorFlow

不言
不言original
2018-04-28 10:24:562913parcourir

Cet article présente principalement l'exemple de code pour implémenter des machines vectorielles de support multi-classes à l'aide de TensorFlow. Maintenant, je le partage avec vous et le donne comme référence. Venez jeter un œil ensemble

Cet article montrera en détail un classificateur de machine à vecteurs de support multiclasse formé sur l'ensemble de données de l'iris pour classer trois types de fleurs.

L'algorithme SVM a été conçu à l'origine pour des problèmes de classification binaire, mais il peut également être utilisé pour la classification multi-classes grâce à certaines stratégies. Les deux principales stratégies sont les suivantes : l'approche un contre tous (un contre tous) et l'approche un contre un (un contre un).

La méthode individuelle consiste à concevoir et à créer un classificateur binaire entre deux types d'échantillons quelconques, puis la catégorie avec le plus de votes est la catégorie prédite de l'échantillon inconnu. Mais lorsqu’il y a plusieurs catégories (k catégories), il faut créer k ! /(k-2) ! 2 ! Pour un classificateur, le coût de calcul reste assez élevé.

Une autre façon d'implémenter un classificateur multi-classes est le un-à-plusieurs, qui crée un classificateur pour chaque classe. La dernière classe prédite est la classe avec l’intervalle SVM le plus grand. Cet article mettra en œuvre cette méthode.

Nous allons charger l'ensemble de données iris et utiliser un modèle SVM multi-classes non linéaire avec une fonction de noyau gaussien. L'ensemble de données sur l'iris contient trois catégories : l'iris des montagnes, l'iris modifiable et l'iris de Virginie (I.setosa, I.virginica et I.versicolor). Nous allons créer trois fonctions de noyau gaussiennes SVM pour la prédiction.

# Multi-class (Nonlinear) SVM Example
#----------------------------------
#
# This function wll illustrate how to
# implement the gaussian kernel with
# multiple classes on the iris dataset.
#
# Gaussian Kernel:
# K(x1, x2) = exp(-gamma * abs(x1 - x2)^2)
#
# X : (Sepal Length, Petal Width)
# Y: (I. setosa, I. virginica, I. versicolor) (3 classes)
#
# Basic idea: introduce an extra dimension to do
# one vs all classification.
#
# The prediction of a point will be the category with
# the largest margin or distance to boundary.

import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf
from sklearn import datasets
from tensorflow.python.framework import ops
ops.reset_default_graph()

# Create graph
sess = tf.Session()

# Load the data
# 加载iris数据集并为每类分离目标值。
# 因为我们想绘制结果图,所以只使用花萼长度和花瓣宽度两个特征。
# 为了便于绘图,也会分离x值和y值
# iris.data = [(Sepal Length, Sepal Width, Petal Length, Petal Width)]
iris = datasets.load_iris()
x_vals = np.array([[x[0], x[3]] for x in iris.data])
y_vals1 = np.array([1 if y==0 else -1 for y in iris.target])
y_vals2 = np.array([1 if y==1 else -1 for y in iris.target])
y_vals3 = np.array([1 if y==2 else -1 for y in iris.target])
y_vals = np.array([y_vals1, y_vals2, y_vals3])
class1_x = [x[0] for i,x in enumerate(x_vals) if iris.target[i]==0]
class1_y = [x[1] for i,x in enumerate(x_vals) if iris.target[i]==0]
class2_x = [x[0] for i,x in enumerate(x_vals) if iris.target[i]==1]
class2_y = [x[1] for i,x in enumerate(x_vals) if iris.target[i]==1]
class3_x = [x[0] for i,x in enumerate(x_vals) if iris.target[i]==2]
class3_y = [x[1] for i,x in enumerate(x_vals) if iris.target[i]==2]

# Declare batch size
batch_size = 50

# Initialize placeholders
# 数据集的维度在变化,从单类目标分类到三类目标分类。
# 我们将利用矩阵传播和reshape技术一次性计算所有的三类SVM。
# 注意,由于一次性计算所有分类,
# y_target占位符的维度是[3,None],模型变量b初始化大小为[3,batch_size]
x_data = tf.placeholder(shape=[None, 2], dtype=tf.float32)
y_target = tf.placeholder(shape=[3, None], dtype=tf.float32)
prediction_grid = tf.placeholder(shape=[None, 2], dtype=tf.float32)

# Create variables for svm
b = tf.Variable(tf.random_normal(shape=[3,batch_size]))

# Gaussian (RBF) kernel 核函数只依赖x_data
gamma = tf.constant(-10.0)
dist = tf.reduce_sum(tf.square(x_data), 1)
dist = tf.reshape(dist, [-1,1])
sq_dists = tf.multiply(2., tf.matmul(x_data, tf.transpose(x_data)))
my_kernel = tf.exp(tf.multiply(gamma, tf.abs(sq_dists)))

# Declare function to do reshape/batch multiplication
# 最大的变化是批量矩阵乘法。
# 最终的结果是三维矩阵,并且需要传播矩阵乘法。
# 所以数据矩阵和目标矩阵需要预处理,比如xT·x操作需额外增加一个维度。
# 这里创建一个函数来扩展矩阵维度,然后进行矩阵转置,
# 接着调用TensorFlow的tf.batch_matmul()函数
def reshape_matmul(mat):
  v1 = tf.expand_dims(mat, 1)
  v2 = tf.reshape(v1, [3, batch_size, 1])
  return(tf.matmul(v2, v1))

# Compute SVM Model 计算对偶损失函数
first_term = tf.reduce_sum(b)
b_vec_cross = tf.matmul(tf.transpose(b), b)
y_target_cross = reshape_matmul(y_target)

second_term = tf.reduce_sum(tf.multiply(my_kernel, tf.multiply(b_vec_cross, y_target_cross)),[1,2])
loss = tf.reduce_sum(tf.negative(tf.subtract(first_term, second_term)))

# Gaussian (RBF) prediction kernel
# 现在创建预测核函数。
# 要当心reduce_sum()函数,这里我们并不想聚合三个SVM预测,
# 所以需要通过第二个参数告诉TensorFlow求和哪几个
rA = tf.reshape(tf.reduce_sum(tf.square(x_data), 1),[-1,1])
rB = tf.reshape(tf.reduce_sum(tf.square(prediction_grid), 1),[-1,1])
pred_sq_dist = tf.add(tf.subtract(rA, tf.multiply(2., tf.matmul(x_data, tf.transpose(prediction_grid)))), tf.transpose(rB))
pred_kernel = tf.exp(tf.multiply(gamma, tf.abs(pred_sq_dist)))

# 实现预测核函数后,我们创建预测函数。
# 与二类不同的是,不再对模型输出进行sign()运算。
# 因为这里实现的是一对多方法,所以预测值是分类器有最大返回值的类别。
# 使用TensorFlow的内建函数argmax()来实现该功能
prediction_output = tf.matmul(tf.multiply(y_target,b), pred_kernel)
prediction = tf.arg_max(prediction_output-tf.expand_dims(tf.reduce_mean(prediction_output,1), 1), 0)
accuracy = tf.reduce_mean(tf.cast(tf.equal(prediction, tf.argmax(y_target,0)), tf.float32))

# Declare optimizer
my_opt = tf.train.GradientDescentOptimizer(0.01)
train_step = my_opt.minimize(loss)

# Initialize variables
init = tf.global_variables_initializer()
sess.run(init)

# Training loop
loss_vec = []
batch_accuracy = []
for i in range(100):
  rand_index = np.random.choice(len(x_vals), size=batch_size)
  rand_x = x_vals[rand_index]
  rand_y = y_vals[:,rand_index]
  sess.run(train_step, feed_dict={x_data: rand_x, y_target: rand_y})

  temp_loss = sess.run(loss, feed_dict={x_data: rand_x, y_target: rand_y})
  loss_vec.append(temp_loss)

  acc_temp = sess.run(accuracy, feed_dict={x_data: rand_x,
                       y_target: rand_y,
                       prediction_grid:rand_x})
  batch_accuracy.append(acc_temp)

  if (i+1)%25==0:
    print('Step #' + str(i+1))
    print('Loss = ' + str(temp_loss))

# 创建数据点的预测网格,运行预测函数
x_min, x_max = x_vals[:, 0].min() - 1, x_vals[:, 0].max() + 1
y_min, y_max = x_vals[:, 1].min() - 1, x_vals[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.02),
           np.arange(y_min, y_max, 0.02))
grid_points = np.c_[xx.ravel(), yy.ravel()]
grid_predictions = sess.run(prediction, feed_dict={x_data: rand_x,
                          y_target: rand_y,
                          prediction_grid: grid_points})
grid_predictions = grid_predictions.reshape(xx.shape)

# Plot points and grid
plt.contourf(xx, yy, grid_predictions, cmap=plt.cm.Paired, alpha=0.8)
plt.plot(class1_x, class1_y, 'ro', label='I. setosa')
plt.plot(class2_x, class2_y, 'kx', label='I. versicolor')
plt.plot(class3_x, class3_y, 'gv', label='I. virginica')
plt.title('Gaussian SVM Results on Iris Data')
plt.xlabel('Pedal Length')
plt.ylabel('Sepal Width')
plt.legend(loc='lower right')
plt.ylim([-0.5, 3.0])
plt.xlim([3.5, 8.5])
plt.show()

# Plot batch accuracy
plt.plot(batch_accuracy, 'k-', label='Accuracy')
plt.title('Batch Accuracy')
plt.xlabel('Generation')
plt.ylabel('Accuracy')
plt.legend(loc='lower right')
plt.show()

# Plot loss over time
plt.plot(loss_vec, 'k-')
plt.title('Loss per Generation')
plt.xlabel('Generation')
plt.ylabel('Loss')
plt.show()

Sortie :

Instructions de mise à jour :
Utilisez `argmax` à la place
Étape n°25
Perte = -313,391
Étape n°50
Perte = -650,891
Étape n°75
Perte = -988,39
Étape n°100
Perte = -1325,89


Résultats multi-classification (trois catégories) du modèle SVM gaussien non linéaire de I.Setosa, où la valeur gamma est de 10

L'objectif est de modifier l'algorithme SVM pour optimiser les trois types de modèles SVM en même temps. Le paramètre de modèle b est calculé pour trois modèles en ajoutant une dimension. Nous pouvons voir que l'algorithme peut être facilement étendu à plusieurs types d'algorithmes similaires à l'aide des fonctions intégrées de TensorFlow.

Recommandations associées :

Méthode d'implémentation TensorFlow d'une machine à vecteurs de support non linéaire

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn