使用 Tensorflow 进行分类的神经网络

源节点: 1570297

这篇文章是作为 数据科学博客马拉松

在本文中,我将使用 TensorFlow 构建神经网络模型来解决分类问题。 让我们一起探讨如何在 Tensorflow 中解决分类问题。 但首先,我想确保我们能够回答这些问题:

是神经网络?

神经网络的主要目的是试图找出数据集中特征之间的关系,它由一组模仿人脑工作的算法组成。 神经网络中的“神经元”是一种数学函数,它根据特定的架构对信息进行收集和分类。

什么是分类?

分类问题涉及预测某物是否属于一类。 换句话说,在做这件事时,我们试图看到某事是一回事或另一回事。

分类类型

  • 假设您想预测一个人是否患有糖尿病。 如果你遇到这种情况,有两种可能吧? 被称为 二元分类。
  • 假设您想识别照片是玩具、人还是猫,对吗? 这就是所谓的 多类分类 因为有两个以上的选择。
  • 假设您要决定应将哪些类别分配给文章。 如果是这样,它被称为 多标签分类,因为一篇文章可能分配了多个类别。 让我们通过这篇文章来解释一下。 我们可能会为这篇文章分配“深度学习、TensorFlow、分类”等类别

现在我们可以继续前进,因为我们对我们将要解决的问题有了共同的理解。 所以,是时候进行编码了。 我希望你和我一起把它们写下来,因为要想变得更好,减少错误的唯一方法就是编写更多的代码。

我们从导入我们将使用的库开始:

import numpy as np import pandas as pd import matplotlib.pyplot as plt import tensorflow as tf print(tf.__version__)

创建数据集

是时候创建一个数据集来处理了:

从 sklearn.datasets 导入 make_circles 样本 = 1000 X,y = make_circles(样本,噪声 = 0.03,random_state = 42)

我们已经创建了一些数据,让我们获取有关它的更多信息。

打印(X >> [0.75424625 0.23148074] [-0.75615888 0.15325888] [-0.81539193 0.17328203] ... [-0.13690036 -0.81001183] [0.67036156 -0.76750154] [0.28105665 0.96382443]
打印(y)>> [1 1 1 1 0 1 1 1 1 0]

好的,我们已经更详细地看到了我们的数据集,但我们仍然对它一无所知,对吧? 这就是为什么这里重要的一步是与数据合而为一,而可视化是做到这一点的最佳方式。

circle = pd.DataFrame({ 'X0' : X[:, 0], 'X1' : X[:, 1], 'label' : y}) circle.head()
使用 Tensorflow 数据头进行分类的神经网络

这里出现了一个问题,我们在处理什么样的标签?

circle.label.value_counts() >> 1 500 0 500 名称:标签,数据类型:int64

看起来我们正在处理 二元分类问题,因为我们有 2 个标签(0 和 1)。

plt.scatter(X[:,0], X[:,1], c = y, cmap = plt.cm.RdYlBu)
使用 Tensorflow 散点图进行分类的神经网络

正如我上面提到的,获取数据的最佳方法是可视化。 现在 plot 自己说我们需要构建什么样的模型。 我们将构建一个能够区分蓝点和红点的模型。

在构建任何神经网络模型之前,我们必须检查输入和输出特征的形状。 他们一定是一样的!

打印(X.shape, y.shape) 打印(len(X), len(y)) >> (1000, 2) (1000,) 1000 1000

我们对每个特征都有相同数量的值,但 X 的形状不同? 为什么? 让我们来看看。

X[0], y[0] >> (数组([0.75424625, 0.23148074]), 1)

好的,我们有 2 年的 1 个 X 特征。 所以我们可以毫无问题地前进。

使用 Tensorflow 为分类建模神经网络的步骤

在 TensorFlow 中有用于创建模型的固定阶段:

  • 建立模型 – 使用功能或顺序 API 将神经网络的各层拼凑在一起
  • 编译模型 – 定义模型的性能应该如何衡量,以及它应该如何改进(损失函数和优化器)
  • 拟合模式l – 让模型在数据中找到模式

我们将使用 Sequential API。 那么,让我们开始吧

tf.random.set_seed(42)
模型_1 = tf.keras.Sequential([tf.keras.layers.Dense(1)])

model_1.compile(loss = tf.keras.losses.BinaryCrossentropy(),

#我们使用二进制作为损失函数,因为我们正在处理 2 个类

 optimizer = tf.keras.optimizers.SGD(), #SGD 代表随机梯度下降指标 = ['accuracy']) model_1.fit(X, y, epochs = 5)
>> Epoch 1/5 32/32 [==============================] - 1s 1ms/step - 损失:2.8544 - 准确度:0.4600 Epoch 2/5 32/32 [==============================] - 0s 2ms/step - 损失: 0.7131 - 准确度: 0.5430 Epoch 3/5 32/32 [==============================] - 0s 2ms/step - 损失:0.6973 - 准确度:0.5090 Epoch 4/5 32/32 [==============================] - 0s 2ms /step - 损失:0.6950 - 准确度:0.5010 Epoch 5/5 32/32 [==============================] - 0s 1ms/step - 损失:0.6942 - 准确度:0.4830

模型的准确率大约为 50%,这基本上意味着模型只是猜测,让我们尝试训练更长时间

model_1.fit(X, y, epochs = 200, verbose = 0) #我们设置verbose = 0来移除训练过程) model_1.evaluate(X, y)
>> 32/32 [==============================] - 0s 1ms/步 - 损失:0.6935 - 准确度:0.5000 [0.6934829950332642, 0.5]

即使在 200 个 epoch 之后,它仍然表现得像在猜测 下一步是添加更多层和更长时间的训练。

tf.random.set_seed(42)
model_2 = tf.keras.Sequential([ tf.keras.layers.Dense(1), tf.keras.layers.Dense(1)]) model_2.compile(loss = tf.keras.losses.BinaryCrossentropy(), 优化器 = tf.keras.optimizers.SGD(), metrics = ['accuracy']) model_2.fit(X, y, epochs = 100,verbose = 0)
 model_2.evaluate(X,y)
>> 32/32 [==============================] - 0s 1ms/步 - 损失:0.6933 - 准确度:0.5000 [0.6933314800262451, 0.5]

还是,一点点变化都没有,似乎有些不对劲。

使用 Tensorflow 改进用于分类模型的神经网络

在不同的阶段有不同的改进模型的方法:

  • 创建模型—— 添加更多层,增加隐藏单元(神经元)的数量,改变每一层的激活函数
  • 编译模型—— 尝试不同的优化函数,例如使用 Adam() 而不是 SGD()。
  • 拟合模型 – 我们可以增加时代的数量

让我们尝试 添加更多神经元 并尝试 Adam 优化

tf.random.set_seed(42)
model_3 = tf.keras.Sequential([ tf.keras.layers.Dense(100), # 添加 100 个密集神经元 tf.keras.layers.Dense(10), # 添加另一个具有 10 个神经元的层 tf.keras.layers.Dense (1) ]) model_3.compile(loss=tf.keras.losses.BinaryCrossentropy(), optimizer=tf.keras.optimizers.Adam(), metrics=['accuracy']) model_3.fit(X, y, epochs =100,详细=0)
model_3.evaluate(X,y) >> 32/32 [==============================] - 0s 1ms/step - 损失:0.6980 - 准确度:0.5080 [0.6980254650115967, 0.5080000162124634]

还是没有好转! 让我们将数据可视化,看看哪里出了问题。

可视化神经网络模型

为了可视化我们模型的预测,我们将创建一个函数 plot_decision_boundary() ,它:

  • 接收经过训练的模型、特征和标签
  • 创建不同 X 值的网格。
  • 跨网格进行预测。
  • 用线绘制预测。

请注意:  该函数改编自两个资源:

CS231n 使用 ML 基础知识制作 

def plot_decision_boundary(model, X, y): # 定义绘图的轴边界并创建网格 x_min, x_max = X[:, 0].min() - 0.1, X[:, 0].max() + 0.1 y_min, y_max = X[:, 1].min() - 0.1, X[:, 1].max() + 0.1 xx, yy = np.meshgrid(np.linspace(x_min, x_max, 100), np .linspace(y_min, y_max, 100)) # 创建 X 个值(我们将预测所有这些值) x_in = np.c_[xx.ravel(), yy.ravel()] # 使用训练好的进行预测model y_pred = model.predict(x_in) # 检查多类
 if len(y_pred[0]) > 1: print("doing multiclass classification...") # 我们必须重塑我们的预测,让它们准备好绘制 y_pred = np.argmax(y_pred, axis=1).reshape( xx.shape) else: print("doing binary classifcation...") y_pred = np.round(y_pred).reshape(xx.shape) # 绘制决策边界 plt.contourf(xx, yy, y_pred, cmap=plt. cm.RdYlBu, alpha=0.7) plt.scatter(X[:, 0], X[:, 1], c=y, s=40, cmap=plt.cm.RdYlBu) plt.xlim(xx.min( ), xx.max()) plt.ylim(yy.min(), yy.max()) plot_decision_boundary(model_3, X, y)
决策边界

这里是! 再次可视化向我们展示了什么是错误的,该怎么做? 我们的模型试图通过数据画一条直线,但我们的数据不能被直线分开。 我们的分类问题是否遗漏了什么? 这是什么?

这就是非线性! 我们需要一些非线性线。 您现在可能会感到困惑,如果您认为以前没有看到那种功能,那您就错了,因为您已经看到了。 让我们直观地看到它们。 可视化总是效果更好!

我们可以使用神经网络中的一些激活函数,例如 热路, 乙状结肠. 让我们创造一点 玩具张量 并检查其上的那些功能。

神经网络的激活函数

A = tf.cast(tf.range(-12,12), tf.float32) 打印(A) >> tf.Tensor( [-12. -11. -10. -9. -8. -7. - 6. -5. -4. -3. -2. -1. 0. 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.], shape=(24,), dtype=float32)

让我们看看我们的玩具张量是什么样子的?

plt.绘图(A)
神经网络的激活函数

看起来像这样,一条直线! 

现在让我们重新创建激活函数,看看它们对我们的张量做了什么?

乙状结肠:

def sigmoid(x): return 1 / (1 + tf.exp(-x)) sigmoid(A) plt.plot(sigmoid(A))
乙状结肠功能

非直线!

回复:

现在让我们来看看 ReLu 做了什么? Relu 将所有负值变为 0,正值保持不变。

def relu(x): 返回 tf.maximum(0,x) plt.plot(relu(A))
热路

又一条非直线!

现在您已经看到了非线性激活函数,这些对我们有用,模型无法在具有线性激活函数的非线性数据集上学习任何东西! 如果已经了解了这一点,那么是时候将我们的数据划分为训练集和测试集并构建强大的模型了。

X_train, y_train = X[:800], y[:800] X_test, y_test = X[800:], y[800:] X_train.shape, X_test.shape >>((800, 2), (200, 2) ))

 

太好了,现在我们有了训练集和测试集,让我们对训练数据进行建模并评估我们的模型在测试集上学到了什么。

tf.random.set_seed(42)
model_4 = tf.keras.Sequential([ tf.keras.layers.Dense(4, activation = 'relu'), #我们也可以对它“tf.keras.activations.relu” tf.keras.layers.Dense(4 , 激活 = 'relu'), tf.keras.layers.Dense(1, activation = 'sigmoid')]) model_4.compile( loss= tf.keras.losses.binary_crossentropy, 优化器 = tf.keras.optimizers.Adam( lr = 0.01), metrics = ['accuracy']) model_4.fit(X_train, y_train, epochs = 25,verbose = 0)

评估模型

loss,accuracy = model_4.evaluate(X_test, y_test) print(f'测试集上的模型损失:{loss}') print(f'测试集上的模型精度:{100*accuracy}')
>> 7/7 [==============================] - 0s 2ms/步 - 损失:0.1247 - 准确度:1.0000测试集上的模型损失:0.1246885135769844 测试集上的模型准确度:100.0

瞧! 100% 准确率! 让我们直观地看到这个结果

plt.figure(figsize=(12, 6)) plt.subplot(1, 2, 1) plt.title("Train") plot_decision_boundary(model_4, X=X_train, y=y_train) plt.subplot(1, 2, 2) plt.title("Test") plot_decision_boundary(model_4, X=X_test, y=y_test) plt.show()
使用 Tensorflow 进行分类的二元神经网络

只需进行一些调整,我们的模型现在几乎可以完美地预测蓝色和红色圆圈。

结论

让我们简单地看一下我们在本文中谈论的内容。 我们一起研究了如何使用 TensorFlow 在神经网络中处理分类任务。 我们以第一种想到的方式创建了 3 个模型,在可视化的帮助下我们意识到我们错在哪里,我们探索了线性、非线性,最后,我们设法建立了一个广义模型。 我试图用所有这些代码和我遵循的步骤表明,没有什么是 100% 准确或固定的,一切都在每天都在变化。 要猜测在哪种数据中您可能会遇到哪些问题并查看哪些组合会导致更好的结果,您需要编写更多代码并获得经验。

我希望这篇文章对你有所帮助,并做出一些贡献。

本文中显示的媒体不归 Analytics Vidhya 所有,由作者自行决定使用

来源:https://www.analyticsvidhya.com/blog/2021/11/neural-network-for-classification-with-tensorflow/

时间戳记:

更多来自 分析维迪亚